设置 GridBagLayout 网格的大小
Setting GridBagLayout grid's size
我正在尝试使用 Java Swing (GridBagLayout) 创建控制台。
我不知道为什么,但正如您在左边距看到的那样,网格的大小不正确。
应该这样显示:
浅蓝色是列表,绿色是图像,橙色是文本面板,黄色是文本字段。
不知道怎么把列表变大,图片变小。同样,文本字段的网格绑定到列表 1,即使列表在 y 1 上而文本字段在 y 2 上也是如此。
这是一些代码。
// Command List
DefaultListModel<String> listInput = new DefaultListModel<String>();
JList<String> list = new JList<String>(listInput);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane scrollPane = new JScrollPane(list);
list.setBackground(new Color(160, 160, 160));
list.setSelectionBackground(new Color(150, 150, 150));
scrollPane.setPreferredSize(new Dimension(20, 20));
manager.setCommandList(listInput);
c.insets = new Insets(2, 2, 2, 2);
c.ipady = 0;
c.ipadx = 100;
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 1;
c.gridheight = 2;
c.weightx = 0.1;
c.weighty = 0.6;
c.fill = GridBagConstraints.BOTH;
console.add(scrollPane, c);
// Image Displayer
JLabel image = new JLabel(new ImageIcon());
manager.setImageField(image);
c.insets = new Insets(0, 0, 0, 0);
c.ipady = 0;
c.ipadx = 0;
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 0.1;
c.weighty = 0.3;
c.fill = GridBagConstraints.BOTH;
console.add(image, c);
其中 'c' 是网格包约束和控制台主 JPanel。
如您所见,列表的网格高度为 2,权重为 0.6,图像的网格高度为 1,权重为 0.9,所以不确定为什么列表比图像小 4 倍。
另一个问题,我已经向保存图像(调整大小)的 JLabel 添加了一个侦听器,无论如何,它没有被调用。我应该将监听器添加到主面板吗?因为图像仅由布局管理器调整大小。
谢谢^^
编辑:
SSCCE:
package co.relieved.jelly.application.display.swing;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.ListSelectionModel;
@SuppressWarnings("serial")
public class Test extends JPanel {
static JLabel image;
public static void main(String[] args) {
display();
try {
BufferedImage buffer = ImageIO
.read(new File("/home/juanco/Pictures/Screenshot from 2016-02-08 22-43-22.png"));
image.setIcon(new ImageIcon(
buffer.getScaledInstance(image.getWidth(), image.getHeight(), BufferedImage.SCALE_SMOOTH)));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public Test() {
super(new GridLayout(1, 1));
JTabbedPane tabs = new JTabbedPane();
/*** >>> Console Pane <<< ***/
JPanel console = new JPanel();
console.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.ipadx = 0;
c.ipady = 0;
c.gridwidth = 1;
c.anchor = GridBagConstraints.CENTER;
c.fill = GridBagConstraints.BOTH;
// Console Screen
JTextPane screen = new JTextPane();
screen.setEditable(false);
c.gridx = 1;
c.gridy = 0;
c.gridheight = 2;
c.weightx = 0.8;
c.weighty = 1;
console.add(screen, c);
// Console Input
JTextField input = new JTextField();
c.insets = new Insets(2, 0, 2, 0);
c.ipady = 3;
c.gridy = 2;
c.gridheight = 1;
c.weighty = 0;
c.fill = GridBagConstraints.HORIZONTAL;
console.add(input, c);
// Command List
DefaultListModel<String> listInput = new DefaultListModel<String>();
listInput.setSize(1);
JList<String> list = new JList<String>(listInput);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane scrollPane = new JScrollPane(list);
c.insets = new Insets(2, 2, 2, 2);
c.ipady = 0;
c.ipadx = 100;
c.gridx = 0;
c.gridy = 1;
c.gridheight = 2;
c.weightx = 0.1;
c.weighty = 0.6;
c.fill = GridBagConstraints.BOTH;
console.add(scrollPane, c);
// Image Displayer
image = new JLabel(new ImageIcon());
c.insets = new Insets(0, 0, 0, 0);
c.ipadx = 0;
c.gridy = 0;
c.gridheight = 1;
c.weighty = 0.3;
console.add(image, c);
// General
tabs.addTab("Console", console);
/*** >>> Logs Pane <<< ***/
JPanel logs = new JPanel();
tabs.addTab("Logs", logs);
// Setup
tabs.setSelectedIndex(0);
add(tabs);
}
static void display() {
JFrame frame = new JFrame("Relieved Console");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(800, 500));
frame.add(new Test(), BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
在我看来,您还需要为文本字段指定 gridwidth
and/or gridheight
。
GridBagLayout 就像美化了的 GridLayout。它将尝试将所有组件与其周围最近的网格空间对齐。 Oracle's Tutorials 也描述了这种行为。
很多时候,使用 GridBagLayout 布局组件的问题来自添加到布局的其他组件,而不是明显的问题子组件。
Here's some code.
这没有帮助。网格只能用完整的代码来完成。也就是说,我们需要知道所有组件的网格宽度和网格高度,以便确定 space 分配给网格中的每个组件。
the text field's grid is binded to the list one, even tough the list is on y 1 and the text field on y 2.
您不能随意将组件分配给网格。如果组件上方的组件的网格高度为 2,则该组件只会转到网格 2。因此基本上您的每一列都需要具有总网格高度为 3 的组件。
I don't know how to make the list bigger
将首选大小设置为 (20, 20) 没有帮助。无论如何,您不应该使用 setPreferredSize() 方法。
您应该使用:
list.setVisibleRowCount(...);
指定可见行。然后 JList 可以确定自己的首选大小。
另一个布局选项是使用可以简化布局的嵌套面板。
因此您可以从使用 BorderLayout 的 "west" 面板开始。然后将标签添加到 "PAGE_START",将列表添加到 "CENTER"。
然后创建一个 "center" 面板。将主要组件添加到 "CENTER",将文本字段添加到 "PAGE_START"。
然后将两个面板添加到框架中:
frame.add(westPanel, BorderLayout.LINE_START);
frame.add(centerPanel, BorderLayout.CENTER);
编辑:
抱歉,我收回关于让每列的网格高度为 3 的评论。您不能只将总网格高度指定为 3,因为每列中只有 2 个组件,因此每个组件只能高度为 1。
查看我在这篇文章中的回答:Why does this GridBagLayout not appear as planned? 一个允许您通过在 row/column.
中使用不可见组件来操纵 gridHeight/Weight 的 hack
但是,我不推荐这种方法。使用 BorderLayout(或嵌套面板上的其他布局管理器)使用我的嵌套面板建议会容易得多。
我修复了将 "console" JPanel 一分为二的问题,左边是边框布局面板,右边是网格包布局面板。正如@camickr 建议的那样
我正在尝试使用 Java Swing (GridBagLayout) 创建控制台。
我不知道为什么,但正如您在左边距看到的那样,网格的大小不正确。
应该这样显示:
浅蓝色是列表,绿色是图像,橙色是文本面板,黄色是文本字段。
不知道怎么把列表变大,图片变小。同样,文本字段的网格绑定到列表 1,即使列表在 y 1 上而文本字段在 y 2 上也是如此。
这是一些代码。
// Command List
DefaultListModel<String> listInput = new DefaultListModel<String>();
JList<String> list = new JList<String>(listInput);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane scrollPane = new JScrollPane(list);
list.setBackground(new Color(160, 160, 160));
list.setSelectionBackground(new Color(150, 150, 150));
scrollPane.setPreferredSize(new Dimension(20, 20));
manager.setCommandList(listInput);
c.insets = new Insets(2, 2, 2, 2);
c.ipady = 0;
c.ipadx = 100;
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 1;
c.gridheight = 2;
c.weightx = 0.1;
c.weighty = 0.6;
c.fill = GridBagConstraints.BOTH;
console.add(scrollPane, c);
// Image Displayer
JLabel image = new JLabel(new ImageIcon());
manager.setImageField(image);
c.insets = new Insets(0, 0, 0, 0);
c.ipady = 0;
c.ipadx = 0;
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 0.1;
c.weighty = 0.3;
c.fill = GridBagConstraints.BOTH;
console.add(image, c);
其中 'c' 是网格包约束和控制台主 JPanel。 如您所见,列表的网格高度为 2,权重为 0.6,图像的网格高度为 1,权重为 0.9,所以不确定为什么列表比图像小 4 倍。
另一个问题,我已经向保存图像(调整大小)的 JLabel 添加了一个侦听器,无论如何,它没有被调用。我应该将监听器添加到主面板吗?因为图像仅由布局管理器调整大小。
谢谢^^
编辑: SSCCE:
package co.relieved.jelly.application.display.swing;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.ListSelectionModel;
@SuppressWarnings("serial")
public class Test extends JPanel {
static JLabel image;
public static void main(String[] args) {
display();
try {
BufferedImage buffer = ImageIO
.read(new File("/home/juanco/Pictures/Screenshot from 2016-02-08 22-43-22.png"));
image.setIcon(new ImageIcon(
buffer.getScaledInstance(image.getWidth(), image.getHeight(), BufferedImage.SCALE_SMOOTH)));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public Test() {
super(new GridLayout(1, 1));
JTabbedPane tabs = new JTabbedPane();
/*** >>> Console Pane <<< ***/
JPanel console = new JPanel();
console.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.ipadx = 0;
c.ipady = 0;
c.gridwidth = 1;
c.anchor = GridBagConstraints.CENTER;
c.fill = GridBagConstraints.BOTH;
// Console Screen
JTextPane screen = new JTextPane();
screen.setEditable(false);
c.gridx = 1;
c.gridy = 0;
c.gridheight = 2;
c.weightx = 0.8;
c.weighty = 1;
console.add(screen, c);
// Console Input
JTextField input = new JTextField();
c.insets = new Insets(2, 0, 2, 0);
c.ipady = 3;
c.gridy = 2;
c.gridheight = 1;
c.weighty = 0;
c.fill = GridBagConstraints.HORIZONTAL;
console.add(input, c);
// Command List
DefaultListModel<String> listInput = new DefaultListModel<String>();
listInput.setSize(1);
JList<String> list = new JList<String>(listInput);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane scrollPane = new JScrollPane(list);
c.insets = new Insets(2, 2, 2, 2);
c.ipady = 0;
c.ipadx = 100;
c.gridx = 0;
c.gridy = 1;
c.gridheight = 2;
c.weightx = 0.1;
c.weighty = 0.6;
c.fill = GridBagConstraints.BOTH;
console.add(scrollPane, c);
// Image Displayer
image = new JLabel(new ImageIcon());
c.insets = new Insets(0, 0, 0, 0);
c.ipadx = 0;
c.gridy = 0;
c.gridheight = 1;
c.weighty = 0.3;
console.add(image, c);
// General
tabs.addTab("Console", console);
/*** >>> Logs Pane <<< ***/
JPanel logs = new JPanel();
tabs.addTab("Logs", logs);
// Setup
tabs.setSelectedIndex(0);
add(tabs);
}
static void display() {
JFrame frame = new JFrame("Relieved Console");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(800, 500));
frame.add(new Test(), BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
在我看来,您还需要为文本字段指定 gridwidth
and/or gridheight
。
GridBagLayout 就像美化了的 GridLayout。它将尝试将所有组件与其周围最近的网格空间对齐。 Oracle's Tutorials 也描述了这种行为。
很多时候,使用 GridBagLayout 布局组件的问题来自添加到布局的其他组件,而不是明显的问题子组件。
Here's some code.
这没有帮助。网格只能用完整的代码来完成。也就是说,我们需要知道所有组件的网格宽度和网格高度,以便确定 space 分配给网格中的每个组件。
the text field's grid is binded to the list one, even tough the list is on y 1 and the text field on y 2.
您不能随意将组件分配给网格。如果组件上方的组件的网格高度为 2,则该组件只会转到网格 2。因此基本上您的每一列都需要具有总网格高度为 3 的组件。
I don't know how to make the list bigger
将首选大小设置为 (20, 20) 没有帮助。无论如何,您不应该使用 setPreferredSize() 方法。
您应该使用:
list.setVisibleRowCount(...);
指定可见行。然后 JList 可以确定自己的首选大小。
另一个布局选项是使用可以简化布局的嵌套面板。
因此您可以从使用 BorderLayout 的 "west" 面板开始。然后将标签添加到 "PAGE_START",将列表添加到 "CENTER"。
然后创建一个 "center" 面板。将主要组件添加到 "CENTER",将文本字段添加到 "PAGE_START"。
然后将两个面板添加到框架中:
frame.add(westPanel, BorderLayout.LINE_START);
frame.add(centerPanel, BorderLayout.CENTER);
编辑:
抱歉,我收回关于让每列的网格高度为 3 的评论。您不能只将总网格高度指定为 3,因为每列中只有 2 个组件,因此每个组件只能高度为 1。
查看我在这篇文章中的回答:Why does this GridBagLayout not appear as planned? 一个允许您通过在 row/column.
中使用不可见组件来操纵 gridHeight/Weight 的 hack但是,我不推荐这种方法。使用 BorderLayout(或嵌套面板上的其他布局管理器)使用我的嵌套面板建议会容易得多。
我修复了将 "console" JPanel 一分为二的问题,左边是边框布局面板,右边是网格包布局面板。正如@camickr 建议的那样