【问题标题】:How to resize Swing control which is inside SwingNode in JavaFX8?如何调整 JavaFX8 中 SwingNode 内部的 Swing 控件的大小?
【发布时间】:2013-12-19 11:52:27
【问题描述】:

如何调整 JavaFX8 中 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);
    }

}

【问题讨论】:

    标签: java swing javafx javafx-8


    【解决方案1】:

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

    基本上,问题在于 SwingNode 的父级试图在布局发生时根据父级的大小设置其大小。因此,当您调整按钮大小,然后触发布局时,SwingNode 的父级会将其设置回默认大小。这是因为 SwingNode 覆盖了 isResizable() 方法以返回 true,从而允许其父对象调整其大小。

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

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

    或:

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

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

    请注意,顺便说一下,您仍然可以在 SwingNode 上调用 resize(width,height),即使它将 isResizable() 覆盖为 false。

    【讨论】:

      【解决方案2】:

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

      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()));
      

      我尝试过的其他任何事情都无法模仿这一点。 谢谢

      【讨论】:

        【解决方案3】:

        我发现窗格监听器有帮助,但由于我的组件的专有性质,它仍然没有调整大小。我正在使用 fxml 并尝试将 SwingNode 放置在窗格中以进行布局。然后我注意到许多示例使用了 StackPane 而不仅仅是一个窗格,并且突然间刚刚进行了这个更改,代码可以正常工作。这是在 AnchorPane 中,它似乎也确保了组件的初始显示填充了所有可用空间。总之,AnchorPane 中的 StackPane 将所有 Anchors 设置为 0,确保控件填充所有初始可用空间,然后进行所有调整大小,当手动调整大小的侦听器开始工作时。

        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()));
        

        【讨论】:

        • 什么是'c'对象?还是窗格?
        猜你喜欢
        • 2018-03-10
        • 2015-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-08
        • 1970-01-01
        相关资源
        最近更新 更多