简体   繁体   English

Java - Swing - JTable - 为选定行设置颜色,但不为单元格设置颜色

[英]Java - Swing - JTable - Set Color for Selected Row, but not Cell

I am trying to make my table select an entire row when you click on a cell (which can be done by turning off column select), but, I don't want the extra thick border around the specific cell you clicked to be highlighted.当您单击一个单元格(这可以通过关闭列选择来完成)时,我试图使我的表 select 成为一整行,但是,我不希望突出显示您单击的特定单元格周围的超粗边框。 I was hoping this would be easy but apparently it involves renderers so I did a lot of research and the closest I can get is this:我希望这会很容易,但显然它涉及渲染器,所以我做了很多研究,我能得到的最接近的是:

    JTable contactTable = new JTable(tableModel);

    contactTable.setCellSelectionEnabled(true);
    contactTable.setColumnSelectionAllowed(false);
    contactTable.setRowSelectionAllowed(false);
    contactTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

    // This renderer extends a component. It is used each time a
    // cell must be displayed.
    class MyTableCellRenderer extends JLabel implements TableCellRenderer {
        // This method is called each time a cell in a column
        // using this renderer needs to be rendered.
        public Component getTableCellRendererComponent(JTable table, Object value,
                boolean isSelected, boolean hasFocus, int rowIndex, int vColIndex) {
            // 'value' is value contained in the cell located at
            // (rowIndex, vColIndex)

            if (isSelected) {
                // cell (and perhaps other cells) are selected

            }

            if (hasFocus) {
                // this cell is the anchor and the table has the focus
                this.setBackground(Color.blue);
                this.setForeground(Color.green);
            } else {
                this.setForeground(Color.black);
            }

            // Configure the component with the specified value
            setText(value.toString());

            // Set tool tip if desired
            // setToolTipText((String)value);

            // Since the renderer is a component, return itself
            return this;
        }

        // The following methods override the defaults for performance reasons
        public void validate() {}
        public void revalidate() {}
        protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}
        public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}
    }

    int vColIndex = 0;
    TableColumn col = contactTable.getColumnModel().getColumn(vColIndex);
    col.setCellRenderer(new MyTableCellRenderer());

I copied the Renderer from an example and only changed the hasFocus() function to use the colors I wanted.我从示例中复制了渲染器,只将 hasFocus() function 更改为使用我想要的 colors。 Setting colors in isSelected() did nothing.isSelected()中设置 colors 没有任何作用。

The problem with this code is:这段代码的问题是:

  1. It only works on one column specified by vColIndex at the bottom.它仅适用于底部 vColIndex 指定的一列。 Obviously I want this applied to all columns so clicking on a cell in one highlights the entire row.显然我希望将其应用于所有列,因此单击一个单元格会突出显示整行。 I could make a for loop to change it to every cell but I figure there's a better way of doing this that changes the cellRenderer for ALL columns at once.我可以制作一个 for 循环以将其更改为每个单元格,但我认为有一种更好的方法可以同时更改所有列的 cellRenderer。

  2. setForegroundColor() works to change text but setBackgroundColor() does nothing to the cells background. setForegroundColor()用于更改文本,但setBackgroundColor()对单元格背景没有任何作用。 I would like it to actually change the background color like the property implies.我希望它像属性暗示的那样实际改变背景颜色。

    • Solution for #2: Use this.setOpaque(true); #2 的解决方案:使用this.setOpaque(true); before assigning backgroundcolor.在分配背景颜色之前。
  3. When the renderer does work, it only works on a single Cell.当渲染器工作时,它只在单个 Cell 上工作。 How can I get it to color all the Cells in the row?我怎样才能让它为行中的所有单元格着色?

    • Solution for #3: I figured it out! #3 的解决方案:我想通了! Instead of using hasFocus() , which only affects the single cell, if you enable row selection ( table.setRowSelectionAllowed(true) ) then you put the color changing in the if(isSelected) statement.如果您启用行选择 ( table.setRowSelectionAllowed(true) ),而不是使用仅影响单个单元格的hasFocus() ,那么您将颜色更改放在if(isSelected)语句中。 Then the whole row is considered selected and it colors all the cells in!然后整行被认为是选中的,它是 colors 中的所有单元格!

3 was the big one but if anyone knows #1 or can explain to me why it was designed such that you can only apply the renderer to one column at a time it would be much appreciated. 3 是最大的,但如果有人知道 #1 或者可以向我解释为什么它被设计成一次只能将渲染器应用于一列,我们将不胜感激。

too direct just do add line太直接了就加行

tablename.setSelectionBackground(Color.red);

in my case就我而言

jtbillItems.setSelectionBackground(Color.red);

The tutorial article Concepts: Editors and Renderers explains that "a single cell renderer is generally used to draw all of the cells that contain the same type of data," as returned by the model's getColumnClass() method.教程文章概念:编辑器和渲染器解释说,“单个单元格渲染器通常用于绘制包含相同类型数据的所有单元格”,如模型的getColumnClass()方法所返回的那样。

Alternatively, override prepareRenderer() , which is invoked for all cells, to selectively alter a row's appearance.或者,覆盖为所有单元格调用的prepareRenderer()以有选择地更改行的外观。 This example compares the two approaches, and the article Table Row Rendering expands on the versatility of the approach.示例比较了这两种方法, 表格行呈现一文扩展了该方法的多功能性。

For the second question you can try setSelectionBackground(Color) and setSelectionForeGround(Color) methods.对于第二个问题,您可以尝试 setSelectionBackground(Color) 和 setSelectionForeGround(Color) 方法。 I'm not sure how you can solve the first one.我不确定您如何解决第一个问题。 And one last suggestion you can use some swing designer plugin such ass JBuilder.最后一个建议您可以使用一些 swing 设计器插件,例如 JBuilder。 It would help lot.这会有很大帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM