javafx 和swing
我很快将不得不在基于Swing的胖客户端中处理JavaFX –哦,对不起,我的意思是“多层富客户端”!
因此,这使我来看看JFXPanel 。 JFXPanel是一个javax.swing.JComponent,用于将JavaFX内容嵌入到Swing-UI中。 JFXPanel的用法类似于JPanel,并且可以通过EDT作为通用Swing组件进行访问,除了必须通过JavaFX应用程序线程来处理JavaFX组件之外。
为了解决这些问题,我创建了两个类似的面板(Swing + JavaFX),每个面板都有一个按钮,一个TextField和一个Label,并将它们放置在JSplitPane和JFrame中:
仔细看里面
要尝试Swing <-> JavaFX互操作性,按钮操作是将文本从TextField设置为JLabel,反之亦然。
JPanel处理通用的Swing东西没有什么特别的,但是JFXPanel包含JavaFX控件:
public class SwingFXPanel extends JFXPanel {
private Button testButton;
private TextField testTextField;
private Label testLabel;
private VBox pane;
public SwingFXPanel() {
init();
}
private void init() {
testButton = new Button("I am a JavaFX Button");
testTextField = new TextField();
testLabel = new Label("empty");
pane = new VBox();
pane.setAlignment(Pos.CENTER);
pane.getChildren().addAll(testTextField, testButton, testLabel);
Platform.runLater(this::createScene);
}
private void createScene() {
Scene scene = new Scene(pane);
setScene(scene);
}
public Button getTestButton() {
return testButton;
}
public TextField getTestTextField() {
return testTextField;
}
public Label getTestLabel() {
return testLabel;
}
}
这里很重要:将场景添加到JavaFX Application线程内的JFXPanel:
Platform.runLater(this::createScene);
如果您致电:
createScene()
从另一个线程,您会获得Runtime-Exception:
java.lang.IllegalStateException: Not on FX application thread; currentThread = AWT-EventQueue-0
同样,每次与JavaFX相关内容的交互都必须放在JavaFX Application Thread上:
例如:
Platform.runLater(() -> {
swingFXPanel.getTestLabel().setText(swingPanel.getTestTextField().getText());
});
public class InteropFrame extends JFrame {
private JSplitPane centralSplitPane;
private SwingPanel swingPanel;
private SwingFXPanel swingFXPanel;
public InteropFrame(){
init();
}
private void init() {
setTitle("Swing <-> JavaFX Interoperatbiliy");
setSize(500, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
centralSplitPane = new JSplitPane();
centralSplitPane.setDividerLocation(0.5);
centralSplitPane.setResizeWeight(0.3);
swingPanel = new SwingPanel();
swingFXPanel = new SwingFXPanel();
swingPanel.getTestButton().addActionListener((ActionEvent e) -> {
Platform.runLater(() -> {
swingFXPanel.getTestLabel().setText(swingPanel.getTestTextField().getText());
});
});
swingFXPanel.getTestButton().setOnAction((javafx.event.ActionEvent t) -> {
swingPanel.getTestLabel().setText(swingFXPanel.getTestTextField().getText());
});
centralSplitPane.setLeftComponent(swingPanel);
centralSplitPane.setRightComponent(swingFXPanel);
add(centralSplitPane, BorderLayout.CENTER);
}
}
另外,处理FXML也很简单:
public class SwingFXMLPanel extends JFXPanel {
@FXML
private Button testButton;
@FXML
private TextField testTextField;
@FXML
private Label testLabel;
private VBox rootPane;
private URL fxmlResource;
public SwingFXMLPanel(URL fxmlResource){
this.fxmlResource = fxmlResource;
init();
}
private void init(){
rootPane = new VBox();
FXMLLoader loader = new FXMLLoader(fxmlResource);
loader.setController(this);
loader.setRoot(rootPane);
try {
loader.load();
} catch (IOException ex) {
Logger.getLogger(SwingFXMLPanel.class.getName()).log(Level.SEVERE, null, ex);
}
testButton.setText("I am a JavaFX Button");
testLabel.setText("empty");
Platform.runLater(this::createScene);
}
private void createScene() {
Scene scene = new Scene(rootPane);
setScene(scene);
}
public Button getTestButton() {
return testButton;
}
public TextField getTestTextField() {
return testTextField;
}
public Label getTestLabel() {
return testLabel;
}
}
对我来说,让我的同事尽可能多地接受在Swing中使用JavaFX至关重要。
因此,我想简化特定的FX应用程序线程处理。 因此,如果使用JPanel的主要区别只是添加以下内容,那么也许可以实现:
private void createScene() {
Scene scene = new Scene(rootPane);
setScene(scene);
}
并致电:
Platform.runLater(this::createScene);
在JFXPanel中 。
- 您可以在此处找到完整的示例代码。
翻译自: https://www.javacodegeeks.com/2014/11/swing-and-javafx-working-with-jfxpanel.html
javafx 和swing
本文介绍了如何在Swing应用中使用JavaFX的JFXPanel组件,通过示例展示了如何创建含有JavaFX控件的Swing面板,并强调了所有JavaFX组件的操作必须在JavaFX Application线程中进行。同时,文章讨论了简化FX线程处理的可能性。

4257

被折叠的 条评论
为什么被折叠?



