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

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

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的建议,并进行了以下操作:

  1. import javax.swing.*;
  2. import javax.swing.table.DefaultTableModel;
  3. import javax.swing.table.TableModel;
  4. import java.awt.*;
  5. import java.awt.event.ActionEvent;
  6. import java.lang.reflect.InvocationTargetException;
  7. public class TableTest {
  8. private static final int CHECKBOX_COL = 0;
  9. public static void main(String[] args) throws InvocationTargetException, InterruptedException {
  10. SwingUtilities.invokeAndWait(() -> {
  11. var frame = new JFrame("TableTest");
  12. Object[][] data = {new Object[]{true, "Foo"}, new Object[]{false, "Buz"}};
  13. MyModel dm = new MyModel(data, new Object[]{"Enabled", "Name"});
  14. var table = new JTable(dm);
  15. var invertSelected = "InvertSelected";
  16. table.getInputMap().remove(KeyStroke.getKeyStroke("SPACE"));
  17. table.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), invertSelected);
  18. table.getActionMap().put(invertSelected, new AbstractAction() {
  19. @Override
  20. public void actionPerformed(ActionEvent e) {
  21. TableModel model = table.getModel();
  22. for (int selectedRow : table.getSelectedRows()) {
  23. var row = table.convertRowIndexToModel(selectedRow);
  24. var value = !(Boolean) model.getValueAt(row, CHECKBOX_COL);
  25. model.setValueAt(value, row, CHECKBOX_COL);
  26. }
  27. }
  28. });
  29. table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
  30. frame.getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);
  31. frame.pack();
  32. frame.setVisible(true);
  33. });
  34. }
  35. private static class MyModel extends DefaultTableModel {
  36. public MyModel(Object[][] data, Object[] columnNames) {
  37. super(data, columnNames);
  38. }
  39. @Override
  40. public boolean isCellEditable(int row, int column) {
  41. return column == CHECKBOX_COL;
  42. }
  43. @Override
  44. public Class<?> getColumnClass(int columnIndex) {
  45. return (columnIndex == CHECKBOX_COL ? Boolean.class : String.class);
  46. }
  47. }
  48. }

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

英文:

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

  1. import javax.swing.*;
  2. import javax.swing.table.DefaultTableModel;
  3. import javax.swing.table.TableModel;
  4. import java.awt.*;
  5. import java.awt.event.ActionEvent;
  6. import java.lang.reflect.InvocationTargetException;
  7. public class TableTest {
  8. private static final int CHECKBOX_COL = 0;
  9. public static void main(String[] args) throws InvocationTargetException, InterruptedException {
  10. SwingUtilities.invokeAndWait(() -&gt; {
  11. var frame = new JFrame(&quot;TableTest&quot;);
  12. Object[][] data = {new Object[]{true, &quot;Foo&quot;}, new Object[]{false, &quot;Buz&quot;}};
  13. MyModel dm = new MyModel(data, new Object[]{&quot;Enabled&quot;, &quot;Name&quot;});
  14. var table = new JTable(dm);
  15. var invertSelected = &quot;InvertSelected&quot;;
  16. table.getInputMap().remove(KeyStroke.getKeyStroke(&quot;SPACE&quot;));
  17. table.getInputMap().put(KeyStroke.getKeyStroke(&quot;SPACE&quot;), invertSelected);
  18. table.getActionMap().put(invertSelected, new AbstractAction() {
  19. @Override
  20. public void actionPerformed(ActionEvent e) {
  21. TableModel model = table.getModel();
  22. for (int selectedRow : table.getSelectedRows()) {
  23. var row = table.convertRowIndexToModel(selectedRow);
  24. var value = !(Boolean) model.getValueAt(row, CHECKBOX_COL);
  25. model.setValueAt(value, row, CHECKBOX_COL);
  26. }
  27. }
  28. });
  29. table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
  30. frame.getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);
  31. frame.pack();
  32. frame.setVisible(true);
  33. });
  34. }
  35. private static class MyModel extends DefaultTableModel {
  36. public MyModel(Object[][] data, Object[] columnNames) {
  37. super(data, columnNames);
  38. }
  39. @Override
  40. public boolean isCellEditable(int row, int column) {
  41. return column == CHECKBOX_COL;
  42. }
  43. @Override
  44. public Class&lt;?&gt; getColumnClass(int columnIndex) {
  45. return (columnIndex == CHECKBOX_COL ? Boolean.class : String.class);
  46. }
  47. }
  48. }

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:

确定