GridbagLayout - 当c.fill = BOTH时获取ButtonSize

时间:2013-06-30 13:28:03

标签: java swing jbutton gridbaglayout

我不习惯Java和Swing,但我需要一个学校项目的答案:)

我有一个JButton,通过GirdbagLayout拉伸到它的父亲宽度/高度:

frame = new JFrame();
frame.setResizable(false);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setUndecorated(true);

Container contentPane = frame.getContentPane();
contentPane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
contentPane.setVisible(true);

JButton test = new JButton("TEST");
c.gridx = 0; c.gridy = 0; c.ipadx = 30; c.ipady = 30; c.weightx = 1; c.weighty = 1; c.fill = GridBagConstraints.BOTH;
test.setVisible(true);
contentPane.add(test, c);

frame.setVisible(true); 

现在,我需要获得按钮的宽度。原因是:Button的字体大小是相对于按钮大小计算的(对于此计算,需要宽度。)

System.out.println("BUTTON WIDTH "+test.getWidth());

test.getWidth()为零:( (在窗格,框架和按钮设置为可见之后调用此方法。)

我该怎么办:)。

提前谢谢


更新

正如Yohan Danvin所说,我使用了frame.pack()。 但是这种行为变得有点奇怪:好像大小变化会被动画化(cfr.css-transitions - 这就是我有时会遇到类似问题的地方),它会在大约30ms内发生变化:

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

System.out.println(test.getWidth());
for(int i=0; i<10; i++){
    try{
        Thread.sleep(10);
        System.out.println(test.getWidth());
    } catch(Exception err){}
}

第一个和第二个输出是“93”,其他9个输出是“1600”(这是正确的)。 这次会发生什么?为什么要改变宽度?

期待任何人启发我:)


更新

这样,它可以正常计算宽度:

import javax.swing.*;
import java.awt.*;

public class VIEW{
    private JFrame frame;

    public VIEW(){
        frame = new JFrame();
        frame.setResizable(false);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setUndecorated(true);

        Container contentPane = frame.getContentPane();
        contentPane.setLayout(new GridBagLayout());
        contentPane.setVisible(true);
        GridBagConstraints c = new GridBagConstraints();

        JButton test = new JButton("TEST");
        c.gridx = 0; c.gridy = 0; c.ipadx = 30; c.ipady = 30; c.weightx = 1; c.weighty     = 1; c.fill = GridBagConstraints.BOTH;
        test.setVisible(true);
        contentPane.add(test, c);

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

        System.out.println(this.getWidth(test));
    }

    private int getWidth(JButton button){
        try{
            int i = 0, width = 0;
            while(i++ < 10 && (width = button.getWidth()) < 100) 
                Thread.sleep(10);
            return width;
        } catch(Exception err){
            return 0;
        }
    }
}    

但是当然等待使用Thread.sleep :)有点hacky(特别是等到值大于100 ... - 这可能只适用于这个例子,甚至可能只适用于我的屏幕分辨率。 )

随意将此类复制到您的IDE中并尝试一下:)


最终更新:

SwingUtilities.invokeLater(new Runnable(){
    public void run(){
        System.out.println(test.getWidth());
    }
});

==&GT;等待窗口最大化。完美。

问题解决了:))

1 个答案:

答案 0 :(得分:3)

问题是按钮的大小尚未计算。 试着打电话:

frame.pack();

在使框架可见之前,然后获得宽度。

更新:
我认为您收到此问题是因为您使用的是frame.setExtendedState(JFrame.MAXIMIZED_BOTH);,遗憾的是开头时没有将其考虑在内(= .pack())。 我认为你别无选择,只能等到窗口完全最大化才能获得正确的价值。

使用SwingUtilities.invokeLater(/*get the width here*/);代替自定义线程休眠。这是在所有操作系统事件(包括我正在考虑的窗口最大化)之后运行代码的更标准方法。