![](/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.