简体   繁体   中英

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. 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. Setting colors in isSelected() did nothing.

The problem with this code is:

  1. It only works on one column specified by vColIndex at the bottom. 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.

  2. setForegroundColor() works to change text but setBackgroundColor() does nothing to the cells background. I would like it to actually change the background color like the property implies.

    • Solution for #2: Use this.setOpaque(true); before assigning backgroundcolor.
  3. When the renderer does work, it only works on a single Cell. How can I get it to color all the Cells in the row?

    • Solution for #3: I figured it out! 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. Then the whole row is considered selected and it colors all the cells in!

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.

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.

Alternatively, override prepareRenderer() , which is invoked for all cells, to selectively alter a row's appearance. 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. 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. It would help lot.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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