如何在JavaFX8中调整SwingNode内部的Swing控件?

如何在SwingNode中调整SwingNode内部的Swing控件?

有时,我在SwingNode调整了控件大小。 但是SwingNode似乎抵制了这一点。

resize() apidoc中说,那

应用程序不应直接调用此方法。 如果应用程序需要直接设置SwingNode的大小,则应设置Swing组件的最小/首选/最大大小约束,这些约束将相应地传播到SwingNode,并且它的父级将在布局期间遵循这些设置。

但显然它不起作用。

示例代码如下。

问题是:如何让控制变得更大?

 public class Try_Sizes_01 extends Application { private static final Logger log = LoggerFactory.getLogger(Try_Sizes_01.class); private static final String text = "Very Long Text For Appear On Button "; private static int position = 7; //private JButton button = new JButton("short"); private JButton button = new JButton(text.substring(0, position)); private SwingNode swingNode = new SwingNode(); { swingNode.setContent(button); } @Override public void start(Stage stage) throws Exception { Group group = new Group(); group.getChildren().add(swingNode); Scene scene = new Scene(group); stage.setTitle("Try_Sizes_01"); stage.setScene(scene); stage.show(); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new Timer(1000, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { /* button.setText(button.getText() + text.charAt(position)); position++; if( position >= text.length() ) { position=0; } */ button.setPreferredSize(new Dimension((int)button.getPreferredSize().getWidth()+10, (int)button.getPreferredSize().getHeight())); button.setMinimumSize(new Dimension((int)button.getPreferredSize().getWidth(), (int)button.getPreferredSize().getHeight())); //button.revalidate(); //button.setBounds(0, 0, (int)button.getBounds().getWidth()+10, (int)button.getBounds().getHeight()); Platform.runLater(new Runnable() { @Override public void run() { //swingNode.autosize(); // does not work //swingNode.resize(button.getBounds().getWidth(), button.getBounds().getHeight()); // does not work and cancels button resizing //swingNode.setContent(button); // works sometimes but imperfect } }); log.info("Swing thread"); log.info("Preferred width is now = {}", button.getPreferredSize().getWidth()); log.info("Bounds width is now = {}", button.getBounds().getWidth()); } }).start(); } }); } public static void main(String[] args) { launch(args); } } 

在基本相同的问题上打了几个小时之后,我终于弄清楚发生了什么。

基本上,问题是SwingNode的父级在布局发生时尝试根据父级的大小设置其大小。 因此,当您调整按钮大小,然后触发布局时,SwingNode的父级会将其设置回其默认大小。 之所以发生这种情况是因为SwingNode会覆盖isResizable()方法以返回true,从而为其父对象提供权限以调整其大小。

为了避免这种情况,您可以:

  • 创建一个SwingNode的自定义子类,它将isResizable()重写为false,

要么:

  • 在包含SwingNode的组上调用setAutosizeChildren(false)。

如果您在FXML中定义类,则可能需要使用后一种技术。

顺便提一下,即使它覆盖了isResizable()为false,你仍然可以在SwingNode上调用resize(width,height)。

我不确定它是否完全相同,但似乎与使用父容器正确地调整摆动组件的意义相关。 在我的情况下,我有一个包含JFreeChart(ChartPanel)的SwingNode,当父框架(SplitPane中的边框窗格)本身已resize时,我无法正确resize。 最后,我只是为高度/宽度属性添加了一个监听器:

 pane.widthProperty().addListener((w,o,n)->c.resizeChart((int)n.intValue(), (int)pane.getHeight())); pane.heightProperty().addListener((w,o,n)->c.resizeChart((int)pane.getWidth(), (int)n.intValue())); 

我试过的其他任何东西都不能模仿这个。 谢谢

我发现窗格监听器有帮助,但由于我的组件的专有性质,它仍然没有resize。 我正在使用fxml并尝试将SwingNode放在窗格中以进行布局。 然后我注意到一些示例使用的是StackPane,而不仅仅是一个Pane,突然之间只是对代码的修改进行了改动。 这是在AnchorPane内部,它似乎也确保了组件的初始显示填充了所有可用空间。 总而言之,AnchorPane中的所有Anchor设置为0的StackPane确保了所有初始可用空间的受控填充,然后完成所有resize,当手动resize的侦听器时,它们全部开始工作。

 pane.widthProperty().addListener((w,o,n)->c.resizeChart((int)n.intValue(), (int)pane.getHeight())); pane.heightProperty().addListener((w,o,n)->c.resizeChart((int)pane.getWidth(), (int)n.intValue()));