组件的width属性的意外更改

时间:2012-07-19 12:52:31

标签: java swing

我注意到运行我在下面列出的程序有时会产生不良影响。

编辑:我简化了代码,使事情看起来很清晰。我正在绘制一个String,它打印出当前的组件大小。我已经覆盖了Component类中的getPrefferedSize()方法,并将宽度和高度分别设置为640 x 512。但是,运行程序后我仍然得到不同的结果:640 x 512和650 x 522.奇怪的是删除frame.setResizable(false)行修复了一些事情。但我希望窗口可以调整大小

import java.awt.*;

import javax.swing.*;

public class DrawTest
{
    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                DrawFrame frame = new DrawFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setResizable(false);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}


class DrawFrame extends JFrame
{

    private static final long serialVersionUID = 1L;
    public DrawFrame()
    {
        setTitle("DrawTest");
        setLocationByPlatform(true);
        Container contentPane = getContentPane();
        DrawComponent component = new DrawComponent();
        contentPane.add(component);
    }

}

class DrawComponent extends JComponent
{
    private static final long serialVersionUID = 1L;
    public Dimension getPreferredSize() {
        return new Dimension(640, 512);
    }

    public void paintComponent(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;         
        String msg = getWidth() + " x " + getHeight();      
        g2.setPaint(Color.BLUE);
        g2.drawString(msg, getWidth()/2, getHeight()/2);
    }
}

import java.awt.*; import javax.swing.*; public class DrawTest { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { DrawFrame frame = new DrawFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(false); frame.pack(); frame.setVisible(true); } }); } } class DrawFrame extends JFrame { private static final long serialVersionUID = 1L; public DrawFrame() { setTitle("DrawTest"); setLocationByPlatform(true); Container contentPane = getContentPane(); DrawComponent component = new DrawComponent(); contentPane.add(component); } } class DrawComponent extends JComponent { private static final long serialVersionUID = 1L; public Dimension getPreferredSize() { return new Dimension(640, 512); } public void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; String msg = getWidth() + " x " + getHeight(); g2.setPaint(Color.BLUE); g2.drawString(msg, getWidth()/2, getHeight()/2); } }

2 个答案:

答案 0 :(得分:3)

setLocationByPlatform()的调用必须遵循pack()并在setVisible()之前,否则几何图形将出错。如果没有理由继承JFrame,我已经省略DrawFrame就是下面的例子。请注意,使用FontMetrics可以在调整封闭容器大小时保持文本居中。这种方法对于学习布局很方便。

enter image description here

import java.awt.*;
import javax.swing.*;

public class DrawTest {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("DrawTest");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new DrawComponent());
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);
            }
        });
    }
}

class DrawComponent extends JComponent {

    private static final long serialVersionUID = 1L;

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(320, 240);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        String msg = getWidth() + " x " + getHeight();
        g2.setPaint(Color.BLUE);
        int w = (getWidth() - g.getFontMetrics().stringWidth(msg)) / 2;
        g2.drawString(msg, w, getHeight() / 2);
    }
}

答案 1 :(得分:3)

可能因为本机窗口系统可能会忽略设置帧大小等请求。
setSize()方法有类似的问题:

http://docs.oracle.com/javase/7/docs/api/java/awt/Window.html#setSize%28java.awt.Dimension%29

  

“该方法会更改与几何相关的数据。因此,本机   窗口系统可能会忽略此类请求,或者它可能会修改   请求的数据,以便以某种方式放置和调整Window对象的大小   这与桌面设置密切相关。“

简单测试,试试:

public Dimension getPreferredSize() {
    return new Dimension(2000, 1000);
}

类似的设置可能会被忽略。

还请查看此主题:setSize() doesn't work for JFrame