我正在尝试使用Java Swing(GridBagLayout)创建一个控制台。
我不知道为什么,但正如您在左边距所看到的那样,网格的大小不正确。
其中浅蓝色是列表,绿色图像,橙色文本面板,黄色文本字段。
我不知道如何使列表更大,图像更小。也就是说,文本字段的网格绑定到列表一,即使列表在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);
}
}
答案 0 :(得分:4)
这里有一些代码。
哪个没有帮助。网格只能使用整个代码完成。也就是说,我们需要知道所有组件的网格宽度和网格高度,以确定网格中每个组件的空间分配。
文本字段的网格绑定到列表一,即使列表位于y 1,文本字段位于y 2上也很困难。
您无法随意将组件分配到网格中。如果组件上方的组件的网格高度为2,则组件将仅转到网格2.因此,基本上每个列都需要具有总网格高度为3的组件。
我不知道如何让名单更大
设置首选大小(20,20)无济于事。无论如何,你不应该使用setPreferredSize()方法。
相反,你应该使用:
list.setVisibleRowCount(...);
指定可见行。然后JList可以确定自己的首选大小。
另一种布局选项是使用嵌套面板,这可以简化布局。
所以你可以从&#34; west&#34;开始。使用BorderLayout的面板。然后将标签添加到&#34; PAGE_START&#34;和#34; CENTER&#34;的列表。
然后你创建一个&#34;中心&#34;面板。将主要组件添加到&#34; CENTER&#34;和#34; PAGE_START&#34;。
的文本字段然后将两个面板添加到框架中:
frame.add(westPanel, BorderLayout.LINE_START);
frame.add(centerPanel, BorderLayout.CENTER);
编辑:
抱歉,我收回了关于使每列的网格高度为3的评论。您不能指定总网格高度为3,因为每列只有2个组件,因此每个组件只能高度为1.
在这篇文章中查看我的答案:Why does this GridBagLayout not appear as planned?,以便通过使用行/列中不可见的组件来操纵gridHeight / Weight。
但是,我不推荐这种做法。使用BorderLayout(或嵌套面板上的其他布局管理器)来使用我对嵌套面板的建议会容易得多。
答案 1 :(得分:0)
在我看来,您还需要为文本字段指定gridwidth
和/或gridheight
。
GridBagLayout就像一个美化的GridLayout。它将尝试将所有组件与其周围最近的网格空间对齐。 Oracle's Tutorials也描述了这种行为。
很多时候,使用GridBagLayout布局组件的问题来自添加到布局中的其他组件,而不是明显的问题子组件。
答案 2 :(得分:0)
我修复了它将“控制台”JPanel拆分为两个,左边是边框布局面板,右边是网格包布局面板。正如@camickr建议的那样