JTable单元格中的小部件

Teg*_*shi 4 java swing editor jtable renderer

JTable列中的小部件预计与正常小部件无法区分,对吧?似乎存在行为差异,采用Swing文档示例并将鼠标移动到素食列中的复选框...它们根本没有反应.我知道那些只是小部件代理,所以突出显示必须手动完成,所以我该如何解决这个问题呢?我试图widget.requestFocusInWindow();mouseMoved()为没有成功替代部件事件处理程序.还有其他解决方法吗?

ten*_*ica 6

您可以创建自己的单元格渲染器,以应用翻转效果.然后,添加一个跟踪鼠标移动的鼠标监听器并重新绘制相关单元格.您需要将效果应用于光标下的当前单元格并清除上一个单元格.

下面是一个简短的示例,演示了复选框渲染器上的此方法.该示例扩展了默认值BooleanRenderer.唯一的变化是getModel().setRollover(...)getTableCellRendererComponent().

import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.UIResource;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

public class TableRolloverDemo {
    private static void createAndShowGUI() {
        JFrame frame = new JFrame("TableRolloverDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final JTable table = new JTable();

        final DefaultTableModel model = new DefaultTableModel(new Object[][] {
                { false }, { false }, { true }, { true } },
                new Object[] { "Column" }) {
            public Class<?> getColumnClass(int columnIndex) {
                return Boolean.class;
            }
        };

        RolloverMouseAdapter rolloverAdapter = new RolloverMouseAdapter(table);
        RolloverBooleanRenderer renderer = new RolloverBooleanRenderer(rolloverAdapter);

        table.addMouseListener(rolloverAdapter);
        table.addMouseMotionListener(rolloverAdapter);

        table.setDefaultRenderer(Boolean.class, renderer);
        table.setModel(model);

        frame.add(new JScrollPane(table));
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    static class RolloverMouseAdapter extends MouseAdapter {
        private int row = -1;
        private int column = -1;
        private JTable table;

        public RolloverMouseAdapter(JTable table) {
            this.table = table;
        }

        public boolean isRolloverCell(int row, int column) {
            return this.row == row && this.column == column;
        }

        @Override
        public void mouseMoved(MouseEvent e) {
            int lastRow = row;
            int lastColumn = column;

            row = table.rowAtPoint(e.getPoint());
            column = table.columnAtPoint(e.getPoint());

            if (row == lastRow && column == lastColumn)
                return;

            if (row >= 0 && column >= 0) {
                table.repaint(table.getCellRect(row, column, false));
            }
            if (lastRow >= 0 && lastColumn >= 0) {
                table.repaint(table.getCellRect(lastRow, lastColumn, false));
            }
        }

        @Override
        public void mouseExited(MouseEvent e) {
            if (row >= 0 && column >= 0) {
                table.repaint(table.getCellRect(row, column, false));
            }
            row = column = -1;
        }

    }

    static class RolloverBooleanRenderer extends JCheckBox implements
            TableCellRenderer, UIResource {
        private static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
        private RolloverMouseAdapter adapter;

        public RolloverBooleanRenderer(RolloverMouseAdapter adapter) {
            super();
            this.adapter = adapter;
            setHorizontalAlignment(JLabel.CENTER);
            setBorderPainted(true);
        }

        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {

            getModel().setRollover(adapter.isRolloverCell(row, column));

            if (isSelected) {
                setForeground(table.getSelectionForeground());
                super.setBackground(table.getSelectionBackground());
            } else {
                setForeground(table.getForeground());
                setBackground(table.getBackground());
            }
            setSelected((value != null && ((Boolean) value).booleanValue()));

            if (hasFocus) {
                setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
            } else {
                setBorder(noFocusBorder);
            }

            return this;
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

  • +1有趣的是,这确实有效:-)并且可能很容易添加到SwingX(每单元翻转支持和组件适配器已经可用).谢谢你的想法!@Tegiri Nenashi - 如果单元格不可编辑,可能不想要翻转视觉效果,或者我们呢? (2认同)