【问题标题】:How to change the dimension of a component in a JFrame如何更改 JFrame 中组件的尺寸
【发布时间】:2012-11-13 01:14:45
【问题描述】:

假设我在 JFrame 中有一个 JPanel。当我调用更改该 JPanel 的首选大小的方法时,它不会更改。

代码如下所示:

public class SomePanel extends JPanel{

    public SomePanel(){
        setPreferredSize( new Dimension( 390, 40 ) );
        setBackground( Color.BLACK );
    }

    public void expand(){
        setPreferredSize( new Dimension( 390, 200 ) );
    }

    public static void main( String args[] ){
        JFrame frame = new JFrame();
        frame.setSize( 450, 500 );
        frame.setLayout( new FlowLayout() );

        SomePanel somePanel = new SomePanel();

        frame.add( somePanel );
        frame.setVisible( true );

        somePanel.expand();
    }
}

有什么我必须先做的吗?我试过在调用 expand() 时检查 JPanel 的大小。 JPanel 在设置首选大小前后的高度保持在 40。

我也尝试过使用 Dimension 变量,但也没有用。

    Dimension dimension;

    public SomePanel(){
        dimension = new Dimension( 390, 40 );
        ...
    }

    public expand(){
        dimension.setSize( 390, 200 );
        setPreferredSize( dimension );
    } 

【问题讨论】:

标签: java swing components jframe jpanel


【解决方案1】:

+1 给所有人。

我通常使用以下组合:

revalidate()pack()。 (see @GagandeepBali and @StanislavL answer here for more reasoning as to my choice of revalidate()) 对于pack(),这允许我的JFrame 调整大小以适应内容。

  • 不要调用setPreferredSize,而是覆盖JPanelgetPreferredSize

  • 也不要在JFrame 上调用setSize(..) 使用正确的LayoutManager,它会根据所有添加的组件大小进行调整,而不是在设置JFrame 可见之前简单地调用pack()

  • 最后但没有足够强调在SwingUtilities.invokeXXX block / Event Dispatch Thread 中对 Swing 组件的扭曲创建和操作@

这是我做的一个例子:

基本上是一个JPanel,它覆盖getPreferredSize,并有一个方法setPanelSize(int w,int h),它更改JPanel实例中的变量,为getPreferredSize返回新的Dimensions。之后,我在JFrame 上致电revalidate()pack() 以反映更改:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test {

    public Test() {
        initComponents();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test();
            }
        });
    }

    private void initComponents() {
        final JFrame frame = new JFrame();
        frame.setTitle("Test");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final MyPanel myPanel = new MyPanel();
        final JButton changeSizeButton = new JButton("Change size to 300x300");

        changeSizeButton.addActionListener(new ActionListener() {
            boolean resized = false;

            @Override
            public void actionPerformed(ActionEvent ae) {
                if (resized) {
                    myPanel.setPanelSize(200, 200);
                    resized = false;
                    changeSizeButton.setText("Change size to 300x300");
                } else {
                    myPanel.setPanelSize(300, 300);
                    resized = true;
                    changeSizeButton.setText("Change size to 200x200");
                }

                frame.revalidate();
                frame.pack();

            }
        });
        frame.add(myPanel);
        frame.add(changeSizeButton, BorderLayout.SOUTH);

        frame.pack();
        frame.setVisible(true);
    }
}

class MyPanel extends JPanel {

    private int width, height;

    public MyPanel() {
        super(true);
        width = 200;
        height = 200;
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(width, height);
    }

    public void setPanelSize(int width, int height) {
        this.width = width;
        this.height = height;
    }
}

【讨论】:

    【解决方案2】:

    您需要invalidate 容器层次结构使其重新布局组件。

    只需在您更改的组件上调用invalidate,然后调用revalidate

    这是一个小例子……

    public class TestComponentHierarcy {
    
        public static void main(String[] args) {
            new TestComponentHierarcy();
        }
    
        public TestComponentHierarcy() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException ex) {
                    } catch (InstantiationException ex) {
                    } catch (IllegalAccessException ex) {
                    } catch (UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Test");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new GridBagLayout());
                    frame.add(new Test());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class Test extends JPanel {
    
            private Dimension size = new Dimension(10, 10);
    
            public Test() {
    
                setLayout(new GridBagLayout());
                addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        size.width += 10;
                        size.height += 10;
                        invalidate();
                        revalidate();
                    }
                });
    
            }
    
            @Override
            public Dimension getPreferredSize() {
                return size;
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setColor(Color.RED);
                g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
            }
    
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      main() 方法中的somePanel.expand(); 之后添加frame.pack();。会搞定的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-03-15
        • 2021-11-06
        • 2012-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多