![](/img/trans.png)
[英]JavaFX 2.2 JFXPanel in Swing application showing Swing modal dialogs
[英]Making JavaFX Alerts/Dialogs Modal within Swing Application
因此,我们再次将完全使用 Swing 的现有 Java 应用程序转换为使用 JavaFX。 但是,该应用程序不会完全使用 JavaFX。 这似乎会导致警报/对话框和模式出现一些问题。 我们目前使用的是 Java 8u40。
主应用程序基本上位于具有菜单的 JFrame 中。 主要内容窗格是 JDesktopPane,单击 MenuItem 会在 DeskopPane 中打开新的 JInternalFrames。 目前,我们正在转换为 JavaFX 的屏幕基本上是 JInternalFrame 中的 JFXPanel。 从 JFXPanel 打开的任何警报/对话框都是面板本身的模式,但不是 JInternalFrame、DeskopPane、Menu 等。
我在 DialogPane 文档中读到,他们计划在 JavaFX 的未来版本中引入一些轻量级对话框,甚至可能引入 InternalFrames,所以也许我们只需要再等一段时间才能使用此功能。 但是,理想情况下,当打开一个新的警报/对话框时,它将是整个应用程序的模态。
编辑:目前正在为模态对话框执行以下操作:
((Stage)getDialogPane().getScene().getWindow()).setAlwaysOnTop(true);
这使得对话框始终显示在顶部,但是即使我们的主应用程序被最小化,该对话框也会保留在其他应用程序的顶部。 它也不会阻止输入到框架中的任何 Swing 组件。
您可以使用以下解决方法,在显示Alert
时创建一个不可见的JDialog
,并在Alert
关闭时处理JDialog
。 这种方法将模态扩展到整个应用程序,包括 Swing 部分。
// create Alert
Alert alert = new Alert(AlertType.INFORMATION, "Hello");
// create invisible JDialog and "show" it
JDialog dialog = new JDialog();
dialog.setModal(true);
dialog.setUndecorated(true);
dialog.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
SwingUtilities.invokeLater(() -> dialog.setVisible(true));
// show Alert
alert.showAndWait();
// close JDialog after Alert is closed
dialog.dispose();
我不认为我完全理解你的问题。 但这是我的猜测 - 您正在尝试从一些JFXPanel
中创建一个警报窗口,该窗口将是模态的(即用户在关闭该警报窗口之前将无法单击您的应用程序)到您的整个应用程序,该应用程序部分使用 swing成分。
如果您的应用程序将纯粹用 JavaFX 编写,那么您将执行类似操作(假设您在JFXPanel
某处创建了一个按钮)
button.setOnAction(evt -> {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.initModality(Modality.APPLICATION_MODAL);
// This will not work in your code
alert.initOwner(button.getScene().getWindow());
alert.show();
});
但由于initOwner
需要一个javafx.stage.window
对象,传递一个 Swing 组件在您的代码中不起作用。 从 Java 8u40 开始,我认为没有正确的方法(即不是黑客)将Alert
对象的所有权设置为摆动组件。 毫不奇怪,这里已经提出了这样的问题,但在撰写本文时尚未回答。
对于您的要求,您可以使用JOptionPane.showMessageDialog
方法及其外观作为解决方法。
button.setOnAction(evt -> {
JOptionPane.showMessageDialog(desktopPane,"My message");
});
默认情况下,这些对话框是模态的,因此无需进行任何操作。 您可以从 JavaFX 组件的任何事件处理程序方法调用这些。
我已经使用在我的 JavaFXFrame 中实现的小接口做了一些解决方法:
public interface DialogParent {
void setOnFocusGained(EventHandler<FocusEvent> focusHandler);
void setOnCloseRequest(EventHandler<WindowEvent> closeHandler);
}
还有我的 JavaFXFrame 实现
public class JavaFXFrame implements DialogParent {
private JFrame frame;
private EventHandler<ch.irix.sumadmin.util.FocusEvent> focusGainedHandler;
private EventHandler<javafx.stage.WindowEvent> windowClosingHandler;
public void JavaFXFrame() {
final JFXPanel fxPanel = new JFXPanel();
frame = new JFrame();
frame.add(fxPanel);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
tryClosing(this);
}
});
frame.addWindowFocusListener(new WindowAdapter() {
@Override
public void windowGainedFocus(WindowEvent e) {
if (focusGainedHandler != null) {
focusGainedHandler.handle(new FocusEvent());
}
}
});
}
public void setVisible(boolean visible) {
frame.setVisible(visible);
}
private void tryClosing(WindowListener listener) {
javafx.stage.WindowEvent windowEvent = new javafx.stage.WindowEvent(null, javafx.stage.WindowEvent.WINDOW_CLOSE_REQUEST);
if (windowClosingHandler != null) {
windowClosingHandler.handle(windowEvent);
}
if (!windowEvent.isConsumed()) {
frame.setVisible(false);
}
}
@Override
public void setOnFocusGained(EventHandler<ch.irix.sumadmin.util.FocusEvent> focusGainedHandler) {
this.focusGainedHandler = focusGainedHandler;
}
@Override
public void setOnCloseRequest(EventHandler<javafx.stage.WindowEvent> windowClosingHandler) {
this.windowClosingHandler = windowClosingHandler;
}
}
并显示警报:
public static void showAlert(Alert alert) {
DialogPane dialogPane = alert.getDialogPane();
final Stage stage = new Stage();
stage.setScene(dialogPane.getScene());
List<ButtonType> buttonTypes = dialogPane.getButtonTypes();
for (ButtonType buttonType : buttonTypes) {
ButtonBase button = (ButtonBase) dialogPane.lookupButton(buttonType);
button.setOnAction(evt -> {
dialogPane.setUserData(buttonType);
stage.close();
});
}
dialogParent.setOnFocusGained(event -> {
stage.toFront();
});
dialogParent.setOnCloseRequest(Event::consume);
stage.setOnCloseRequest(event -> {
dialogParent.setOnFocusGained(null);
dialogParent.setOnCloseRequest(null);
});
stage.show();
}
希望能帮到你
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.