我正在尝试使用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);
}
}
下面是一些代码。
这无济于事。网格只能用整个代码完成。也就是说,我们需要知道所有组件的网格宽度和网格高度,以便确定网格中每个组件的空间分配。
文本字段的网格与列表绑定在一起,尽管列表在y 1上,文本字段在y 2上。
你不能随便给一个网格分配一个组件。仅当组件上方的组件的网格高度为2时,组件才会转到网格2。所以基本上你的每一列都需要有总网格高度为3的组件。
我不知道如何把名单扩大
将首选大小设置为 (20, 20) 无济于事。无论如何,你不应该使用 setPreferredSize() 方法。
相反,您应该使用:
list.setVisibleRowCount(...);
以指定可见行。然后JList可以确定自己喜欢的大小。
另一个布局选项是使用嵌套面板,这可以简化布局。
所以你可以从一个使用边界布局的“西”面板开始。然后将标签添加到“PAGE_START”,将列表添加到“CENTER”。
然后创建一个“中心”面板。将主组件添加到“中心”,将文本字段添加到“PAGE_START”。
然后将两个面板添加到框架中:
frame.add(westPanel, BorderLayout.LINE_START);
frame.add(centerPanel, BorderLayout.CENTER);
编辑:
对不起,我收回了我关于让每列的网格高度为3的评论。不能只指定总轴网高度为3,因为每列中只有2个构件,所以每个构件的高度只能为1。
看看我在这篇文章中的回答:为什么这个GridBagLayout没有按计划出现?一个黑客,允许你通过使用行/列中的不可见组件来操纵网格高度/重量。
但是,我不建议使用这种方法。使用我建议的嵌套面板使用BorderLayout(或嵌套面板上的其他布局管理器)会容易得多。
在我看来,您还需要为文本字段指定< code>gridwidth和/或< code>gridheight。
GridBagLayout就像一个荣耀的GridLayout。它将尝试将所有组件与周围最近的网格空间对齐。Oracle的教程也描述了这种行为。
很多时候,使用GridBagLayout布局组件的问题来自于添加到布局中的其他组件,而不是明显的问题子组件。
我修复了它,将“控制台”JPanel 一分为二,左侧是边框布局面板,右侧是网格袋布局面板。正如@camickr所建议的