Интерфейс Java ListSelectionListener с клавиатурой

Я реализовал ListSelectionListener, как вы можете видеть ниже, так что после выбора определенной строки в первой таблице вторая таблица обновляется соответствующим образом.

class SelectionListener implements ListSelectionListener {

    public SelectionListener(){}

    @Override
    public void valueChanged(ListSelectionEvent e) 
    {
        if (e.getSource() == myTrumpsAndMessages.jTable1.getSelectionModel() 
            && myTrumpsAndMessages.jTable1.getRowSelectionAllowed()
            && e.getValueIsAdjusting()) 
        {
          int selected = myTrumpsAndMessages.jTable1.getSelectedRow();
            clearjTable(jTable4);
            showSubscribers(selected);
        }
    }

}

Есть ли способ вызвать слушателя не только при выборе мышью, но и при выборе с клавиатуры?


person Onca    schedule 29.08.2012    source источник
comment
Из памяти выбор может не измениться, пока пользователь не нажмет пробел или не войдет - не проверено, просто работает с моей утренней памятью - это будет означать, что вы не будете получать события изменения выбора до тех пор   -  person MadProgrammer    schedule 30.08.2012
comment
прослушиватель вызывается всякий раз, когда изменяется выбор, независимо от низкоуровневого триггера для изменения (мышь, клавиатура, программный, джойстик и т. д.). Если это не работает в вашем коде, что-то не так в той части, которую вы не показываете . Кстати: не забудьте проверить свойство getValueIsAdjusting, прежде чем что-то делать   -  person kleopatra    schedule 30.08.2012
comment
@kleopatra, что проверка выполнена (последнее условие в операторе if), но проверка отличается от всех других слушателей и может объяснить проблему. Я включил это замечание в свой ответ   -  person Robin    schedule 30.08.2012
comment
@Robin Позор мне за то, что я слишком ленив, чтобы прокручивать ;-) Что вы подразумеваете под отличным от всех остальных?   -  person kleopatra    schedule 30.08.2012
comment
@kleopatra обычно ничего не делает, пока getValueIsAdjusting не вернет false. В этом случае код срабатывает только при изменении значения.   -  person Robin    schedule 30.08.2012
comment
@ Робин, черт возьми .. пропустил это, так что это была не только прокрутка :-) Опечатка или особенность?   -  person kleopatra    schedule 30.08.2012


Ответы (3)


Причина необычного опыта — отсутствие уведомления о выборе с помощью клавиатуры — заключается в тонком различии настроек valueIsAdjusting для событий выбора, запускаемых с помощью клавиатуры и мыши:

  • выбор, запускаемый клавиатурой (даже с модификаторами), срабатывает только один раз (с настройкой == false)
  • выбор, вызванный мышью, всегда срабатывает дважды (первый с истинным, второй с ложным)

Этот факт в сочетании с необычной логикой (которую заметил @Robin, +1 ему :-)

if (e.getSource() == myTrumpsAndMessages.jTable1.getSelectionModel() 
        && myTrumpsAndMessages.jTable1.getRowSelectionAllowed()
        // typo/misunderstanding or feature? doing stuff only when adjusting 
        && e.getValueIsAdjusting()) 

(реакция только в том случае, если выделение изменяется) приводит к тому, что изменения, вызванные клавиатурой, не отображаются.

person kleopatra    schedule 30.08.2012
comment
+1 за лучшее объяснение почему. Я только предположил, что это было причиной проблемы, теперь я также знаю, почему - person Robin; 30.08.2012
comment
Спасибо, я изменил на && e.getValueIsAdjusting()==false, и это решило проблему. - person Onca; 30.08.2012

Есть ли способ вызвать слушателя не только при выборе мышью, но и при выборе с клавиатуры?

Слушатель будет запущен независимо от источника изменения выбора. Так что да, это вполне возможно и даже поведение по умолчанию. Так что ничего особенного делать не нужно, чтобы это заработало.

Глядя на код вашего слушателя, я бы предложил переписать его на

class SelectionListener implements ListSelectionListener {
  public SelectionListener(){}
  @Override
  public void valueChanged(ListSelectionEvent e){
    if ( e.getValueIsAdjusting() ){
       return;
    }
    if (e.getSource() == myTrumpsAndMessages.jTable1.getSelectionModel() && 
        myTrumpsAndMessages.jTable1.getRowSelectionAllowed() ) {
      int selected = myTrumpsAndMessages.jTable1.getSelectedRow();
      clearjTable(jTable4);
      showSubscribers(selected);
    }
  }
}

Обратите внимание на быстрый отход от метода, когда getValueIsAdjusting() возвращает true, так как это поведение, которое вам нужно в большинстве случаев.

person Robin    schedule 30.08.2012

Я только что попробовал ListSelectionListener, и событие valueChanged() на самом деле также запускается при изменении выбора клавиатуры. Смотрите мой пример ниже:

list.addListSelectionListener(new ListSelectionListener() {
  public void valueChanged(ListSelectionEvent e) {
    System.out.println(list.getSelectedValue());
  }
});
person Dan D.    schedule 29.08.2012
comment
Конечно, это потому, что вы не проверили, что e.getValueIsAdjusting())==true. когда вы опускаете это, каждое событие происходит дважды. - person Onca; 30.08.2012
comment
@ Onca, вы, вероятно, хотите проверить e.getValueIsAdjusting() == false, а не true. Смотри мой ответ - person Robin; 30.08.2012