JTable change cell background at mouse click - after release change background back?

前端 未结 3 1650
孤城傲影
孤城傲影 2021-01-06 21:30

my question is, how to solve following problem:

If i click on a cell in a JTable, i want to change its background. If i release the mousebutton, i want the backgroun

相关标签:
3条回答
  • 2021-01-06 21:53

    in your renderer you have to overide hasFocus

    for example

    enter image description here

    import java.awt.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.table.*;
    
    public class TableRenderer extends JFrame {
    
        private static final long serialVersionUID = 1L;
        private JTable table;
        private String[] columnNames = {"Date", "String", "Centered", "Integer", "Boolean"};
        private Object[][] data = {
            {new Date(), "A", "A", new Integer(1), true},
            {new Date(), "B", "B", new Integer(2), false},
            {new Date(), "C", "C", new Integer(10), null},
            {new Date(), "D", "D", new Integer(4), false}
        };
    
        public TableRenderer() {
            DefaultTableModel model = new DefaultTableModel(data, columnNames);
            table = new JTable(model) {
    
                private static final long serialVersionUID = 1L;
                //  Returning the Class of each column will allow different
                //  renderers to be used based on Class
    
                @Override
                public Class getColumnClass(int column) {
                    return getValueAt(0, column).getClass();
                }
            };
            table.setPreferredScrollableViewportSize(table.getPreferredSize());
            JScrollPane scrollPane = new JScrollPane(table);
            getContentPane().add(scrollPane);
    
            //  Override default renderer on a specific Class
            TableCellRenderer colorRenderer = new ColorRenderer();
            table.setDefaultRenderer(String.class, colorRenderer);
    
            //  Override default renderer for a specific column
            DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
            centerRenderer.setHorizontalAlignment(JLabel.CENTER);
            table.getColumnModel().getColumn(2).setCellRenderer(centerRenderer);
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    TableRenderer frame = new TableRenderer();
                    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        /*
         **  Color the focused cell
         */
        private class ColorRenderer extends DefaultTableCellRenderer {
    
            private static final long serialVersionUID = 1L;
    
            @Override
            public Component getTableCellRendererComponent(
                    JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                if (hasFocus) {
                    setBackground(Color.cyan);
                } else if (isSelected) {
                    setBackground(table.getSelectionBackground());
                } else {
                    setBackground(table.getBackground());
                }
                return this;
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-06 22:12

    For doing it in the visual realm you need

    • a MouseListener which sets some state in cell-coordinates on pressed and resets that state on released
    • a PropertyChangeListener listeneng to that state which repaints the cell on change
    • a custom renderer which sets a custom background for the cell that is flagged

    some code for the listeners

        MouseListener l = new MouseAdapter() {
    
            /** 
             * @inherited <p>
             */
            @Override
            public void mousePressed(MouseEvent e) {
                JTable table = (JTable) e.getComponent();
                int col = table.columnAtPoint(e.getPoint());
                int row = table.rowAtPoint(e.getPoint());
                if (col < 0 || row < 0) {
                    table.putClientProperty("pressedCell", null);
                } else {
                    table.putClientProperty("pressedCell", new Point(col, row));
                }
            }
    
            /** 
             * @inherited <p>
             */
            @Override
            public void mouseReleased(MouseEvent e) {
                ((JTable) e.getComponent()).putClientProperty("pressedCell", null);
            }
    
        };
        table.addMouseListener(l);
        PropertyChangeListener property = new PropertyChangeListener() {
    
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                JTable table = (JTable) evt.getSource();
                Point cell = evt.getNewValue() != null ? 
                        (Point) evt.getNewValue() : (Point) evt.getOldValue();
                if (cell != null) table.repaint(table.getCellRect(cell.y, cell.x, false));        
            }
    
        };
        table.addPropertyChangeListener("pressedCell", property);
    

    Highlighting the cell in SwingX (cant resist :-)

        HighlightPredicate predicate = new HighlightPredicate() {
    
            @Override
            public boolean isHighlighted(Component renderer, ComponentAdapter adapter) {
                Point p = (Point) adapter.getComponent().getClientProperty("pressedCell");
                return p != null && p.x == adapter.column && p.y == adapter.row;
    
            }
        };
        table.addHighlighter(new ColorHighlighter(predicate, Color.YELLOW, null, Color.YELLOW, null));
    

    For core Swing, either implement a custom TableCellRenderer or subclass the JTable and override prepareRenderer to set the background color according to the cell flag, as explained in Rob's Table Row Rendering

    0 讨论(0)
  • 2021-01-06 22:18

    Yes it is possible. Use a custom ListSelectionModel and set your JTable to use that : setSelectionModel().

    Here's an example.

    0 讨论(0)
提交回复
热议问题