如何在 Javafx 和 Scene Builder 中使用一个事件处理程序方法管理多个按钮
How to manage multiple buttons with one event handler method in Javafx and Scene Builder
我有 14 对按钮与两组文本字段相关联,它们将相关联的文本字段递增和递减 2。每个文本字段显示有多少对特定重量的盘子要加载到杠铃上。
它们存储在两个二维数组中,一个用于磅,另一个用于千克。 [递增或递减][按钮]
final Button[][] poundIncrementDecrementButton = new Button[2][7];
final Button[][] kilogramIncrementDecrementButton = new Button[2][7];
我正在使用 Scene Builder 和 JavaFX,我正在努力避免编写 28 个 @FXML 事件处理程序。
到目前为止,这是我想出的遍历每个数组的方法,但我不确定如何替换 lambda 表达式来完成这项工作。
// assigns event handlers to increment and decrement buttons.
private void incrementDrecimentButtonEventHandlers() {
// p=1 increment buttons, p=2 decrement buttons
for (int p = 0; p < poundIncrementDecrementButton.length; p++) {
// loops through buttons
for (int j = 0; j < poundIncrementDecrementButton[p].length; j++) {
Button incrementButton = poundIncrementDecrementButton[p][j];
final int incrementDecriment = p;
final int textField = j;
incrementButton.setOnAction((ActionEvent event) -> {
incrementDecrementPlate("pounds", incrementDecriment, textField);
});
}
// k=1 increment buttons, k=2 decrement buttons
for (int k = 0; k < kilogramIncrementDecrementButton.length; k++) {
// loops through buttons
for (int j = 0; j < kilogramIncrementDecrementButton[k].length; j++) {
Button incrementButton = kilogramIncrementDecrementButton[k][j];
final int incrementDecriment = k;
final int textField = j;
incrementButton.setOnAction((ActionEvent event) -> {
incrementDecrementPlate("kilograms", incrementDecriment, textField);
});
}
}
}
}
然后我让事件处理程序使用相关索引调用此方法。
// increments or decrements the plates
private void incrementDecrementPlate(String unit, int incrementDecrement, int textField) {
Double oldValue = Double.parseDouble(poundTextFieldList.get(textField).getText());
String incremented;
String decremented;
if (oldValue % 2 != 0) {
incremented = Double.toString(oldValue + 1);
} else {
incremented = Double.toString(oldValue + 2);
}
if (oldValue % 2 != 0) {
decremented = Double.toString(oldValue - 1);
} else if (oldValue != 0) {
decremented = Double.toString(oldValue - 2);
} else {
decremented = Double.toString(oldValue);
}
switch (unit) {
case "pounds":
if (incrementDecrement == 0) {
poundTextFieldList.get(textField).setText(incremented);
} else {
poundTextFieldList.get(textField).setText(decremented);
}
break;
case "kilograms":
if (incrementDecrement == 0) {
kilogramTextFieldList.get(textField).setText(incremented);
} else {
kilogramTextFieldList.get(textField).setText(decremented);
}
break;
}
}
以下代码演示了如何让一组 (2) 个按钮递增文本字段的值:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class FxMain extends Application {
private Button[] increment, decrement;
private TextField[] txt;
private static final int numberOfGroups = 3;
@Override
public void start(Stage stage) {
initComponents(numberOfGroups);
GridPane root = new GridPane();
for(int row =0; row < numberOfGroups; row++){ //add all components
root.addRow(row, decrement[row], txt[row],increment[row]);
}
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
//create and initialize components
private void initComponents(int size) {
increment = new Button[size]; decrement = new Button[size];
txt = new TextField[size];
for(int group = 0; group < size; group++) {
final int i = group;
txt[i] = new TextField(String.valueOf(0));
increment[i] = new Button("+");
increment[i].setOnAction(a-> updateTxtField(txt[i], 1));//assign handle
decrement[i] = new Button("-");
decrement[i].setOnAction(a-> updateTxtField(txt[i],-1));
}
}
//increment text filed value
private void updateTxtField(TextField textField, int i) {
int newValue = Integer.valueOf(textField.getText()) + i;
textField.setText(String.valueOf(newValue));
}
public static void main(String[] args) { launch(args);}
}
如有需要,请随时提出要求。
如需更多帮助,post MCVE
经过一些实验,我想出了一个解决方案。请记住,这是我使用 Scene Builder、FXML 和 JavaFX 坚持使用 MVC 架构的尝试。
有 14 种不同的盘子,7 种以磅为单位,7 种以公斤为单位。每个板都有一个文本字段,用于显示对于给定的重量,每个板需要加载到杠铃上的数量。这些 textFields 存储在 ObservableLists 中,并在控制器的其他地方被赋予监听器。
// textFields associated with 45, 35, 25, 15, 10, 5, 2.5lb plates
ObservableList<TextField> poundTextFieldList = FXCollections.observableArrayList();
// textFields associated with 25, 20, 15, 10, 5, 2.5, 1.25kg plates
ObservableList<TextField> kilogramTextFieldList = FXCollections.observableArrayList();
这些数组存储盘子的数量。
int[] poundPlatesToLoad = calculator.getPoundPlatesToLoad();
int[] kilogramPlatesToLoad = calculator.getKilogramPlatesToLoad();
这些ArrayLists存储增量按钮
private final ArrayList<Button> poundIncrementButtons = new ArrayList();
private final ArrayList<Button> poundDecrementButtons = new ArrayList();
private final ArrayList<Button> kilogramIncrementButtons = new ArrayList();
private final ArrayList<Button> kilogramDecrementButtons = new ArrayList();
由于我使用了Scene Builder来设计GUI,所以每个按钮都需要@FXML标签来标识它们。我认为没有办法解决这个问题,所以控制器中有 28 个。
@FXML
private Button poundIncrement45Button;
@FXML
private Button poundDecrement45Button;
然后,为了避免编写 28 个处理程序,我编写了 4 个与每个 ArrayList 关联的处理程序。
public void poundIncrementButtonPressed(ActionEvent event) {
System.out.println("pound increment button pressed");
Button button = (Button) event.getSource();
// identifies which plate is to be incremented
int plate = poundIncrementButtons.indexOf(button);
incrementDecrementPlate(0, 0, plate);
}
还有一种增加或减少正确文本字段的方法。
private void incrementDecrementPlate(int unit, int incrementDecrement, int textField) {
int oldValue;
if(unit == 0){
oldValue = (int) poundPlatesToLoad[textField];
} else {
oldValue = (int) kilogramPlatesToLoad[textField];
}
String incremented;
String decremented;
if (oldValue % 2 != 0) {
incremented = Integer.toString(oldValue + 1);
} else {
incremented = Integer.toString(oldValue + 2);
}
if (oldValue % 2 != 0) {
decremented = Integer.toString(oldValue - 1);
} else if (oldValue != 0) {
decremented = Integer.toString(oldValue - 2);
} else {
decremented = Integer.toString(oldValue);
}
switch (unit) {
case 0:
if (incrementDecrement == 0) {
poundTextFieldList.get(textField).setText(incremented);
} else {
poundTextFieldList.get(textField).setText(decremented);
}
break;
case 1:
if (incrementDecrement == 0) {
kilogramTextFieldList.get(textField).setText(incremented);
} else {
kilogramTextFieldList.get(textField).setText(decremented);
}
break;
}
}
这是到目前为止的程序图像。每个文本字段动态响应更改。右边的杠铃显示千克板以响应文本字段的变化。
我有 14 对按钮与两组文本字段相关联,它们将相关联的文本字段递增和递减 2。每个文本字段显示有多少对特定重量的盘子要加载到杠铃上。 它们存储在两个二维数组中,一个用于磅,另一个用于千克。 [递增或递减][按钮]
final Button[][] poundIncrementDecrementButton = new Button[2][7];
final Button[][] kilogramIncrementDecrementButton = new Button[2][7];
我正在使用 Scene Builder 和 JavaFX,我正在努力避免编写 28 个 @FXML 事件处理程序。 到目前为止,这是我想出的遍历每个数组的方法,但我不确定如何替换 lambda 表达式来完成这项工作。
// assigns event handlers to increment and decrement buttons.
private void incrementDrecimentButtonEventHandlers() {
// p=1 increment buttons, p=2 decrement buttons
for (int p = 0; p < poundIncrementDecrementButton.length; p++) {
// loops through buttons
for (int j = 0; j < poundIncrementDecrementButton[p].length; j++) {
Button incrementButton = poundIncrementDecrementButton[p][j];
final int incrementDecriment = p;
final int textField = j;
incrementButton.setOnAction((ActionEvent event) -> {
incrementDecrementPlate("pounds", incrementDecriment, textField);
});
}
// k=1 increment buttons, k=2 decrement buttons
for (int k = 0; k < kilogramIncrementDecrementButton.length; k++) {
// loops through buttons
for (int j = 0; j < kilogramIncrementDecrementButton[k].length; j++) {
Button incrementButton = kilogramIncrementDecrementButton[k][j];
final int incrementDecriment = k;
final int textField = j;
incrementButton.setOnAction((ActionEvent event) -> {
incrementDecrementPlate("kilograms", incrementDecriment, textField);
});
}
}
}
}
然后我让事件处理程序使用相关索引调用此方法。
// increments or decrements the plates
private void incrementDecrementPlate(String unit, int incrementDecrement, int textField) {
Double oldValue = Double.parseDouble(poundTextFieldList.get(textField).getText());
String incremented;
String decremented;
if (oldValue % 2 != 0) {
incremented = Double.toString(oldValue + 1);
} else {
incremented = Double.toString(oldValue + 2);
}
if (oldValue % 2 != 0) {
decremented = Double.toString(oldValue - 1);
} else if (oldValue != 0) {
decremented = Double.toString(oldValue - 2);
} else {
decremented = Double.toString(oldValue);
}
switch (unit) {
case "pounds":
if (incrementDecrement == 0) {
poundTextFieldList.get(textField).setText(incremented);
} else {
poundTextFieldList.get(textField).setText(decremented);
}
break;
case "kilograms":
if (incrementDecrement == 0) {
kilogramTextFieldList.get(textField).setText(incremented);
} else {
kilogramTextFieldList.get(textField).setText(decremented);
}
break;
}
}
以下代码演示了如何让一组 (2) 个按钮递增文本字段的值:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class FxMain extends Application {
private Button[] increment, decrement;
private TextField[] txt;
private static final int numberOfGroups = 3;
@Override
public void start(Stage stage) {
initComponents(numberOfGroups);
GridPane root = new GridPane();
for(int row =0; row < numberOfGroups; row++){ //add all components
root.addRow(row, decrement[row], txt[row],increment[row]);
}
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
//create and initialize components
private void initComponents(int size) {
increment = new Button[size]; decrement = new Button[size];
txt = new TextField[size];
for(int group = 0; group < size; group++) {
final int i = group;
txt[i] = new TextField(String.valueOf(0));
increment[i] = new Button("+");
increment[i].setOnAction(a-> updateTxtField(txt[i], 1));//assign handle
decrement[i] = new Button("-");
decrement[i].setOnAction(a-> updateTxtField(txt[i],-1));
}
}
//increment text filed value
private void updateTxtField(TextField textField, int i) {
int newValue = Integer.valueOf(textField.getText()) + i;
textField.setText(String.valueOf(newValue));
}
public static void main(String[] args) { launch(args);}
}
如有需要,请随时提出要求。 如需更多帮助,post MCVE
经过一些实验,我想出了一个解决方案。请记住,这是我使用 Scene Builder、FXML 和 JavaFX 坚持使用 MVC 架构的尝试。
有 14 种不同的盘子,7 种以磅为单位,7 种以公斤为单位。每个板都有一个文本字段,用于显示对于给定的重量,每个板需要加载到杠铃上的数量。这些 textFields 存储在 ObservableLists 中,并在控制器的其他地方被赋予监听器。
// textFields associated with 45, 35, 25, 15, 10, 5, 2.5lb plates
ObservableList<TextField> poundTextFieldList = FXCollections.observableArrayList();
// textFields associated with 25, 20, 15, 10, 5, 2.5, 1.25kg plates
ObservableList<TextField> kilogramTextFieldList = FXCollections.observableArrayList();
这些数组存储盘子的数量。
int[] poundPlatesToLoad = calculator.getPoundPlatesToLoad();
int[] kilogramPlatesToLoad = calculator.getKilogramPlatesToLoad();
这些ArrayLists存储增量按钮
private final ArrayList<Button> poundIncrementButtons = new ArrayList();
private final ArrayList<Button> poundDecrementButtons = new ArrayList();
private final ArrayList<Button> kilogramIncrementButtons = new ArrayList();
private final ArrayList<Button> kilogramDecrementButtons = new ArrayList();
由于我使用了Scene Builder来设计GUI,所以每个按钮都需要@FXML标签来标识它们。我认为没有办法解决这个问题,所以控制器中有 28 个。
@FXML
private Button poundIncrement45Button;
@FXML
private Button poundDecrement45Button;
然后,为了避免编写 28 个处理程序,我编写了 4 个与每个 ArrayList 关联的处理程序。
public void poundIncrementButtonPressed(ActionEvent event) {
System.out.println("pound increment button pressed");
Button button = (Button) event.getSource();
// identifies which plate is to be incremented
int plate = poundIncrementButtons.indexOf(button);
incrementDecrementPlate(0, 0, plate);
}
还有一种增加或减少正确文本字段的方法。
private void incrementDecrementPlate(int unit, int incrementDecrement, int textField) {
int oldValue;
if(unit == 0){
oldValue = (int) poundPlatesToLoad[textField];
} else {
oldValue = (int) kilogramPlatesToLoad[textField];
}
String incremented;
String decremented;
if (oldValue % 2 != 0) {
incremented = Integer.toString(oldValue + 1);
} else {
incremented = Integer.toString(oldValue + 2);
}
if (oldValue % 2 != 0) {
decremented = Integer.toString(oldValue - 1);
} else if (oldValue != 0) {
decremented = Integer.toString(oldValue - 2);
} else {
decremented = Integer.toString(oldValue);
}
switch (unit) {
case 0:
if (incrementDecrement == 0) {
poundTextFieldList.get(textField).setText(incremented);
} else {
poundTextFieldList.get(textField).setText(decremented);
}
break;
case 1:
if (incrementDecrement == 0) {
kilogramTextFieldList.get(textField).setText(incremented);
} else {
kilogramTextFieldList.get(textField).setText(decremented);
}
break;
}
}
这是到目前为止的程序图像。每个文本字段动态响应更改。右边的杠铃显示千克板以响应文本字段的变化。