gpt4 book ai didi

java - 我可以从 javaFX 中的 setOnAction 参数调用另一个类吗?

转载 作者:行者123 更新时间:2023-11-30 07:57:38 27 4
gpt4 key购买 nike

我是一个初级程序员,我学了足够多的 java,现在我的目标是使用 JavaFX 为 gui 创建一个计算器,并尽可能让它成为 oop,这样在实践中,其他人很容易修改程序,我在添加按钮并想对其应用 setOnAction 方法时遇到问题,我想有一个单独的类来处理按钮事件,但我不明白如何使用这个特殊的方法

这是 Gui 类:

package calculator;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Gui extends Application {

InputHandler inputhandler = new InputHandler();

Button add = new Button();

@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("HackCalc");


add.setText("+");
add.setOnAction(inputhandler);


StackPane layout = new StackPane();
layout.getChildren().add(add);

Scene scene = new Scene(layout, 330, 500);

primaryStage.setScene(scene);
primaryStage.show();
}
}

如您所见,我已经创建了一个 InputHandler 类的实例,我将向您展示并将其传递给 setOnAction 但它从未奏效,我遇到了一个令人沮丧的 NoSuchMethodException 错误。

现在,这是 InputManager 类:

import javafx.event.ActionEvent;
import javafx.event.EventHandler;

public class InputHandler extends Gui implements EventHandler<ActionEvent>{

@Override
public void handle(ActionEvent event) {
if(event.getSource()== add){
System.out.println("InputHandler works");
}
}
}

最佳答案

首先 InputHandler 扩展 Gui 就设计而言没有意义,因为 "is" 关系 InputHandlerGui/Application.

您最好使用匿名类/lambda 表达式作为事件处理程序,并取消对按钮的检查,但改用不同的事件处理程序。这样你就可以摆脱所有的 if (source == someButton) 检查...

有意义的是将 View 与计算器逻辑分开,使 GUI 独立于计算器逻辑。

示例

public class Calculator {

private final ObservableList<String> formulaParts = FXCollections.observableArrayList();
private final ObservableList<String> formulaPartsUnmodifiable = FXCollections.unmodifiableObservableList(formulaParts);
private final ReadOnlyStringWrapper operandString = new ReadOnlyStringWrapper();
private Integer operand;
private Integer previousOperand;
private IntBinaryOperator operator;
private boolean operandModifiable = true;

/** previous input elements as Strings */
public ObservableList<String> getFormulaParts() {
return formulaPartsUnmodifiable;
}

public final String getOperand() {
return this.operandString.get();
}

/** property contains current input as String */
public final ReadOnlyStringProperty operandProperty() {
return this.operandString.getReadOnlyProperty();
}

public void addDigit(byte digit) {
if (operandModifiable) {
operand = operand == null ? digit : operand * 10 + digit;
operandString.set(Integer.toString(operand));
}
}

public void addBinaryOperator(IntBinaryOperator operator) {
if (operand != null) {
if (previousOperand != null) {
evaluate();
}

previousOperand = operand;
operand = null;
operandString.set("");
formulaParts.setAll(Integer.toString(previousOperand), operator.toString());
this.operator = operator;
operandModifiable = true;
}
}

public void evaluate() {
if (operand != null && operator != null) {
int result = operator.applyAsInt(previousOperand, operand);
formulaParts.clear();
operandString.set(Integer.toString(result));
operandModifiable = false;
previousOperand = null;

operand = result;
}
}

}
public class BinaryPlusOperator implements IntBinaryOperator {

@Override
public int applyAsInt(int left, int right) {
return left + right;
}

@Override
public String toString() {
return "+";
}

}
public class Gui extends Application {

private final static IntBinaryOperator PLUS = new BinaryPlusOperator();

@Override
public void start(Stage primaryStage) {
Calculator calc = new Calculator();

// display parts of formula in ListView
ListView<String> formulaPartsDisplay = new ListView<>(calc.getFormulaParts());
formulaPartsDisplay.setMaxHeight(30);
formulaPartsDisplay.setOrientation(Orientation.HORIZONTAL);

Text operand = new Text();
operand.setFont(Font.font(20));

// display current input in Text
operand.textProperty().bind(calc.operandProperty());

VBox display = new VBox(5, formulaPartsDisplay, operand);
display.setAlignment(Pos.CENTER_RIGHT);
VBox.setVgrow(display, Priority.NEVER);
display.setBorder(new Border(new BorderStroke(Color.GREEN, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, new BorderWidths(3))));

Button plus = new Button("+");
Button eval = new Button("=");
Button d1 = new Button("1");

// event handlers invoke appropriate methods of Calculator
plus.setOnAction(evt -> calc.addBinaryOperator(PLUS));
eval.setOnAction(evt -> calc.evaluate());
d1.setOnAction(evt -> calc.addDigit((byte) 1));

GridPane buttons = new GridPane();
buttons.add(d1, 0, 0);
buttons.addRow(1, plus, eval);

Scene scene = new Scene(new VBox(display, buttons));

primaryStage.setScene(scene);
primaryStage.show();
}

关于java - 我可以从 javaFX 中的 setOnAction 参数调用另一个类吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41070280/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com