gpt4 book ai didi

java - JPanel 的子组件绘制/布局问题

转载 作者:搜寻专家 更新时间:2023-11-01 02:18:07 24 4
gpt4 key购买 nike

我遇到一个问题,当我的框架显示时(在登录对话框之后)按钮不在正确的位置,然后在几毫秒内它们会转到正确的位置(带边框布局的面板的中心)。

-- 更新

在我的机器上,这个 SSCCE 在我运行它的 10 次中有 2 次显示布局问题:

import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TEST {

public static void main(String[] args) throws Exception {

SwingUtilities.invokeAndWait(new Runnable() {

public void run() {

System.out.println("Debug test...");

JPanel btnPnl = new JPanel();
btnPnl.add(new JButton("TEST"));

JFrame f = new JFrame("TEST");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new BorderLayout());
f.getContentPane().add(btnPnl);
f.setPreferredSize(new Dimension(800, 600));
f.pack();
f.setExtendedState(JFrame.MAXIMIZED_BOTH);
f.setVisible(true);

System.out.println("End debug test!");

}
});

}

}

按钮首先出现在左上角,然后移到中间。是 Java 错误吗?

--更新

看起来 SSCCE 并没有为每个正在尝试的人显示问题。可能是我的电脑性能问题。我仍然认为 Java Swing 正在创建新线程以在幕后制作布局。但我不确定。

--更新

问题只发生在 f.setExtendedState(JFrame.MAXIMIZED_BOTH);

最佳答案

你的问题引起了我的兴趣。经过一番调查后,我想我确认了一些我记得的关于设置窗口状态(最大化、恢复等)的事情,即设置状态是对操作系统的请求,并且由操作系统随意处理请求。这意味着它是异步的,或者至少在您设置它之后才完成。我确认使用日志记录并添加调整大小监听器,您可以在代码块退出后看到框架已调整大小。正因为如此, pack() 会将组件布局到他们喜欢的大小。因此,想象一下框架的大小为 800x600,组件也是如此定位(按钮水平居中在 400 左右)。然后,操作系统将框架的大小更改为全屏(例如 1024x768)- 一会儿,您会看到按钮仍为 400。然后框架处理新的大小并重新布局组件并将按钮居中在 512 左右。所以你会看到闪烁,因为它在此过程中转换。也许一个解决方案是 NOT pack() - 它的大小将保持为零,用户将看到最小的闪烁。

首先尝试这个改变:

// pack()

如果这看起来不错,那么您可能会遇到下一个问题……如果用户单击恢复按钮,整个框架就会收缩成一个黑洞。因此,在帧由于最大化而可预测地调整大小后,请尝试调用 pack。像这样:

f.addComponentListener( new ComponentAdapter( ComponentEvent e ) {
public void componentResized( Component) {
if( f.getSize().getWidth() > 0 ) {
e.getComponent().removeComponentListener( this );
((JFrame)e.getComponent()).pack();
}
}
}

因此,如果用户稍后单击恢复按钮,框架将有一个很好的包装尺寸,可以使用。

--更新

好的,最后一次尝试。虽然我认为我对问题的描述有一定道理,但我提供的解决方案没有任何作用。这是最后一次尝试。删除 pack() 和 setPreferredSize() 并替换为将大小设置为屏幕大小。这似乎大大减少了我系统上的闪烁。这是因为初始布局和后面做的最大化布局应该没有区别。如果您在恢复和最大化之间切换,您可以看到这一点。虽然我在切换两者时仍然看到非常轻微的闪烁,但至少在第一次显示时看起来更好。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TEST {

public static void main(String[] args) throws Exception {

SwingUtilities.invokeAndWait(new Runnable() {

public void run() {

System.out.println("Debug test...");

JPanel btnPnl = new JPanel();
btnPnl.add(new JButton("TEST"));

JFrame f = new JFrame("TEST");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new BorderLayout());
f.getContentPane().add(btnPnl);
// f.setPreferredSize(new Dimension(800, 600));
// f.pack();
f.setSize( Toolkit.getDefaultToolkit().getScreenSize() );
f.setExtendedState(JFrame.MAXIMIZED_BOTH);
f.setVisible(true);

System.out.println("End debug test!");

}
});

-迈克

关于java - JPanel 的子组件绘制/布局问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2418956/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com