GridBagLayout中的JScrollPane影响应用程序的大小

时间:2015-01-06 15:55:40

标签: java swing jscrollpane gridbaglayout

我一直在练习Java GUI开发,在我的一个项目中,我使用GridBagLayout使用JLabelJComboBoxe等各种控件JTable JScrollPane包含JScrollPane

但是,我注意到JPanel似乎影响了我的.Pack(),除非我的身高是一定数量(根据{{ 522 px 或更高) 1}})我的JComboBoxe似乎"紧凑"并且宽度将设置为适合文本而不是我指定的尺寸( 200 px )。

所以我的问题是导致这种情况的原因以及我如何解决这个问题,以便JFrame的高度可以更小,而不会导致JComboBoxe s表现得那样。

我的应用在调整大小之前/之后的截图:

http://i59.tinypic.com/2i6ntc8.jpg

我的应用程序的当前代码:

package gui;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTable;
import javax.swing.SwingConstants;

public class MainWindow {

    public static void main(String[] args) {
        MainWindow main = new MainWindow();
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();

        JComboBox<String> cmbTeam, cmbPosition;
        JLabel lblTeam, lblPosition, lblResults;
        JTable table;
        JSeparator sep1,sep2;

        int rowCount;

        GridBagConstraints gbc = new GridBagConstraints();  

        panel.setLayout(new GridBagLayout());
        gbc.anchor = GridBagConstraints.NORTHWEST;
        gbc.weightx = 1;

        gbc.gridx = 0;
        gbc.gridy = 0;
        lblTeam = new JLabel("First Label");
        panel.add(lblTeam, gbc);

        gbc.gridx = 1;
        lblPosition = new JLabel("Second Label");
        panel.add(lblPosition, gbc);

        gbc.gridx = 0;
        gbc.gridy = 1;
        cmbTeam = new JComboBox<>(new String[]{"Data1","Data2","Data3"});
        cmbTeam.setPreferredSize(new Dimension(200,25));
        panel.add(cmbTeam, gbc);

        gbc.gridx = 1;
        cmbPosition = new JComboBox<>(new String[]{"Data1","Data2","Data3"});
        cmbPosition.setPreferredSize(new Dimension(200,25));
        panel.add(cmbPosition, gbc);

        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.gridwidth = 2;
        sep1 = new JSeparator(SwingConstants.HORIZONTAL);
        panel.add(sep1,gbc);

        gbc.gridy = 3;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.weighty = 1;
        table = new JTable(new String[][]{{"AA","AB","AC"},{"BA","BB","BC"},{"CA","CB","CC"}}, new String[]{"Col1","Col2","Col3"});
        table.setFillsViewportHeight(true);
        panel.add(new JScrollPane(table),gbc);

        gbc.gridy = 4;
        gbc.weighty = 0;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        sep2 = new JSeparator(SwingConstants.HORIZONTAL);
        panel.add(sep2,gbc);

        rowCount = table.getRowCount();
        lblResults = new JLabel(rowCount + " results found.");
        gbc.gridy = 5;
        panel.add(lblResults, gbc);

        frame.setTitle("GridBagLayout Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.add(panel);
        frame.pack();
    }

}

编辑:我通过为每个JComboBox设置最小尺寸来修正高度问题,但是从.pack()生成的空白区域仍未修复。我还注意到,如果我垂直调整窗口大小并使其变小,表格的宽度似乎会减少一个pizel。也许这与它有关?

3 个答案:

答案 0 :(得分:1)

这可能是因为Scollpane试图填补整个空间。正如您可能从其名称中注意到的那样,setPrefferedSize集不是严格的大小。方法setMaximumSizesetMinimumSize设置了严格的限制(实际上不是,但差不多:))。从那以后,添加这两行代码:

cmbTeam.setMinimumSize(new Dimension(200,25));
cmbPosition.setMinimumSize(new Dimension(200,25));

答案 1 :(得分:1)

  

造成这种情况的原因和

通常,当没有足够的空间在GridbagLayout中以其首选大小显示组件时,组件将捕捉到其最小大小。我不确定为什么更改高度会导致首选宽度发生变化,但不知何故,这会导致组合框以最小宽度显示。

  

我将如何修复它,以便JFrame的高度可以更小,而不会导致我的JComboBox表现得那样。

利用框架的默认BorderLayout。将组件分别添加到框架中:

//frame.add(panel);
frame.add(panel, BorderLayout.NORTH);
frame.add(new JScrollPane(table));
frame.add(lblResults, BorderLayout.SOUTH);

当然,您需要整理剩余的代码,因为您不再向面板添加滚动窗格和标签。

当宽度减小时,您仍会看到组合框缩小。

编辑:

  

但是.pack()生成的空格仍然没有修复。

JTable具有“视口”的硬编码首选大小。你可以通过执行以下操作来覆盖它:

table.setPreferredScrollableViewportSize(table.getPreferredSize());

答案 2 :(得分:0)

正如camickr所说,只要没有足够的空间容纳每个组件的首选大小,GridBagLayout就会将所有组件恢复到最小尺寸。

一个简单的解决方案是使最小尺寸与首选尺寸相同:

// Make sure these lines come AFTER you've set the preferred sizes.
cmbTeam.setMinimumSize(cmbTeam.getPreferredSize());
cmbPosition.setMinimumSize(cmbPosition.getPreferredSize());