我已将此控制器连接到带有多个按钮,标签,表格等的FXML文件。 我有一些弹出窗口被初始化并显示当点击不同的按钮并且工作正常。
我还有另一个弹出窗口,当出现问题时我想“弹出”,所以当从另一个类的java代码发送一个事件得到处理时调用它。
调用此消息弹出窗口,但Platform.runLater()中的代码未执行,实际上冻结了GUI。
我发现有一个区别似乎导致了这一点,那就是我在Platform.runLater()之前调用的Platform.isFxApplicationThread()在此消息弹出窗口中返回false,其中一个返回true通过按钮单击调用其他弹出窗口。
因为我还尝试过一个通常从按钮点击调用的弹出窗口,当从因为传入事件而被执行的代码中调用它时也不起作用,我很确定这是问题所在,但是Platform.runLater声明“可以从任何线程调用此方法,将Runnable发布到事件队列,然后立即返回给调用者。”对我来说这似乎不对,所以如果这实际上是问题,我有点不解......
之前有没有人遇到过这个和/或有没有人知道我做错了什么?
这很好用:
@FXML
private void btnCashClicked(ActionEvent event) {
screensController.getCashTransactionController().addCashTransactionListener(this);
labelToPay = new Label(eurosToPay + " euro");
sealbagTextField = new SealbagTextField();
PopupUtils.showCashPaymentPopup(btnSealbag, btnCashOk, labelPaid, labelSealbag, labelToPay, lblExchange,
labelExchange, labelReturnValue, eurosToPay, btnCash, this, sealbagTextField);
screensController.getMainController().startTransaction(amountInCents, PaymentType.Asap);
}
同一控制器类中的此代码不显示弹出窗口:
@Override
public void showErrorOnScreen(String message) {
// temporary usage of label and textfield
labelToPay = new Label(eurosToPay + " euro");
sealbagTextField = new SealbagTextField();
PopupUtils.showCashPaymentPopup(btnSealbag, btnCashOk, labelPaid, labelSealbag, labelToPay, lblExchange,
labelExchange, labelReturnValue, eurosToPay, btnCash, this, sealbagTextField);
//PopupUtils.showMessagePopup("Error", message, "Close", 374, 250, btnCancel);
}
我在Windows上使用jre1.8.0_60
cashPopup的代码:
public static int showCashPaymentPopup(Button btnSealbag, Button btnCashOk, Label labelPaid, Label labelSealbag, Label labelToPay, Label lblExchange, Label labelExchange, Label labelReturnAmount, int amount, Node node, PayScreen parent, SealbagTextField sealbagTextField) {
int paid = 0;
logger.debug("cashPopup is on GUI thread: " + Platform.isFxApplicationThread());
Platform.runLater(new Runnable() {
@Override
public void run() {
cashPopup.getContent().clear();
Rectangle rectangle = new Rectangle();
rectangle.setArcHeight(20);
rectangle.setArcWidth(20);
rectangle.setFill(Color.LIGHTBLUE);
rectangle.setWidth(466);
rectangle.setHeight(311);
rectangle.setStroke(Color.DARKBLUE);
rectangle.setStrokeType(StrokeType.INSIDE);
...
cashPopup.getContent().addAll(rectangle, textArea, headerLabel, lblDesc, lblAmount, labelAmount, lblPaid, labelPaid, lblToPay, labelToPay, btnCashOk, lblSealbag, labelSealbag, lblExchange, labelExchange, labelReturnAmount, btnSealbag, btnCancel);
cashPopup.show(node, 150, 164);
}
});
return paid;
}
showMessagePopup:
public static void showMessagePopup(String title, String text, String buttonText, int posX, int posY, Node parent) {
logger.debug("messagePopup is on GUI thread: " + Platform.isFxApplicationThread());
Platform.runLater(new Runnable() {
@Override
public void run() {
logger.debug("0");
messagePopup.getContent().clear();
Rectangle rectangle = new Rectangle();
rectangle.setArcHeight(20);
rectangle.setArcWidth(20);
rectangle.setFill(Color.LIGHTBLUE);
rectangle.setWidth(500);
rectangle.setHeight(300);
rectangle.setStroke(Color.DARKBLUE);
rectangle.setStrokeType(StrokeType.INSIDE);
Label headerLabel = new Label(title);
headerLabel.setStyle("-fx-font-size: 18; -fx-font-family: Arial;");
headerLabel.setLayoutX(15);
headerLabel.setLayoutY(10);
TextArea textArea = new TextArea();
textArea.setStyle("-fx-font-size: 14; -fx-font-family: Arial;");
textArea.setLayoutX(10);
textArea.setLayoutY(35);
textArea.setMaxWidth(480);
textArea.setMinHeight(190);
textArea.setMaxHeight(190);
textArea.setEditable(false);
textArea.setWrapText(true);
textArea.setText(text);
Button btnClose = new Button(buttonText);
btnClose.setLayoutX(180);
btnClose.setLayoutY(235);
btnClose.setPrefSize(120, 54);
btnClose.setStyle("-fx-font-size: 18; -fx-font-family: Arial; -fx-text-fill:white; -fx-background-color: linear-gradient(#8b9aa1, #456e84), linear-gradient(#c5dde7, #639fba), linear-gradient(#79abc1, #639fba); -fx-background-insets: 0,1,2; -fx-background-radius: 6,5,4;");
btnClose.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
messagePopup.hide();
}
});
messagePopup.getContent().addAll(rectangle, headerLabel, btnClose, textArea);
messagePopup.show(parent, posX, posY);
}
});
}
logger.debug(“0”)甚至没有执行......
答案 0 :(得分:-1)
通过在调试模式下运行并挂起Java FX线程来查看它正在做什么,找到它。 这个“其他线程”从主程序开始,需要在流程继续之前启动。这个其他线程看起来像这样:
pinPadAsSlaveThread = new Thread(pinPadAsSlave);
pinPadAsSlaveThread.start();
while (!pinPadAsSlave.isRunning()) {
// wait for pinPadAsSlave to be running
try {
Thread.sleep(10);
} catch(InterruptedException ie) {
// ignore
}
}
通常这需要大约50 ms,但由于引脚焊盘在网络上不可用,因此这将成为无限循环。当然,应该通过让这个循环只尝试50次左右来处理。 但真正的问题是这个连续10毫秒睡眠的线程是Java FX线程。我不知道为什么Java FX线程正在设置通信,因为它不应该(并且我没有通过将它放在platform.runLater或类似的东西中来要求),但事实是:它是......