JTable изменить фон ячейки при щелчке мыши-после выпуска изменить фон обратно?


Мой вопрос в том, как решить следующую задачу:

Если я нажимаю на ячейку в JTable, я хочу изменить ее фон. Если я отпущу кнопку мыши, я хочу, чтобы фон вернулся к нормальному цвету.

Возможно ли это?

Привет Айк

3 3

3 ответа:

В вашем рендерере вы должны пересилить hasFocus

Например

Введите описание изображения здесь

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

Для этого в визуальной области вам нужно

  • Муселистенер, который устанавливает некоторое состояние в координатах ячейки при нажатии и сбрасывает это состояние при отпускании
  • A PropertyChangeListener listeneng к тому состоянию, которое перекрашивает клетку при изменении
  • пользовательский визуализатор, который устанавливает пользовательский фон для ячейки, помеченной флагом

Некоторый код для слушателей

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

Выделение ячейки в SwingX (не могу сопротивляться : -)

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

Для ядра Swing, либо реализовать пользовательский TableCellRenderer или подкласс JTable и переопределить prepareRenderer, чтобы установить цвет фона в соответствии с флагом ячейки, как описано в таблице

Да, это возможно. Используйте пользовательский ListSelectionModel и установите JTable, чтобы использовать его : setSelectionModel().

Вот пример .