设置GridBagLayout网格的大小

时间:2016-02-10 15:13:14

标签: java swing layout-manager gridbaglayout

我正在尝试使用Java Swing(GridBagLayout)创建一个控制台。

我不知道为什么,但正如您在左边距所看到的那样,网格的大小不正确。

The code output

它应该以这种方式显示: enter image description here

其中浅蓝色是列表,绿色图像,橙色文本面板,黄色文本字段。

我不知道如何使列表更大,图像更小。也就是说,文本字段的网格绑定到列表一,即使列表在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);
    }
}

3 个答案:

答案 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建议的那样