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事件(包括我正在考虑的窗口的最大化)之后进行代码运行的一种更标准的方法。