添加到BorderLayout.CENTER的面板不占用剩余空间 [英] Panel added to BorderLayout.CENTER does not occupy remaining space
问题描述
我目前正在学习用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调整大小时绘画的有趣问题
有错误的Height
和Width
参数,错误的代码行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屋!