【发布时间】:2015-10-14 15:31:11
【问题描述】:
我目前正在使用 JavaFX 开发一个计算器,目前正在尝试实现键盘输入支持。
为此,我试图在主 .java 文件中实现一个 EventHandler,如下所示:
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene_main = new Scene(root);
stage.setScene(scene_main);
stage.show();
scene_main.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent keyEvent) {
switch (keyEvent.getCode()) {
case ENTER:
System.out.println("Enter");
break;
case ADD:
System.out.println("Plus");
break;
case SUBTRACT:
System.out.println("Minus");
break;
case DIVIDE:
System.out.println("Division");
break;
case MULTIPLY:
System.out.println("Multiply");
break;
}
}
}
);
}
FXMLDocumentController.java:
import java.net.URL;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.Random;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;
/**
*
* @author ilja
*/
public class FXMLDocumentController implements Initializable {
@FXML
private void handleTestAction(ActionEvent event) throws Exception {
((Node) (event.getSource())).getScene().getWindow().hide();
Parent parent = FXMLLoader.load(getClass().getResource("/calculator/CrashPopup.fxml"));
Stage stage = new Stage();
Scene scene = new Scene(parent);
stage.setScene(scene);
stage.setTitle("Teeeeest");
stage.show();
}
private enum State {
EQUALED, FIRST, SECOND, OPERATOR
}
public static String operator = "+";
private double oldValue = 0;
private double newValue = 0;
private double result = 0;
private String oldText, newText;
private String digit;
private boolean equaled = false;
Random r = new Random();
int i1;
private State state = State.EQUALED;
NumberFormat nf = new DecimalFormat("##.###", new DecimalFormatSymbols(Locale.US));
@FXML
private TextField displayField;
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
displayField.setText("0");
}
@FXML
private void handleDotAction(ActionEvent event) {
double result;
oldText = displayField.getText();
if (!oldText.isEmpty() && !oldText.contains(".")) {
newText = oldText + ".";
} else {
newText = oldText;
}
displayField.setText(newText);
result = Double.parseDouble(newText);
if (state == State.EQUALED || state == State.FIRST) {
oldValue = result;
state = State.FIRST;
} else {
newValue = result;
state = State.SECOND;
}
}
@FXML
private void handleDigitAction(ActionEvent event) {
digit = ((Button) event.getSource()).getText();
if (state == State.FIRST || state == State.SECOND) {
oldText = displayField.getText();
} else {
oldText = "";
}
if ("0".equals(oldText) /*|| "0.0".equals(oldText)*/) {
displayField.setText(digit);
} else {
displayField.setText(oldText + digit);
}
if (state == State.EQUALED || state == State.FIRST) {
oldValue = Double.parseDouble(displayField.getText());
state = State.FIRST;
} else {
newValue = Double.parseDouble(displayField.getText());
state = State.SECOND;
}
}
@FXML
private void handleOperator(ActionEvent event) {
if (state == State.EQUALED) {
operator = ((Button) event.getSource()).getText();
}
if (state == State.SECOND) {
switch (operator) {
case "+":
oldValue += newValue;
break;
case "-":
oldValue -= newValue;
break;
case "*":
oldValue *= newValue;
break;
case "/":
oldValue /= newValue;
break;
default:
break;
}
result = oldValue;
newValue = 0;
displayField.setText(String.valueOf(nf.format(oldValue)));
}
operator = ((Button) event.getSource()).getText();
state = State.OPERATOR;
}
@FXML
private void handleEqualAction(ActionEvent event) throws Exception{
i1 = r.nextInt(6 - 0) + 0;
if (i1 == 1) {
((Node) (event.getSource())).getScene().getWindow().hide();
Parent parent = FXMLLoader.load(getClass().getResource("/calculator/CrashPopup.fxml"));
Stage stage = new Stage();
Scene scene = new Scene(parent);
stage.setScene(scene);
stage.setTitle("Unerwarteter Fehler");
stage.show();
}
switch (operator) {
case "+":
oldValue += newValue;
break;
case "-":
oldValue -= newValue;
break;
case "*":
oldValue *= newValue;
break;
case "/":
oldValue /= newValue;
break;
default:
break;
}
result = oldValue;
displayField.setText(String.valueOf(nf.format(oldValue)));
state = State.EQUALED;
}
@FXML
private void handleClearAction(ActionEvent event) {
displayField.setText("0");
oldValue = 0;
newValue = 0;
operator = "+";
state = State.EQUALED;
}
@FXML
private void handleClearEntryAction(ActionEvent event) {
displayField.setText("0");
newValue = 0;
switch (state) {
case EQUALED:
displayField.setText(String.valueOf(nf.format(result)));
break;
case FIRST:
oldValue = 0;
state = State.EQUALED;
break;
case SECOND:
case OPERATOR:
newValue = 0;
state = State.OPERATOR;
break;
default:
break;
}
}
private void handleZeroAction(ActionEvent event) {
digit = ((Button) event.getSource()).getText();
oldText = displayField.getText();
if ("0".equals(oldText) || "0.0".equals(oldText)) {
newText = oldText;
} else {
newText = oldText + digit;
}
displayField.setText(newText);
}
}
现在的问题是,每当按下这些键时,都会发生与我在 GUI 中单击相应按钮时相同的情况。
所有数字按钮共享一个 onAction 事件,+,-,/,* 也共享一个,等等。 它们都使用 FXMLDocumentController.java 文件中的变量。
所以我不确定最好的处理方法是什么。我可以只从 main.java 文件中调用 onAction 事件,还是应该将方法内容复制粘贴(这会导致冗余)到该文件中并使变量公开/受保护?
我尝试从主文件中调用方法但失败了,因为我不明白该方法将获得哪些参数,因为它们需要一个 ActionEvent 对象。
【问题讨论】:
-
可以显示控制器代码吗?
-
不久前,我创建了一个小型示例计算器。它只是一个玩具项目,并没有被设计为一个健壮的、功能齐全的实现。不过你不妨review the code看看里面有没有你想用的点子。
标签: javafx parameters