JTable: send key event to all selected components to check all selected checkboxes

huangapple go评论82阅读模式
英文:

JTable: send key event to all selected components to check all selected checkboxes

问题

我有一个带有复选框的JTable(因为getColumnClassBoolean)。用户选择了多行,并点击空格键,但只有lead selection的复选框会收到KeyEvent并变为选中状态。

如何检查所有选中的复选框?

这看起来是一个非常简单的任务,但我找不到“官方”的方法来做到这一点,我也不想使用hack。

我可以在我的表格中重写processKeyEvent,并在模型中物理地设置所有值为true,但这看起来不太好。

英文:

I have JTable with checkboxes (because getColumnClass is Boolean).
User selects several rows, and clicks space but only "lead selection" checkbox gets KeyEvent and becomes checked.

How can I check all selected checkboxes?

It looks like a very simple task, but I can't find "official" way to do that, and I do not want to use hacks.

I can override processKeyEvent in my table and physically set true to all values in model, but it doesn't look good.

答案1

得分: 2

我遵循了@camickr和@Jean Willian S. J的建议,并进行了以下操作:

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.lang.reflect.InvocationTargetException;

public class TableTest {
    private static final int CHECKBOX_COL = 0;

    public static void main(String[] args) throws InvocationTargetException, InterruptedException {
        SwingUtilities.invokeAndWait(() -> {
            var frame = new JFrame("TableTest");

            Object[][] data = {new Object[]{true, "Foo"}, new Object[]{false, "Buz"}};
            MyModel dm = new MyModel(data, new Object[]{"Enabled", "Name"});
            var table = new JTable(dm);
            var invertSelected = "InvertSelected";
            table.getInputMap().remove(KeyStroke.getKeyStroke("SPACE"));
            table.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), invertSelected);
            table.getActionMap().put(invertSelected, new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    TableModel model = table.getModel();
                    for (int selectedRow : table.getSelectedRows()) {
                        var row = table.convertRowIndexToModel(selectedRow);
                        var value = !(Boolean) model.getValueAt(row, CHECKBOX_COL);
                        model.setValueAt(value, row, CHECKBOX_COL);
                    }
                }
            });
            table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);

            frame.getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);
            frame.pack();
            frame.setVisible(true);
        });
    }

    private static class MyModel extends DefaultTableModel {
        public MyModel(Object[][] data, Object[] columnNames) {
            super(data, columnNames);
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            return column == CHECKBOX_COL;
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            return (columnIndex == CHECKBOX_COL ? Boolean.class : String.class);
        }
    }
}

现在它可以正常工作。谢谢大家。

英文:

I followed @camickr and @Jean Willian S. J 's suggestion, and did:

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.lang.reflect.InvocationTargetException;
public class TableTest {
private static final int CHECKBOX_COL = 0;
public static void main(String[] args) throws InvocationTargetException, InterruptedException {
SwingUtilities.invokeAndWait(() -&gt; {
var frame = new JFrame(&quot;TableTest&quot;);
Object[][] data = {new Object[]{true, &quot;Foo&quot;}, new Object[]{false, &quot;Buz&quot;}};
MyModel dm = new MyModel(data, new Object[]{&quot;Enabled&quot;, &quot;Name&quot;});
var table = new JTable(dm);
var invertSelected = &quot;InvertSelected&quot;;
table.getInputMap().remove(KeyStroke.getKeyStroke(&quot;SPACE&quot;));
table.getInputMap().put(KeyStroke.getKeyStroke(&quot;SPACE&quot;), invertSelected);
table.getActionMap().put(invertSelected, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
TableModel model = table.getModel();
for (int selectedRow : table.getSelectedRows()) {
var row = table.convertRowIndexToModel(selectedRow);
var value = !(Boolean) model.getValueAt(row, CHECKBOX_COL);
model.setValueAt(value, row, CHECKBOX_COL);
}
}
});
table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
frame.getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
});
}
private static class MyModel extends DefaultTableModel {
public MyModel(Object[][] data, Object[] columnNames) {
super(data, columnNames);
}
@Override
public boolean isCellEditable(int row, int column) {
return column == CHECKBOX_COL;
}
@Override
public Class&lt;?&gt; getColumnClass(int columnIndex) {
return (columnIndex == CHECKBOX_COL ? Boolean.class : String.class);
}
}
}

It now works. Thank you, everyone

huangapple
  • 本文由 发表于 2020年7月31日 06:54:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/63182530.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定