微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 JPanel 大小是错误的?

如何解决为什么 JPanel 大小是错误的?

有扩展 JFrame 的类的构造函数

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

public class ChessFrame extends JFrame {
    public ChessFrame () {
        setSize(520,520);
        setResizable(false);
        setLocationRelativeto(null);
        setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new GridLayout(1,1));

        // Add components
        getContentPane().add(new Board());
        pack();
        setVisible(true);
    }
}

和扩展 JPanel 的类:

import javax.swing.*;

public class Board extends JPanel {
    public Board() {
        setSize(new Dimension(520,520));
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.fillRect(0,520,520);
    }

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

结果矩形小于 520x520。

enter image description here

黑色矩形的大小约为 496x510。还有更多:

  1. getWidth()getHegiht() 写在 Board 类中,返回 0 和 0(因此 JPanel 到 JFrame 的大小为 0x0)
  2. 如果我删除 pack(),框架的大小变为 496x510(黑色矩形大小)

其实是java官方教程的复制粘贴:https://docs.oracle.com/javase/tutorial/uiswing/painting/step2.html

我做错了什么还是与java有关?如果是第二个,为什么会发生这种情况? 任何帮助将不胜感激。

解决方法

enter image description here

此示例仅在框架(和面板)在屏幕上可见时才尝试确定面板大小。它返回代码中设置的确切大小(300 像素)。

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

public class ChessBoard extends JPanel {
    
    int size = 300;
    JLabel sizeLabel = new JLabel();

    ChessBoard() {
        setBackground(Color.CYAN);
        setLayout(new GridBagLayout());
        add(sizeLabel);
    }
    
    public void showSize() {
        sizeLabel.setText(String.format("%1sx%1s",getWidth(),getHeight()));
    }
    
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(size,size);
    }

    public static void main(String[] args) {
        Runnable r = () -> {
            ChessBoard cb = new ChessBoard();
            
            JFrame f = new JFrame(cb.getClass().getSimpleName());
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            f.setLocationByPlatform(true);
            
            f.setContentPane(cb);
            f.pack();
            f.setMinimumSize(f.getSize());
            
            f.setVisible(true);
            // delay showing size until app. is on-screen
            Runnable r1 = cb::showSize;
            SwingUtilities.invokeLater(r1);
        };
        SwingUtilities.invokeLater(r);
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。