【问题标题】:How to set correctly border for focused cell in jtable?如何为jtable中的焦点单元格正确设置边框?
【发布时间】:2013-11-22 09:18:30
【问题描述】:

我的 jtable 具有不同的三种渲染器。所以,我看不到提供自定义单元格渲染器的简单方法。但我需要当前选中的单元格周围的自定义边框。为此,我使用 prepareRenderer 方法。这可行,但有一个小错误 - 仅显示顶部和底部边框,但不显示左右边框。

请复制、粘贴以查看问题:

public class CellBorderDemo extends JFrame
{
    private JTable dataSearchResultTable;

    public CellBorderDemo()
    {
        JPanel panel = new JPanel(new GridLayout(2, 1, 5, 10));
        panel.setPreferredSize(new Dimension(500, 300));
        dataSearchResultTable = new JTable(new MyTableModel())
        {
            private EmptyBorder emptyBorder = new EmptyBorder(0, 1, 0, 1);
            private Border redBorder = new CompoundBorder(new MatteBorder(1, 0, 1, 0, Color.RED), emptyBorder);
            private Border unselectedBorder = super.getBorder();

            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column)
            {
                Object value = getValueAt(row, column);

                boolean isSelected = false;
                boolean hasFocus = false;

                // Only indicate the selection and focused cell if not printing
                if (!isPaintingForPrint()) {
                    isSelected = isCellSelected(row, column);

                    boolean rowIsLead = (selectionModel.getLeadSelectionIndex() == row);
                    boolean colIsLead = (columnModel.getSelectionModel().getLeadSelectionIndex() == column);

                    hasFocus = (rowIsLead && colIsLead) && isFocusOwner();
                }
                JComponent cellRenderer = (JComponent) renderer.getTableCellRendererComponent(this, value, isSelected,
                        hasFocus, row, column);
                if (isSelected && hasFocus) {
                    cellRenderer.setBorder(redBorder);
                } else {
                    cellRenderer.setBorder(unselectedBorder);
                }
                return cellRenderer;
            }
        };
        dataSearchResultTable.setSelectionBackground(new Color(0xccccff));
        dataSearchResultTable.setFillsViewportHeight(true);
        dataSearchResultTable.setRowSelectionAllowed(true);
        dataSearchResultTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        dataSearchResultTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        dataSearchResultTable.setRowHeight(25);
        dataSearchResultTable.getColumnModel().setColumnMargin(0);
        dataSearchResultTable.setShowGrid(true);
//      dataSearchResultTable.setIntercellSpacing(new Dimension(0, 0));
        dataSearchResultTable.setCellSelectionEnabled(true);

        panel.add(new JScrollPane(dataSearchResultTable));
        super.getContentPane().add(panel);
        super.pack();
        super.setDefaultCloseOperation(EXIT_ON_CLOSE);
        super.setVisible(true);
    }

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

        MyTableModel()
        {
            data = new Object[][] { { "Vova", "KipokKipokKipokKipok", false }, { "Olia", "Duo", true },
                    { "Ivan", "Brown", false } };
        }

        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;
        }

        public Class getColumnClass(int c)
        {
            Object valueAt = getValueAt(0, c);
            return valueAt == null ? Object.class : valueAt.getClass();
        }

        public boolean isCellEditable(int row, int col)
        {
            return true;
        }

        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 CellBorderDemo();
    }
}

您对如何在 jtable 单元格的每一侧设置边框有任何想法吗?

谢谢!

【问题讨论】:

  • I have jtable that has different three types of renderers. So, I don't see easy way to provide custom cell renderer - 我在上一个问题 (stackoverflow.com/q/19863490/131872) 中给了你答案,但即使你使用我的方法,你也接受了另一个答案。

标签: java swing jtable border


【解决方案1】:
  • prepareRenderer 默认为Renderer 行,用于高亮整行

  • 当您想要更改整个单个单元格时,您必须设置和测试行和列,这两个坐标,

【讨论】:

  • 使用 isSelected、isCellEditable。在某些特定情况下,如果不覆盖 UIManager,则在 Nimbus 中不起作用
  • 在方法 prepareRenderer 中,我使用了 getTableCellRendererComponent 方法返回的单元格渲染器,该方法使用行和列。
  • aaaach 现在我看到你的问题更改了 Borders 的命令,简单地切换 emptyBorder 和 MatteBorder 在 Coumpound Border,否则你必须使用 Insets,我认为它会起作用
  • mKorbel 谢谢。我只是覆盖了 MatteBorder 的 getBorderInsets() 方法,它就可以工作。谢谢!
  • 并且不要忘记渲染器在屏幕外绘制,不要对边框中的插图使用零值
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-11
  • 2011-03-11
  • 1970-01-01
  • 2014-08-29
  • 2014-06-06
  • 2014-05-22
相关资源
最近更新 更多