java - 在 JavaFx 应用程序中未正确显示 Swing 内容
问题描述
我目前正在开发 JavaFx 应用程序。Fx 应该只负责 UI 内容,而相当复杂的功能位于另一个已经完成的项目中,该项目是使用 Swing 创建的。为此,我使用 Scenebuilder 构建了一个 FXML,然后将多个 Swing 面板传递到单独的 SwingNode 中,并将 SwingNode 传递到 TabPane 的不同选项卡中(全部在我的 Application 类的 start() 方法中完成)。启动程序后,一切看起来都很好,Swing 和 Fx 内容显示正确,功能也正常工作。但是,当手动调整应用程序窗口的大小时,SwingNode 内容行为异常,有时选项卡保持为空,有时只绘制节点的一部分,有时它只是显示完全黑色。
现在,实际启动的程序是“旧”的 Swing 项目,它在某些时候使用 Platform.startup() 来启动 FX 应用程序。出于功能原因,这是必要的。那时的 Swing 面板被传递到位于 Fx 项目中的 SwingNodes。
我试图通过在窗口调整大小上不断设置 SwingNode-Content 来“更新” SwingNodes。我还尝试重新绘制 Swing 内容。两种尝试都没有成功。
我错过了什么?为什么 SwingNode 内容不与窗口的其余部分一起调整大小?Swing 内容是否可能太大而无法正常运行?还是可能存在一些多线程问题?
我知道如果没有任何代码示例,这个问题可能很难理解。我目前正在创建两个项目的简约版本,以重现我的问题,并在完成后立即更新。
编辑:我相信我能够重现该问题并尝试将所有内容包括在下面。fx
被传递给swing
BuildPath,但不是相反。运行时swing
会打开一个 FX 窗口,其中包含三个选项卡,所有选项卡都充满了 SwingNode。但是,当用户调整此窗口的大小时,只有活动选项卡的 SwingNode 才能正确重新绘制。其他两个选项卡仍然包含节点,但是元素只有在鼠标悬停在它们上方时才会重新出现 - 这不适用于标签。我已经尝试在 SwingNodes 上使用重绘,但到目前为止没有成功,所以我选择不在这里包含它。
第二次编辑:删除了 FXML 和 FXML 控制器类,以使问题更小一些。FXML 只是一个简单的 TabPane,在 SceneBuilder 中内置了 3 个选项卡,控制器仅包含 3 个选项卡的 Getter。
调整大小并将鼠标悬停在 10 个按钮中的 3 个上后的选项卡 2
该项目fx
包含MainFx
扩展应用程序的类和DebugWindowController
FXML 文件的控制器。还有一个
由项目中MainInterface
的类实现的接口Main
swing
班级MainFx
package controllers;
import interfaces.MainInterface;
import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class MainFx extends Application {
private DebugWindowController debugWindowController;
private AnchorPane mainRoot;
private final SwingNode swingNode1 = new SwingNode();
private final SwingNode swingNode2 = new SwingNode();
private final SwingNode swingNode3 = new SwingNode();
private MainInterface mainInterface = null;
@Override
public void start(Stage primaryStage) {
try {
FXMLLoader debugWindowLoader = new FXMLLoader(getClass().getResource("/view/DebugWindow.fxml"));
mainRoot = debugWindowLoader.load();
debugWindowController = debugWindowLoader.getController();
Scene scene1 = new Scene(mainRoot);
fillFxTabPane();
primaryStage.setScene(scene1);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
private void fillFxTabPane() {
swingNode1.setContent(mainInterface.getPanel1());
swingNode2.setContent(mainInterface.getPanel2());
swingNode3.setContent(mainInterface.getPanel3());
debugWindowController.getTab1().setContent(swingNode1);
debugWindowController.getTab2().setContent(swingNode2);
debugWindowController.getTab3().setContent(swingNode3);
}
public MainInterface getMainInterface() {
return mainInterface;
}
public void setMainInterface(MainInterface mainInterface) {
this.mainInterface = mainInterface;
}
}
界面MainInterface
package interfaces;
import javax.swing.JComponent;
public interface MainInterface {
JComponent getPanel1();
JComponent getPanel2();
JComponent getPanel3();
}
该项目swing
仅包含一个类,其中包含用于启动程序的 main() 方法。班级Main
package swing;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import controllers.MainFx;
import interfaces.MainInterface;
import javafx.application.Platform;
import javafx.stage.Stage;
public class Main implements MainInterface {
private JPanel panel1;
private JPanel panel2;
private JPanel panel3;
public Main() {
panel1 = new JPanel();
JLabel label1 = new JLabel("Panel1");
panel1.add(label1);
for (int i = 0; i < 10; i++) {
JButton button = new JButton("B" + (i + 1));
panel1.add(button);
}
panel2 = new JPanel();
JLabel label2 = new JLabel("Panel2");
panel2.add(label2);
for (int i = 0; i < 10; i++) {
JButton button = new JButton("B" + (i + 1));
panel2.add(button);
}
panel3 = new JPanel();
JLabel label3 = new JLabel("Panel3");
panel3.add(label3);
for (int i = 0; i < 10; i++) {
JButton button = new JButton("B" + (i + 1));
panel3.add(button);
}
MainFx mainFx = new MainFx();
mainFx.setMainInterface(this);
Platform.startup(() -> {// launch JavaFx application
Stage stage = new Stage();
try {
mainFx.start(stage);
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
public static void main(String[] args) {
Main main = new Main();
}
@Override
public JComponent getPanel1() {
return panel1;
}
@Override
public JComponent getPanel2() {
return panel2;
}
@Override
public JComponent getPanel3() {
return panel3;
}
}
解决方案
推荐阅读
- excel - 根据条件粘贴行
- c - 请解释为什么循环执行了 11 次
- typescript - 如何用打字稿开玩笑地模拟静态方法和实例
- ios - 如果在创建 tableView Cell 时没有指定 indexPath 会发生什么?cellForRowAt()
- git - 当我在 jupyter 中进行更改时,.ipynb 文件没有更新
- javascript - 无法向 jQuery 元素添加属性
- java - 容器启动失败:在 Bitbucket 管道上的集成测试中使用 Testcontainers Localstack 1.15.0-rc2 和 Maven/Spring Boot
- reactjs - React-Firebase:为什么在我的一个组件中无限调用 console.log?
- c# - 我的启动画面无法正确隐藏或关闭
- node.js - 无法从新区域发布到 SNS