0

Java 8, Eclipse 2018-12, WindowsBuilder 1.9.1

I added a JTable with 2 columns and 5 rows to my Frame:

JTable table = new JTable();
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
table.setModel(new DefaultTableModel(
    new Object[][] {
        {null, null},
        {null, null},
        {null, null},
        {null, null},
        {null, null},
    },
    new String[] {
        "ColumnA", "ColumnB"
    }
));

With this code a single row is selected by clicking on it but to select multiple rows you have to press Shift/Ctrl. If you click on another row without pressing Shift/Ctrl, the current selection is deleted.

How do I make it work more like "on/off" (without pressing any additional keys)?

  • Clicking on row 1 selects it
  • Clicking on row 3 selects it, additional to row 1
  • Clicking on row 1 again deselects it (but leaves row 3 selected)

Is this even possible with a JTable? If not, is there anything else that can be used similar to a JTable but can be selected the way I need it to?

Neph
  • 1,823
  • 2
  • 31
  • 69
  • You can implement [focus listener](https://docs.oracle.com/en/java/javase/12/docs/api/java.desktop/java/awt/event/FocusListener.html) and check for the row selected and keep it in memory. When user selects another row. Reapply focus to all rows that were selected using `addSelectionInterval` – Yoshikage Kira Sep 12 '19 at 14:28
  • @Goion Thanks for the suggestion! Aren't listeners like that pretty "expensive" performance-wise? Is there any UI element that can do what I need (semi-) out of the box? – Neph Sep 12 '19 at 14:38
  • 2
    See: [JTable multiple selection without the CTRL](https://stackoverflow.com/questions/39545591/jtable-multiple-selection-without-the-ctrl/39548102#39548102) – camickr Sep 12 '19 at 14:41
  • @camickr Thanks, this indeed works with a `JTable`! Want to post it here as an answer too to gain some more fake internet points? – Neph Sep 12 '19 at 14:50
  • @camickr I just noticed that deselecting multiple rows doesn't work. If I click on e.g. row 1 and pull down to row 10, they are all selected. But if I click on row 1 again and pull down, row 1 is deselected for a split second, then goes back to being selected and the other rows don't change at all. I tried looping from `index0` to `index1` and doing the same `isSelectedIndex()` check individually but that just makes the rows flicker on and off. Same thing if I just check the very first one and change everything else depending on its state (without `for`). – Neph Sep 12 '19 at 15:05
  • Yes that is the way it was designed to work. When you click and drag all the items are selected. That is why the `addSelectionInterval(...)` method is invoked. It is not designed to check the state of the first item clicked and reset the state of all other item to that state as you drag. If it doesn't do what you want then you can try to manipulate the logic to meet your requirement. – camickr Sep 12 '19 at 15:20
  • Yes, I changed it. First test: Check only the first index and apply the opposite state to all of them (no matter if they're selected or not). Second test: Check all of them individually and also change their states individually. But with both versions the rows start to flicker as if pulling down sets off a single row multiple times. Afterwards about half of them end up being in the wrong state. – Neph Sep 12 '19 at 15:27
  • As you drag the mouse from row to row, multiple ListSelectionEvents are generated so you are continually toggling the selection on/off. I made the decision to always set the selection on to avoid this problem. To do what you want you would also need this class to implement a MouseListener. Then on the mousePressed event you would need to get current state of the row you clicked on. Then you would toggle that value and apply it to all the other rows as you drag the mouse. Problem is you need access to the JTable so the MouseListener can determine the original state of the row that was clicked – camickr Sep 12 '19 at 15:34
  • And if I just want to set all the rows to the same state as the first selected one? Wouldn't it be possible to simply "lock" it with a static boolean instead of using the MouseListener? The first event locks the code, so it can't run multiple times and it's unlocked after the current run is done. I'm currently testing what code I can lock and what I shouldn't. – Neph Sep 13 '19 at 08:32
  • Ad lock: Okay, not as easy as I thought it would be, it's still being called a lot and it's also still flickering. – Neph Sep 13 '19 at 09:17
  • *Wouldn't it be possible to simply "lock" it with a static boolean instead of using the MouseListener?* - no because 1) you don't know when the mouse is first pressed. All you get is a bunch of events. You don't know which events are related. 2) Also lets say you click on item 5 and then drag down to 10 and then up to 1. Even if you do keep the original state all the items from 6-10 should be reset to the opposite of the saved state. So I'm starting to think what you want can't be done easily. Even the default implementation doesn't support selection by dragging. This is probably why. – camickr Sep 13 '19 at 14:23

0 Answers0