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

时间:2014-08-26 11:24:36

标签: java swing user-interface layout-manager border-layout

我目前正在学习使用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 个答案:

答案 0 :(得分: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正确地返回到容器,您需要重写getPreferredSize,对于BoxLayout min,max和首选大小

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

  • 根本不是真的,看我的编辑 - > 如果JFrame调整大小,则使用JPAnel的另一个LayoutManager来减少绘画的滑稽问题

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

e.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());
        }
    }
}

修改

对我来说,这很简单

  • 如果JFrame调整大小,则使用JPAnel的另一个LayoutManager来减少绘画的滑稽问题

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