【问题标题】:Adding JPanels to regions other than CENTER将 JPanel 添加到 CENTER 以外的区域
【发布时间】:2016-11-27 18:13:17
【问题描述】:

我目前正在阅读 Head First Java 关于制作 GUI 的第 12 章。他们刚刚提到 JFrame 分为中心、北部、南部、东部和西部。然后本书使用 2 参数 add() 方法将指定组件添加到具有该 JFrame 的指定区域。

我可以为五个区域中的每一个区域添加一个 JButton。我还可以将我自己的 JPanel 添加到中心区域,周围有 JButtons。但是当我尝试将 JPanel 添加到除中心以外的任何区域时,JPanel 不会出现。

在过去的一个小时里,我真的在整个网络和 Stack Overflow 上进行了搜索,但我没有遇到任何提到将 JPanel 添加到 JFrame 中心以外的任何区域的内容。所以我的问题是:是否可以将 JPanel 添加到 JFrame 的北部、南部、东部或西部区域?

提前感谢任何可以帮助我的人。

这是我一直试图在北部地区使用我的 JPanel 运行的代码:

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.BorderLayout;

public class StackQ {

    JFrame frame;

    public static void main(String [] args) {

        StackQ gui = new StackQ();
        gui.go();

    }

    public void go() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JButton button = new JButton("location test");
        JButton button2 = new JButton("location test");
        JButton button3 = new JButton("location test");
        JButton button4 = new JButton("location test");

        myDrawPanel custom = new myDrawPanel();

        frame.getContentPane().add(button, BorderLayout.CENTER);
        frame.getContentPane().add(button2, BorderLayout.EAST);
        frame.getContentPane().add(button3, BorderLayout.WEST);
        frame.getContentPane().add(button4, BorderLayout.SOUTH);

        frame.getContentPane().add(custom, BorderLayout.NORTH);

        frame.setSize(300,300);
        frame.setVisible(true);
    }

}

class myDrawPanel extends JPanel {

    public void paintComponent(Graphics g) {

        int red = (int) (Math.random() * 255);
        int green = (int) (Math.random() * 255);
        int blue = (int) (Math.random() * 255);

        Color random = new Color(red, green, blue);
        g.setColor(random);
        g.fillOval(20,20,100,100);

    }
}

【问题讨论】:

标签: java user-interface jframe jpanel


【解决方案1】:

这可能更清楚,但这在BorderLayout 文档中有所描述:

组件根据其首选大小和容器大小的约束进行布局......CENTER 组件可以水平和垂直拉伸以填充剩余的任何空间。

换句话说,CENTER 组件将被拉伸(如果需要)以填充应用程序,并且任何其他组件都需要指定 preferred-size 才能从 CENTER 中获取一些内容。

JButton 默认情况下根据按钮的内容指定首选大小。另一方面,JPanel 没有 - 它的首选大小取决于其内容,而您的 JPanel 没有任何内容,因此它的首选大小为零。

简而言之,为您的JPanel 指定首选大小,BorderLayout 将尝试为面板分配至少那么多空间。

【讨论】:

  • “将尝试分配”:解决方案就这么多
  • @gpasch 是的;如果JFrame 不够宽/不够高,无法容纳每个组件的首选尺寸,就必须给出一些东西。这就是为什么它是 preferred 尺寸的原因。只要BorderLayout 组件本身足够大以容纳它的所有组件,就会尊重首选尺寸。
  • @dimo414,非常感谢您的回复。我首先尝试在 JPanel 上使用 setSize() 方法,但它仍然不会出现在 Frame 中。然后我在有问题的 JPanel 上尝试了 setPreferredSize() 方法,它出现在框架的北部区域!任何想法为什么 setSize() 方法不起作用?另外,当您说“您的 JPanel 没有任何内容”时,我用颜色填充的椭圆形是否不算作 JPanel 中的内容?再次感谢!
  • 简而言之,首选尺寸就是布局管理器在确定如何布局组件时使用的大小。这肯定有点令人困惑,但this answer 更详细。
  • 至于你的 JPanel 的内容 no,Swing 不知道你在面板中画的是什么,也不知道它占用了多少空间。您仍然必须配置您希望面板的布局方式以及它应该有多大。 JPanel 的内容是任何Component 对象add to the panel,面板的布局管理器根据其内容的首选大小计算自己的首选大小。如果它没有内容,则其默认首选大小为零。
【解决方案2】:

为了这篇文章的任何潜在的未来查看者,为了获得所需的结果,我首先在我的 StackQ 类的最顶部导入了 Dimension 类(这是必需的,因为 setPreferredSize() 方法稍后在 go( ) 方法接受 Dimension 类型的参数):

import java.awt.Dimension;

然后我在 myDrawPanel 类实例化后立即将此代码添加到 go() 方法中:

Dimension dims = new Dimension(1366, 200);
custom.setPreferredSize(dims);

我选择了 1366 作为宽度,因为我的屏幕就是这么大。

感谢大家的帮助!

【讨论】:

  • 尝试让宽度为零;因为它是“首选”尺寸,所以布局管理器只会使用它需要的值。正如文档中提到的那样,“NORTHSOUTH 组件可能会水平拉伸”,如果 CENTER 组件比它们需要的宽。对于 NORTHSOUTH 来说,重要的是高度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-18
  • 2013-08-08
相关资源
最近更新 更多