4

列内のウィジェットはJTable、通常のウィジェットと区別できないはずですよね? 動作に違いがあるようです。Swing のドキュメントの例を見て、 Vegetarian列のチェックボックスにマウスを移動してください。まったく反応しません。これらは単なるウィジェットの代理であることを理解しています。強調表示は手動で行う必要があります。どうすれば修正できますか? サロゲート ウィジェット イベント ハンドラを試してみwidget.requestFocusInWindow(); ましたが、成功しませんでした。mouseMoved()他の回避策はありますか?

4

3 に答える 3

6

ロールオーバー効果を適用する独自のセルレンダラーを作成できます。次に、マウスの動きを追跡し、関連するセルを再描画するマウスリスナーを追加します。カーソルの下の現在のセルに効果を適用し、前のセルをクリアする必要があります。

以下は、チェックボックスレンダラーでこのアプローチを示す短い例です。この例では、defaultを拡張しています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();
            }
        });
    }
}
于 2012-11-09T05:50:56.620 に答える
3

テーブル内のウィジェットが死んでいるように見えるのは、ロールオーバー (またはその欠如) です。JPanelウィジェットの本物のコンテナーである場合、なぜそうJTableJTreeないのでしょうか?

と の両方JTableで、レンダリングにflyweight パターンJTreeを使用します。デフォルトのレンダラーとエディターには、固有のマウスオーバー動作がありません。@Maxが示すように、目的の動作を自分で提供する必要があります。

于 2012-11-09T18:46:54.880 に答える
0

Jtable は実際のコンポーネントをセルに入れません。コンポーネントのペイント メソッドのみを使用して、セルのコンテンツをレンダリングします。

于 2012-11-09T14:38:29.517 に答える