如何使用JavaFX正确实现上一个或下一个按钮事件
在这里使用JavaFX编写我的第一个程序。该程序显示一个对象(个人)的数据,我想实现一个“previous”按钮,该按钮应使用静态ArrayList“arrayListOfPeople”中的前一个对象刷新窗格 作为一名noob,我希望我可以简单地执行currentPersonPosition-1和loadWindow,如下所示:如何使用JavaFX正确实现上一个或下一个按钮事件,java,javafx,Java,Javafx,在这里使用JavaFX编写我的第一个程序。该程序显示一个对象(个人)的数据,我想实现一个“previous”按钮,该按钮应使用静态ArrayList“arrayListOfPeople”中的前一个对象刷新窗格 作为一名noob,我希望我可以简单地执行currentPersonPosition-1和loadWindow,如下所示: Button btnBottom = new Button(Integer.toString(currentPersonPosition-1)); final
Button btnBottom = new Button(Integer.toString(currentPersonPosition-1));
final EventHandler<MouseEvent> eventHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
loadWindow(currentPersonPosition, borderPane, anotherStage);
}
};
Button btnBottom=新按钮(Integer.toString(currentPersonPosition-1));
final EventHandler EventHandler=new EventHandler(){
@凌驾
公共无效句柄(MouseEvent e){
加载窗口(currentPersonPosition、边框窗格、其他阶段);
}
};
但是,handle()方法不能使用currentPersonPosition变量,因为内部方法似乎只能使用最终实例变量。。。那么你如何妥善处理这件事呢
我写了一些肯定不是正确的方法:我将按钮文本设置为currentPersonPosition-1,然后读取并解析handle方法中的值。
在花了很多时间来解决这个愚蠢的问题后,我想知道它是如何正确完成的
下面的最小可生产示例打开一个窗口,在窗口标题栏中显示Name1/Name2/Name3,并在左下角包含一个小按钮,用作“上一个”按钮
提前谢谢
public class Main extends Application {
Scene scene = null;
static ArrayList<String> arrayListOfPeople = new ArrayList<>();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(final Stage primaryStage) {
int currentPersonPosition = arrayListOfPeople.size() - 1;
final BorderPane borderPane = new BorderPane();
scene = new Scene(borderPane, 640, 480);
arrayListOfPeople.add("Name1");
arrayListOfPeople.add("Name2");
arrayListOfPeople.add("Name3");
loadWindow(currentPersonPosition, borderPane, primaryStage);
}
public void loadWindow(int currentPersonPosition, final BorderPane borderPane, final Stage anotherStage) {
if (currentPersonPosition < 0) currentPersonPosition = arrayListOfPeople.size()-1;
// BOTTOM
Button btnBottom = new Button(Integer.toString(currentPersonPosition-1));
final EventHandler<MouseEvent> eventHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
String[] testString = e.getTarget().toString().split(",");
System.out.println(testString[0]);
if (testString[0].contains("\"")) {
int positionOfFirstTextQuote = testString[0].indexOf("\"");
int positionOfLastTextQuote = testString[0].lastIndexOf("\"");
String currentClipPositionString = testString[0].substring(positionOfFirstTextQuote + 1, positionOfLastTextQuote);
int currentPersonPosition = Integer.parseInt(currentClipPositionString);
loadWindow(currentPersonPosition, borderPane, anotherStage);
}
}
};
btnBottom.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
borderPane.setBottom(btnBottom);
anotherStage.setTitle(arrayListOfPeople.get(currentPersonPosition));
anotherStage.setScene(scene);
anotherStage.show();
}
public类主扩展应用程序{
场景=空;
静态ArrayList arrayListOfPeople=new ArrayList();
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
公共作废开始(最终阶段初级阶段){
int currentPersonPosition=arrayListOfPeople.size()-1;
final BorderPane BorderPane=新的BorderPane();
场景=新场景(边框窗格,640480);
arrayListOfPeople.add(“Name1”);
arrayListOfPeople.add(“Name2”);
arrayListOfPeople.add(“Name3”);
加载窗口(currentPersonPosition、borderPane、primaryStage);
}
公共void加载窗口(int currentPersonPosition,final BorderPane BorderPane,final Stage另一个Stage){
如果(currentPersonPosition<0)currentPersonPosition=arrayListOfPeople.size()-1;
//底部
按钮btnBottom=新按钮(整数.toString(currentPersonPosition-1));
final EventHandler EventHandler=new EventHandler(){
@凌驾
公共无效句柄(MouseEvent e){
String[]testString=e.getTarget().toString().split(“,”);
System.out.println(testString[0]);
if(testString[0]。包含(“\”){
int-positionOfFirstTextQuote=testString[0]。indexOf(“\”);
int positionOfLastTextQuote=testString[0]。lastIndexOf(“\”);
String currentClipPositionString=testString[0]。子字符串(positionOfFirstTextQuote+1,positionOfLastTextQuote);
int currentPersonPosition=Integer.parseInt(currentClipPositionString);
加载窗口(currentPersonPosition、边框窗格、其他阶段);
}
}
};
btnBottom.addEventHandler(MouseEvent.MOUSE_单击,eventHandler);
borderPane.setBottom(btnBottom);
setTitle(arrayListOfPeople.get(currentPersonPosition));
另一阶段:场景;
另一个阶段。show();
}
}有各种方法可以解决这个问题,但它们都是以相同的方式工作的;您需要将值封装在对象中 如果您使用的是Java 10或更高版本,则可以将匿名内部类与局部变量类型推断一起使用。如下所示声明变量:
Button btnBottom = new Button(Integer.toString(currentPersonPosition-1));
final EventHandler<MouseEvent> eventHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
loadWindow(currentPersonPosition, borderPane, anotherStage);
}
};
final var currentPersonPosition=新对象(){
int值;
};
现在,您可以使用currentPersonPosition.value
引用变量。这样做的缺点是,您将无法将对象作为参数传递,并且仍然可以访问value
字段
另一个选项是使用单元素数组:
final int[]currentPersonPosition=new int[1];
现在,您可以使用
currentPersonPosition[0]引用变量
解决这一问题的关键是使用计数器变量跟上当前位置。您不应允许计数器变量大于列表大小-1或小于0。如果您是初学者,我建议您使用匿名内部类创建按钮处理程序,如以下示例所示
Main
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Control;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
/**
* JavaFX App
* @Author Sedrick (SedJ601)
*/
public class App extends Application {
List<Person> listOfPeople = new ArrayList();
AtomicInteger currentPosition = new AtomicInteger();
Label lblName;
Label lblAge;
@Override
public void start(Stage stage) {
listOfPeople.add(new Person("John Doe", 22));
listOfPeople.add(new Person("Jane Doe", 21));
listOfPeople.add(new Person("Kim Doe", 5));
listOfPeople.add(new Person("John Doe Jr", 3));
//Load the first Person
stage.setTitle(listOfPeople.get(currentPosition.get()).getName());
Label lblNameTag = new Label("Name: ");
lblName = new Label(listOfPeople.get(currentPosition.get()).getName());
Label lblAgeTag = new Label("Age: ");
lblAge = new Label(Integer.toString(listOfPeople.get(currentPosition.get()).getAge()));
//Use a GridPane to display the name and age.
GridPane gridPane = new GridPane();
gridPane.setMaxSize(Control.USE_PREF_SIZE, Control.USE_PREF_SIZE);
gridPane.add(lblNameTag, 0, 0);
gridPane.add(lblName, 1, 0);
gridPane.add(lblAgeTag, 0, 1);
gridPane.add(lblAge, 1, 1);
//Create Previous and Next Buttons with their handlers
Button btnPrevious = new Button("<");
btnPrevious.setOnAction((t) -> {
System.out.println(currentPosition.get());
if(currentPosition.get() > 0)
{
currentPosition.decrementAndGet();
stage.setTitle(listOfPeople.get(currentPosition.get()).getName());
lblName.setText(listOfPeople.get(currentPosition.get()).getName());
lblAge.setText(Integer.toString(listOfPeople.get(currentPosition.get()).getAge()));
}
});
Button btnNext = new Button(">");
btnNext.setOnAction((t) -> {
System.out.println(currentPosition.get());
if(currentPosition.get() < listOfPeople.size() - 1)
{
currentPosition.incrementAndGet();
stage.setTitle(listOfPeople.get(currentPosition.get()).getName());
lblName.setText(listOfPeople.get(currentPosition.get()).getName());
lblAge.setText(Integer.toString(listOfPeople.get(currentPosition.get()).getAge()));
}
});
HBox hBox = new HBox(btnPrevious, btnNext);
hBox.setAlignment(Pos.CENTER);
BorderPane root = new BorderPane();
root.setCenter(gridPane);
root.setBottom(hBox);
var scene = new Scene(root, 640, 480);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
/**
*
* @author sedrick (SedJ601)
*/
class Person
{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" + "name=" + name + ", age=" + age + '}';
}
}
请问..@kleopatra done您在哪里学会了公共静态void main(String[]args){arrayListOfPeople.add(“Name1”);arrayListOfPeople.add(“Name2”);arrayListOfPeople.add(“Name3”);launch(args);}from?@Sedrick我只是想快速想出一个“可重复性最小的示例。实际程序将json文件中的数据加载到Person对象中,ArrayListPersole是ArrayList谢谢,我使用了“单元素数组”选项,这比我的解决方法好得多。@如果答案解决了您的问题,请随意接受t他回答是为了表明问题已经解决。我肯定会记得,在将来使用重写方法时,这种“单元素数组”方法,否则我无法访问某些变量,因此对此表示感谢!但我现在知道,我可以使用Button.setOnAction而不是EventHandler&重写句柄方法,所以我没有首先是这个问题。谢谢你的回复!使用Button.setOnAction而不是像我那样使用EventHandler&handle()方法解决了主要问题(我无法访问ArrayList变量)。现在了解AtomicInteger也很好。有一些重复的代码(stage.setTitle、lblName.setText和lblAge.setText在start方法中总共是3倍),我会更改它,但您的答复节省了我几个小时,再次感谢!