如何更改 JFrame 中 JPanel 的大小?
Posted
技术标签:
【中文标题】如何更改 JFrame 中 JPanel 的大小?【英文标题】:How can I change the size of JPanels in a JFrame? 【发布时间】:2021-12-23 08:52:54 【问题描述】:我有一个 JFrame,目前包含 4 个面板。其中一个面板是键盘,其他 3 个框架是键盘的控制面板,如下图所示:
我一直在尝试找到一种方法来使用 GridLayout 缩小控制面板的宽度,以便它们不会占用框架的整个宽度,但不幸的是我的代码无法正常工作。另外,我想将钢琴卷推到屏幕底部。到目前为止,这是我的代码:
JFrame frame = new JFrame();
JPanel container = new JPanel();
container.setSize(1000, 1000);
container.setLayout(new GridLayout(5,5));
// add control panels to JPanel
int y = 0;
for(int i =0; i < oscillators.length; ++i)
JPanel panel = new JPanel();
panel.setSize(289, 100);
panel.setBorder(Utils.WindowDesign.LINE_BORDER);
panel.setLayout(null);
container.add(oscillators[i]);
y+=105;
// add keyboard to panel
keyboard = new PianoKeys(this);
keyboard.setFocusable(true);
container.add(keyboard);
// make frame visible
frame.setSize(1000, 1000);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setBackground(Color.WHITE);
frame.setLayout(new BorderLayout());
frame.add(container);
frame.setVisible(true);
有人可以向我解释为什么这不能按预期工作吗?我将控制面板的宽度设置为 289,并且我的网格包含 5 列和 5 行,所以我不确定为什么控制面板最终会扩展到整个宽度。感谢您提供的任何帮助!
【问题讨论】:
1) 以最小尺寸提供 ASCII 艺术或 GUI 的 预期 布局的简单绘图,如果给定更大的宽度和高度。 2) Edit 添加一个 minimal reproducible example 以表示您对 GUI 进行布局的最佳尝试。 一般提示:1) 不要使用null
布局。 2) 避免调用setXXXSize
方法(其中XXX
可能代表各种事物,如无或Minimum
或Preferred
)。布局管理器仅将它们作为建议,但更重要的是,GUI 中的组件和容器通常能够更好地自行确定这些尺寸。然后,当所有组件和容器都添加完毕后.. 3) 将 frame.setSize(1000, 1000);
替换为 frame.pack();
- 以获得正确的 GUI 大小。
差点忘了:GridLayout
通常不用作主 GUI 的主布局。我怀疑它的使用是这种情况下问题的核心,但在知道预期的布局之前无法推测更多。
【参考方案1】:
SetPreferredSize
通常用于布局协商。但是,在您的情况下,SetMaxSize
在面板上。
通常不要使用空布局。
JFrame 的默认布局管理器是 BorderLayout。这会将内容放大到 JFrame 的内容窗格。
我不确定 GridLayout 是否是您想要的。 GridBagLayout 还允许网格单元格合并。有些布局允许您将元素锚定到底部。在 GridBagLayout 中,可以使用 constraint 将小于单元格的组件与 SOUTH(底部)对齐。那将是一个差距。
一句话:
我赞成另一种编码风格,即拥有一个内部带有组件的 MyJFrame 类。并做:
public static void main(String[] args)
MyJFrame frame = new MyJFrame();
SwingUtilities.invokeLater(() -> frame.setVisible());
这允许使用 GUI 设计器(=代码生成器),这可以节省大量实验,即使对于经验丰富的程序员也是如此。
【讨论】:
【参考方案2】:有趣的问题。因此,我做了一些研究。
解决一个思路:从GridLayout切换到BoxLayout
引用文档:
“BoxLayout 类将组件放在单个行或列中。它尊重组件请求的最大尺寸,还允许您对齐组件。有关更多详细信息,请参阅如何使用 BoxLayout。” A Visual Guide to Layout Managers
简短示例:
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class GridLayoutExample extends JFrame
GridLayoutExample()
JPanel listPane = new JPanel();
//listPane.setLayout(new GridLayout(5,0));
listPane.setLayout(new BoxLayout(listPane, BoxLayout.PAGE_AXIS));
this.add(listPane);
for(int i = 0; i < 5; i++)
JLabel imgLabel = new JLabel(generateImage(20 + 20 * i, 10 + 10 * i));
listPane.add(imgLabel);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
public static void main(String[] args)
new GridLayoutExample();
private static ImageIcon generateImage(int width, int height)
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
//create random image pixel by pixel
for(int y = 0; y < height; y++)
for(int x = 0; x < width; x++)
int a = (int)(Math.random()*256); //alpha
int r = (int)(Math.random()*256); //red
int g = (int)(Math.random()*256); //green
int b = (int)(Math.random()*256); //blue
int p = (a<<24) | (r<<16) | (g<<8) | b; //pixel
img.setRGB(x, y, p);
return new ImageIcon(img);
您可以通过更改以下几行来比较 GridLayout 和 BoxLayout:
//listPane.setLayout(new GridLayout(5,0));
listPane.setLayout(new BoxLayout(listPane, BoxLayout.PAGE_AXIS));
显示差异 - GridLayout:
框布局:
我希望这会有所帮助。
随机图片生成致dyclas-s-room.com
【讨论】:
以上是关于如何更改 JFrame 中 JPanel 的大小?的主要内容,如果未能解决你的问题,请参考以下文章