【问题标题】:How to set space between cells so that cell's content is not erased如何设置单元格之间的空间,以便不删除单元格的内容
【发布时间】:2013-11-07 02:25:14
【问题描述】:

我的下一个烦人的问题是在单元格之间设置空格,这样单元格的内容就不会被删除。 我已经尝试了所有互联网解决方案,但它们没有帮助,因为当我增加边框时,单元格的内容就会被删除。 这是我尝试过的:

public class DateFormatDemo extends JFrame
{
    private Border emptyBorder = BorderFactory.createEmptyBorder(5, 5, 5, 5);
    private JTable dataSearchResultTable;

    public DateFormatDemo()
    {
        JPanel panel = new JPanel(new GridLayout(2, 1, 5, 10));
        panel.setPreferredSize(new Dimension(500, 300));
        panel.add(new JScrollPane(initDataSearchResultTable()));
        super.getContentPane().add(panel);
        super.pack();
        super.setDefaultCloseOperation(EXIT_ON_CLOSE);
        super.setVisible(true);
    }

    private JTable initDataSearchResultTable()
    {
        dataSearchResultTable = new JTable(new MyTableModel()) {

            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column)
            {
                JComponent component = (JComponent) super.prepareRenderer(renderer, row, column);
//              component.setBorder(emptyBorder);
                return component;
            }
        };
        dataSearchResultTable.setIntercellSpacing(new Dimension(5, 10));
        dataSearchResultTable.setSelectionBackground(new Color(0xaaaaff));
        dataSearchResultTable.setFillsViewportHeight(true);
        dataSearchResultTable.setRowSelectionAllowed(true);
        dataSearchResultTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        dataSearchResultTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        dataSearchResultTable.setDefaultRenderer(String.class, new DefaultTableCellRenderer() {
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                    boolean hasFocus, int row, int column)
            {
                JComponent component = (JComponent) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                component.setBorder(emptyBorder);
                return component;
            }
        });
        return dataSearchResultTable;
    }

    class MyTableModel extends AbstractTableModel
    {
        private String[] columnNames = { "First Name", "Last Name", "Timestamp", "Number", "Vegetarian" };
        private Object[][] data ;

        MyTableModel()
        {
            data = new Object[][] {
                    { "Vova", "KipokKipokKipokKipok", Timestamp.valueOf("2013-04-12 11:20:41"), new Integer(5),
                            new Boolean(true) },
                    { "Olia", "Duo", Timestamp.valueOf("2010-01-11 11:11:41"), new Integer(3), new Boolean(false) },
                    { "Oksana", "Stack", Timestamp.valueOf("2012-04-12 11:20:41"), new Integer(2), new Boolean(false) },
                    { "Petro", "White", Timestamp.valueOf("2010-04-12 11:20:21"), new Integer(20), new Boolean(true) },
                    { "Ivan", "Brown", Timestamp.valueOf("2011-04-11 11:20:41"), new Integer(10), new Boolean(true) } };
            fireTableDataChanged();
        }

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

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

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

        public Object getValueAt(int row, int col)
        {
            if (data.length > 0 && data[0] != null) {
                return data[row][col];
            }
            return null;
        }

        /*
         * JTable uses this method to determine the default renderer/ editor for
         * each cell. If we didn't implement this method, then the last column
         * would contain text ("true"/"false"), rather than a check box.
         */
        public Class getColumnClass(int c)
        {
            Object valueAt = getValueAt(0, c);
            return valueAt == null ? Object.class : valueAt.getClass();
        }

        /*
         * Don't need to implement this method unless your table's editable.
         */
        public boolean isCellEditable(int row, int col)
        {
                return true;
        }

        /*
         * Don't need to implement this method unless your table's data can
         * change.
         */
        public void setValueAt(Object value, int row, int col)
        {
            if (data.length > 0 && data[0] != null) {
                data[row][col] = value;
                fireTableCellUpdated(row, col);
            }
        }

    }

    public static void main(String[] args) throws ParseException
    {
        new DateFormatDemo();
    }
}

有人知道如何设置单元格之间的空间,这样单元格的内容就不会被删除吗?

已解决:

dataSearchResultTable.setRowHeight(25);
        dataSearchResultTable.setRowMargin(5);
        dataSearchResultTable.getColumnModel().setColumnMargin(20);

rowMargin 导致选定行比行边框窄。解决方案是只设置rowHeight,而不设置rowMargin。这确保选择不会比行本身更窄。

谢谢!

【问题讨论】:

    标签: java swing jtable


    【解决方案1】:

    我建议您对表使用下一个方法,而不是使用您提到的setRowHeight() 方法(found here):

    private void updateRowHeights(JTable table ) {
        for (int row = 0; row < table.getRowCount(); row++) {
            int rowHeight = table.getRowHeight();
            for (int column = 0; column < table.getColumnCount(); column++) {
                Component comp = table.prepareRenderer(table.getCellRenderer(row, column), row, column);
                rowHeight = Math.max(rowHeight,comp.getPreferredSize().height);
            }
            table.setRowHeight(row, rowHeight);
        }
    }
    

    因为它计算每一行的高度。在这种情况下,您的所有行都会看起来很好。

    当您使用setRowHeight() 时,并不总是能解决系统默认属性的问题,例如,尝试将该行添加到您的代码中,您就会明白我的意思dataSearchResultTable.setFont(new Font("Arial", 1, 25));

    【讨论】:

    • 当单元格组件大于 rowHeight 时,此方法很好,但不是我的情况
    • Java 教程提供了类似的解决方案,但用于设置宽度here