GridbagLayout -当c时,得到ButtonSize。填补=两

时间:2023-01-28 18:08:22

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

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

I have a JButton that is stretched to it's parents width/height via GirdbagLayout:

我有一个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); 

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).

test.getWidth()为零:(这是在窗格、框架和按钮被设置为可见后调用的)。

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:

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

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?

第一个和第二个输出是“93”,另外9个是“1600”(正确的)。这段时间发生了什么?为什么改变宽度?

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.)

当然,使用线程是有点不方便的。睡眠:)(尤其要等到价值大于100……-这可能只适合这个例子,甚至可能只适合我的屏幕分辨率。

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

请随意将这个类复制到您的IDE中并尝试:)


FINAL UPDATE:

最后更新:

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

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

==>等待窗口最大化。完美的。

Problem solved :)

问题解决:)

1 个解决方案

#1


3  

The problem is the size for the button has not been computed yet. Try calling:

问题是按钮的大小还没有计算出来。试着调用:

frame.pack();

before making the frame visible, then get the width.

在使框架可见之前,先得到宽度。

UPDATE:
I think you're getting this issue because you use frame.setExtendedState(JFrame.MAXIMIZED_BOTH);, which unfortunately is not taken into consideration at the beginning (= by .pack()).
I think you have no choice than to wait for the window to be fully maximized before you can get the right value.

更新:我认为您之所以会遇到这个问题,是因为您使用了frame.setExtendedState(JFrame.MAXIMIZED_BOTH);不幸的是,在开始时没有考虑到这个问题。我认为你别无选择,只能等待窗口完全最大化,然后才能得到正确的值。

Use SwingUtilities.invokeLater(/*get the width here*/); instead of your custom thread sleeps. This is a more standard way to have code run after all OS events (including the maximization of the window I'm thinking) have been taken care of.

使用SwingUtilities。invokeLater(/ *宽* /);而不是您的自定义线程休眠。这是在所有OS事件(包括我正在考虑的窗口的最大化)之后进行代码运行的一种更标准的方法。

#1


3  

The problem is the size for the button has not been computed yet. Try calling:

问题是按钮的大小还没有计算出来。试着调用:

frame.pack();

before making the frame visible, then get the width.

在使框架可见之前,先得到宽度。

UPDATE:
I think you're getting this issue because you use frame.setExtendedState(JFrame.MAXIMIZED_BOTH);, which unfortunately is not taken into consideration at the beginning (= by .pack()).
I think you have no choice than to wait for the window to be fully maximized before you can get the right value.

更新:我认为您之所以会遇到这个问题,是因为您使用了frame.setExtendedState(JFrame.MAXIMIZED_BOTH);不幸的是,在开始时没有考虑到这个问题。我认为你别无选择,只能等待窗口完全最大化,然后才能得到正确的值。

Use SwingUtilities.invokeLater(/*get the width here*/); instead of your custom thread sleeps. This is a more standard way to have code run after all OS events (including the maximization of the window I'm thinking) have been taken care of.

使用SwingUtilities。invokeLater(/ *宽* /);而不是您的自定义线程休眠。这是在所有OS事件(包括我正在考虑的窗口的最大化)之后进行代码运行的一种更标准的方法。