首页 文章

添加到BorderLayout.CENTER的面板不占用剩余空间

提问于
浏览
1

我目前正在学习用Java编程GUI,我遇到的问题是CENTER组件没有占用框架中的剩余空间 . 从我读到的内容看,BorderLayout将向北/南提供他们首选高度的组件并将其拉伸到边缘,而西/东将是相反的 . 然后中心组件将获得剩余的空间 . 我要做的是创建一个简单的窗口,在北部区域有一个面板,在中心区域有一个面板 . 我给每个人自己的背景颜色,这样我就可以很容易地看到他们给出的空间 . 但是,我得到了this,而不是让一个黄色顶栏的窗口和剩下的空间被洋红色面板占用 .

顶部面板只是一个常规的JPanel,但中间面板是一个扩展JPanel的类,它覆盖paintComponent并用颜色填充面板 . 如果我在fillRect()中的更大区域进行硬编码,它实际上会填满窗口 . 所以当我在方法中调用getHeight()和getWidth时,我怀疑发生了一些错误 . 值得一提的是,dawPanel总是会绘制一个完美的正方形,如果我将窗口调整为Y-aksis上更长的矩形,则会在底部出现间隙 .

所以我的问题是,如何将组件添加到Borderlayout.CENTER以占用frame.contentPane()中的所有剩余空间?

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

public class Oblig1 
{
    JFrame frame;
    JPanel infoPanel;
    DrawingPanel drawPanel;

    public static void main(String[] args) 
    {
        Oblig1 game = new Oblig1();
    }

    public Oblig1()
    {
        frame = new JFrame("Parachute Game");
        frame.setSize(860, 640);
        infoPanel = new JPanel();
        drawPanel = new DrawingPanel();

        infoPanel.setBackground(Color.yellow);
        infoPanel.setPreferredSize(new Dimension(840, 20));
        infoPanel.setLayout(new BoxLayout(infoPanel, BoxLayout.X_AXIS));

        drawPanel.setPreferredSize(new Dimension(840, 620));

        frame.getContentPane().add(infoPanel, BorderLayout.NORTH);
        frame.getContentPane().add(drawPanel, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//      frame.setResizable(false);
        frame.setVisible(true);
    }

    //This class represents the panel that paints all animated parts of the game
    public class DrawingPanel extends JPanel
    {
        public DrawingPanel()
        {
            setDoubleBuffered(true);
        }

        @Override
        protected void paintComponent(Graphics g)
        {
            Graphics2D g2d = (Graphics2D) g;
            g2d.setColor(Color.MAGENTA);

            g2d.fillRect(0, 0, drawPanel.getHeight(), drawPanel.getWidth());
        }
    }
}

1 回答

  • 3

    问题来自两个代码行(错过了一个代码行)

    • infoPanel.setPreferredSize(new Dimension(840, 20));

    • infoPanel.setLayout(new BoxLayout(infoPanel, BoxLayout.X_AXIS));

    • BoxLayout需要Min,Max和PreferredSize,否则错过Dimensions与另一个PreferredSize相撞,在这种情况下( infoPanel.setPreferredSize(new Dimension(840, 20)); )放置在使用BorderLayout的JFrame中

    • 删除 infoPanel.setPreferredSize(new Dimension(840, 20)); ,或其widht必须小于JPanel使用的PreferredSize

    默认情况下,在Swing中

    • 绘画永远不会将PreferredSize正确地返回到容器中,为了BoxLayout min,max和首选大小,你jave要覆盖getPreferredSize

    • 使用JFrame.pack()而不是将min,max和preferredSize直接调整为JComponents或容器,也不调整setSize for JFrame

    • 根本不是真的,看我的编辑 - > use another LayoutManager for JPanel to reduce funny issue with painting if is JFrame resized

    • 你的paintComponent错过了重要的代码行super.paintComponent(g);

    例如

    import java.awt.*;
    import javax.swing.*;
    
    public class Oblig1 {
    
        JFrame frame;
        JPanel infoPanel;
        DrawingPanel drawPanel;
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new Oblig1();
                }
            });
        }
    
        public Oblig1() {
            frame = new JFrame("Parachute Game");
            //frame.setSize(860, 640);
            infoPanel = new JPanel() {
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(20, 20);
                }
            };
            drawPanel = new DrawingPanel();
    
            infoPanel.setBackground(Color.yellow);
            //drawPanel.setPreferredSize(new Dimension(840, 20));
            infoPanel.setLayout(new BoxLayout(infoPanel, BoxLayout.X_AXIS));
            //drawPanel.setPreferredSize(new Dimension(840, 620));
            frame.getContentPane().add(infoPanel, BorderLayout.NORTH);
            frame.getContentPane().add(drawPanel, BorderLayout.CENTER);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //      frame.setResizable(false);
            frame.pack();
            frame.setVisible(true);
        }
    
        //This class represents the panel that paints all animated parts of the game
        public class DrawingPanel extends JPanel {
    
            private static final long serialVersionUID = 1L;
    
            public DrawingPanel() {
                setDoubleBuffered(true);
            }
    
            @Override
            public Dimension getMinimumSize() {
                return new Dimension(300, 300);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(300, 300);
            }
    
            @Override
            public Dimension getMaximumSize() {
                return new Dimension(300, 300);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                g2d.setColor(Color.MAGENTA);
                //g2d.fillRect(0, 0, getHeight(), getWidth());
                g2d.fillRect(0, 0, getWidth(), getHeight());
            }
        }
    }
    

    编辑

    在我看来,这很简单

    • use another LayoutManager for JPanel to reduce funny issue with painting if is JFrame resized

    • 有错误, HeightWidth 的反向参数,错误的代码行 g2d.fillRect(0, 0, getHeight(), getWidth()); 应为 g2d.fillRect(0, 0, getWidth(), getHeight());

相关问题