我正在使用XFCE 4桌面在Debian 8上编译和运行以下代码。
import javax.swing.JFrame;
import javax.swing.JComponent;
import java.awt.EventQueue;
import java.awt.Dimension;
import java.awt.Graphics;
public class FrameDemo
{
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.setLocationByPlatform(true);
frame.add(new HelloWorldComponent());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
class HelloWorldComponent extends JComponent
{
public void paintComponent(Graphics g)
{
g.drawString("hello, world", 50, 50);
}
public Dimension getPreferredSize()
{
return new Dimension(200, 100);
}
}
这会产生所需的输出。框架以桌面为中心。
但是当我在frame.pack()
语句之后移动frame.setVisible(true)
语句时,即在显示帧后我打包,我再也看不到所需的输出。
JFrame frame = new JFrame();
frame.setLocationByPlatform(true);
frame.add(new HelloWorldComponent());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.pack();
框架现在显示在桌面的左上角。
实际上,框架确实会在短时间内出现在桌面的中央,只需几分之一秒。大约一秒钟后,框架移动到桌面的左上角。
为什么移动frame.pack()
语句的位置会更改框架在桌面上显示的位置?
答案 0 :(得分:3)
pack()
拨打setClientSize()
来调用setBounds(x,y,w,h)
无论哪种方式,在我的电脑上,它似乎总是显示在左上角。
以下是JavaDoc about Window#setLocationByPlatform
调用后调用setVisible,setLocation和setBounds setLocationByPlatform清除Window的这个属性。例如, 执行以下代码后:
setLocationByPlatform(真);调用setVisible(真);布尔标志= isLocationByPlatform();窗口将显示在平台上 默认位置和标志将为false。在以下示例中:
setLocationByPlatform(真); setLocation(10,10);布尔标志= isLocationByPlatform();调用setVisible(真);将显示该窗口 在(10,10)和旗帜将是假的。
如果您希望将窗口置于中心位置,则使用JFrame#setLocationRelativeTo(null)
(将null
作为参数设置非常重要。)
如果组件为null,或者与GraphicsConfiguration关联 此组件为null,窗口位于中心 屏幕。
答案 1 :(得分:2)
pack()最终调用setBounds()。根据Window的javadoc,
调用后调用setVisible,setLocation和setBounds setLocationByPlatform清除Window的这个属性。
因此窗口重新定位到平台的默认定位。
答案 2 :(得分:1)
这是因为pack()
计算窗口的大小,这是正确执行居中计算所需的。设置可见后,对pack()
的调用不会更改窗口位置(但会计算大小)。