详细说明JPanel具有可变长度字段

时间:2013-03-18 11:34:01

标签: java swing user-interface jpanel layout-manager

我正在尝试创建一个包含N行和2列的Panel,其中第一列是一个标签,其长度可变但在一定限度内(根据语言而变化长度),而第二列包含可能很长的文字。

我尝试使用NetBeans使用GridBagLayout但是在缩放面板或添加非常长的字段时结果很混乱。 在JPanel的截图下面看看我的意思:

enter image description here

我希望左列与左边界隔开,第一列永远不会调整为比它最长标签更小的值(标签必须始终可读),而第二列应该可视化到可用的水平空格然后显示点(而不是裁剪文本)。

虽然我将NorthWest定义为方向,但面板显示在中心垂直对齐

,这也很无聊

编辑:我已经使用TableColumnAdjuster为我的值使用表格行而不是标签,以便我可以使用鼠标选择值。 我仍然有行符合文本的长度,而不是包含Panel:

public class TestPanel extends JPanel
{
    private static ArrayList<String> columnNames = new ArrayList<>();
    static JTable table;
    MyTableModel myTableModel = new MyTableModel();

    static class MyTableModel extends AbstractTableModel
    {
        private String[] columnNames =
        {
            "Name", "Value"
        };
        private Object[][] data =
        {
            { "Subject", "very very very very very very very very very very very very very very very very long subject"},
            { "Date", "" },
            { "Location", "" },
            { "Status", "" },
            { "Notes", "" }
        };

        @Override
        public int getColumnCount()
        { return columnNames.length; }

        @Override
        public int getRowCount()
        {  return data.length; }

        @Override
        public String getColumnName(int col)
        {  return columnNames[col]; }

        @Override
        public Object getValueAt(int row, int col)
        {  return data[row][col]; }

        @Override
        public Class getColumnClass(int c)
        { return getValueAt(0, c).getClass(); }

        @Override
        public boolean isCellEditable(int row, int col)
        { return false; }

        @Override
        public void setValueAt(Object value, int row, int col)
        {        }
    }

    public TestPanel()
    {
        table = new JTable(myTableModel);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        TableColumnAdjuster tca = new TableColumnAdjuster(table);
        tca.adjustColumns();

        JPanel panel = new JPanel(new GridBagLayout());
        panel.add(table);
        GridBagConstraints constraints = new GridBagConstraints();
        constraints.weighty = 1.0;
        constraints.fill = GridBagConstraints.VERTICAL;
        panel.add(Box.createGlue(), constraints);
        add(panel);
    }

    public static void main(String args[])
    {
        JFrame frame = new JFrame();
        frame.setContentPane(new TestPanel());
        frame.setSize(300, 800);
        frame.setVisible(true);
    }
}

而TableColumnAdjuster来自TableColumnAdjuster ..我得到的仍然如下

enter image description here

3 个答案:

答案 0 :(得分:2)

您可能对GridBagLayout的使用不正确。

  1. 要将所有内容推送到顶部,请将GridBagLayout面板包装到另一个面板(如BorderLayout位置的NORTH面板)或在底部添加一个组件占用所有额外空间
  2. 对于第一列中的所有组件,将weightx设置为0,而在第二列中,将其设置为大于0的值。
  3. 要在左边框和标签之间添加一些空格,只需使用insets
  4. 即可

    这是一个说明这个的例子:

    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import java.util.Random;
    
    import javax.swing.Box;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    
    public class Gridbag {
    
        public void initUI() {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JPanel panel = new JPanel(new GridBagLayout());
            Random random = new Random();
            for (int i = 0; i < 10; i++) {
                String label = "Label " + (i + 1);
                StringBuilder fieldValue = new StringBuilder();
                int r = 1 + random.nextInt(4);
                for (int j = 0; j < r; j++) {
                    fieldValue.append("Some long value that may be very long in some cases");
                }
                addField(panel, label, fieldValue.toString());
            }
            GridBagConstraints constraints = new GridBagConstraints();
            constraints.weighty = 1.0;
            constraints.fill = GridBagConstraints.VERTICAL;
            panel.add(Box.createGlue(), constraints);
            frame.add(panel);
            frame.pack();
            frame.setVisible(true);
        }
    
        private void addField(JPanel panel, String label, String fieldValue) {
            GridBagConstraints labelGBC = new GridBagConstraints();
            labelGBC.insets = new Insets(0, 5, 0, 5);
            labelGBC.anchor = GridBagConstraints.EAST;
            GridBagConstraints fieldGBC = new GridBagConstraints();
            fieldGBC.gridwidth = GridBagConstraints.REMAINDER;
            fieldGBC.weightx = 1.0;
            fieldGBC.anchor = GridBagConstraints.WEST;
            panel.add(new JLabel(label), labelGBC);
            panel.add(new JLabel(fieldValue), fieldGBC);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new Gridbag().initUI();
                }
            });
        }
    
    }
    

答案 1 :(得分:1)

您可以使用带有两列和TableColumnAdjusterTableCellRenderer的JTable,以便将列的宽度调整为最长的内容。

答案 2 :(得分:1)

实现它的一种方法是在“嵌套布局”中使用3个面板。小组的布局如下。

  1. 使用BorderLayout作为外部面板,它包含面板2&amp; 3。
  2. 使用单个列GridLayout - 放入BorderLayout.LINE_START
  3. 使用单个列GridLayout - 放入BorderLayout.CENTER