添加到BorderLayout.CENTER的面板不占用剩余空间 [英] Panel added to BorderLayout.CENTER does not occupy remaining space

查看:133
本文介绍了添加到BorderLayout.CENTER的面板不占用剩余空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在学习用Java编写GUI的程序,但我遇到一个问题,即CENTER组件没有占据框架中的剩余空间.根据我的阅读,BorderLayout将赋予北/南组件的首选高度,并将其拉伸到边缘,而西/东则相反.然后,中心组件将获得剩余的任何空间.我想做的是创建一个简单的窗口,在北部区域有一个面板,在中央区域有一个面板.我给他们每个人自己的背景色,这样我就可以很容易地看到它们所给的空间.但是,我得到的不是

I am currently learning to program GUI in Java, and I have a problem where the CENTER component does not occupy the remaining space in the frame. From what I've read BorderLayout will grant components in north/south their preferred height and the stretch it out to the edges, and west/east will be the opposite. The center component will then get whatever space is left. What I am trying to do is to create a simple window with a panel in the north region, and a panel in the center region. I give each their own background color so I can easily see the space they are given. However, instead of getting a window with a yellow top bar and the remaining space being occupied by the magenta panel, I get this.

顶部面板只是常规的JPanel,而中间面板是扩展JPanel的类,该类重写paintComponent并用一种颜色填充面板.如果我在fillRect()的较大区域中进行硬编码,它将实际填充窗口.因此,我怀疑在该方法中调用getHeight()和getWidth时发生了错误.值得一提的是,dawPanel始终会绘制一个完美的正方形,如果我将窗口的尺寸调整为在Y-aksis上更长的矩形,则间隙将显示在底部.

The top panel is just a regular JPanel, but the center panel is a class extending JPanel which overrides paintComponent and fills the panel with a color. If I hardcode in a bigger area in the fillRect() it will actually fill the window. So I suspect there's something wrong happening when I call getHeight() and getWidth in the method. It also might be worth mentioning that the dawPanel always will paint a perfect square, if I resize the window into a rectangle longer on the Y-aksis the gap will appear on the bottom instead.

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

So my question is, how can I get the component added to the Borderlayout.CENTER to occupy all remaining space in the 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());
        }
    }
}

推荐答案

问题来自两条代码行(和一条代码行遗漏了

issue came from two code lines (and one code line missed

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

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

  • BoxLayout必须为Min,Max和PreferredSize,否则会丢失尺寸与另一个PreferredSize发生冲突,在这种情况下(infoPanel.setPreferredSize(new Dimension(840, 20));)放置在使用BorderLayout的JFrame中

  • BoxLayout required Min, Max and PreferredSize, otherwise missed Dimensions collided with another PreferredSize, in this case (infoPanel.setPreferredSize(new Dimension(840, 20)); ) that is laid in JFrame that uses BorderLayout

删除infoPanel.setPreferredSize(new Dimension(840, 20));,否则其宽度必须小于用于JPanel的PreferredSize

remove infoPanel.setPreferredSize(new Dimension(840, 20));, or its widht must be less than PreferredSize used for JPanel

默认情况下,Swing中的绘画永远不会正确地将PreferredSize返回到容器,您想要覆盖getPreferredSize,以获得BoxLayout的最小,最大和首选大小

painting in Swing by default never returns PreferredSize correctly back to the container, you jave to override getPreferredSize, for BoxLayout min, max and preferred size

使用JFrame.pack()而不是将min,max和preferredSize的大小直接调整为JComponents或容器,也不为JFrame设置setSize

use JFrame.pack() instead of sizing for min,max and preferredSize directly to the JComponents or container, nor to setSize for JFrame

一点都不对,看我的编辑-> 如果JFrame调整了大小,请使用另一个LayoutManager for JPanel减少绘画时的有趣问题

not true at all, to see my EDIT --> use another LayoutManager for JPanel to reduce funny issue with painting if is JFrame resized

您的paintComponent缺少重要的代码行super.paintComponent(g);

your paintComponent missed important code line 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());
        }
    }
}


编辑


EDIT

我认为这是简单的错误

  • 使用JPanel的另一个LayoutManager来减少JFrame调整大小时绘画的有趣问题

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

there are wrong, reversed parameters for Height and Width, wrong code line g2d.fillRect(0, 0, getHeight(), getWidth()); should be g2d.fillRect(0, 0, getWidth(), getHeight());

这篇关于添加到BorderLayout.CENTER的面板不占用剩余空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆