1

I'm not really used to Java and Swing, but I need an answer for a school project :)

I have a JButton that is stretched to it's parents width/height via 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); 

Now, I need to get the button's width. The reason: The Button's font-size is calculated relative to the button's size (for this calculation its width is needed.).

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

test.getWidth() is zero :( (this is called after pane, frame and Button were set visible).

What can I do :)

Thx in advance


UPDATE:

As suggested by Yohan Danvin, I used frame.pack(). But the behavior becomes a bit strange: As if the size-change would be animated (cfr. css-transitions - that's where I sometimes get similiar problems), it changes within about 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){}
}

The first and second output is "93", the 9 other ones "1600" (what would be correct). What happens in this time? Why changes the width?

Looking forward to anyone to enlighten me :)


UPDATE:

This way, it works, the correct width is calculated:

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;
        }
    }
}    

But of course it's a bit hacky to wait using Thread.sleep :) (and exspecially to wait till the value is bigger than 100... - this might only fit for this example and maybe even only for my screen resolution.)

Feel free to copy this class into your IDE and try it out :)


FINAL UPDATE:

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

==> waits for the window to maximize. perfect.

Problem solved :)

4

1 回答 1

3

问题是尚未计算按钮的大小。尝试调用:

frame.pack();

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

更新:
我认为您遇到此问题是因为您使用frame.setExtendedState(JFrame.MAXIMIZED_BOTH);,不幸的是,在开始时没有考虑到这一点(= by .pack())。
我认为您别无选择,只能等待窗口完全最大化才能获得正确的值。

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

于 2013-06-30T13:34:40.823 回答