JTable Java Swing; Меню правой кнопки мыши (как мне заставить его выбрать или выделить строку)

Коротко: мне нужно «событие щелчка правой кнопкой мыши», чтобы выделить строку ячейки.

Я использую JTable внутри ScrollPane в Java Swing (Netbeans Matisse). У меня есть прослушиватель событий MouseClicked на JTable, который делает следующее:

if (evt.getButton() == java.awt.event.MouseEvent.BUTTON3) {
          System.out.println("Right Click");
          JPopUpMenu.show(myJTable, evt.getX(), evt.getY())
}

Проблема в том, что... всякий раз, когда я щелкаю правой кнопкой мыши по JTable, строка не выделяется (кстати, я устанавливаю выделение только для строк). Я искал несколько функций setSelected(), но не смог найти подходящей. По умолчанию щелчок левой кнопкой мыши автоматически выделяет строку. Как настроить правый клик?


person Community    schedule 24.08.2010    source источник


Ответы (2)


нравится:

table.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseReleased(MouseEvent e) {
        int r = table.rowAtPoint(e.getPoint());
        if (r >= 0 && r < table.getRowCount()) {
            table.setRowSelectionInterval(r, r);
        } else {
            table.clearSelection();
        }

        int rowindex = table.getSelectedRow();
        if (rowindex < 0)
            return;
        if (e.isPopupTrigger() && e.getComponent() instanceof JTable ) {
            JPopupMenu popup = createYourPopUp();
            popup.show(e.getComponent(), e.getX(), e.getY());
        }
    }
});

......

person clamp    schedule 24.08.2010
comment
Вот так:]... верхняя половина mouseReleased() — это то, что мне было нужно. Будет проголосовано + принято в качестве ответа. Спасибо, вы мужчина (или женщина)! - person ; 24.08.2010
comment
Отличный ответ. Деталь: на некоторых платформах (например, Mac OS X) всплывающее меню запускается с помощью mousePressed, а не mouseReleased, поэтому, если вы используете этот код, всплывающее окно не будет отображаться, если вы запустите свое приложение в Mac OS X. - person gabuzo; 31.12.2012
comment
Какова цель получения rowIndex два раза? Я имею в виду, в чем разница между r и rowindex? - person Ad Infinitum; 11.10.2016
comment
Идеальное решение. Не забудьте не использовать метод setComponentPopupMenu(), если вы используете это решение. - person m4heshd; 12.07.2019
comment
См. ниже комментарий Оливера Хоффманна, 26 авг. Единственное изменение, необходимое в исходном решении, — не использовать setRowSelectionInterval() в случае, если сфокусированная строка уже выбрана, например: if (!table.getSelectionModel().isSelectedIndex(r)) table.setRowSelectionInterval(r, r); - person neflow; 24.06.2020

В принятом ответе не учитываются клавиши-модификаторы, такие как ctrl или shift, однако они указывают, что текущий выбор следует не заменить, а расширить .

Кроме того, я добавил поддержку нескольких ОС, отметив mousePressed и mouseReleased.

Ниже вы можете найти полный пример того, как настроить выбранные строки, используя ссылку ListSelectionModel, включая MouseEvent#getModifiers проверяет. После этого можно открыть (необязательно) JPopupMenu .

JPopupMenu contextMenu = new JPopupMenu();
// ...
// add elements to the popup menu
// ...

table.addMouseListener(new MouseAdapter() {
  @Override
  public void mousePressed(MouseEvent e) {
    handleRowClick(e);
    if (e.isPopupTrigger()) {
      doPop(e);
    } else {
      hidePop();
    }
  }

  @Override
  public void mouseReleased(MouseEvent e) {
    if (e.isPopupTrigger()) {
      doPop(e);
    }
  }

  private void handleRowClick(MouseEvent e) {
    ListSelectionModel selectionModel = table.getSelectionModel();
    Point contextMenuOpenedAt = e.getPoint();
    int clickedRow = table.rowAtPoint(contextMenuOpenedAt);

    if (clickedRow < 0) {
      // No row selected
      selectionModel.clearSelection();
    } else {
      // Some row selected
      if ((e.getModifiers() & InputEvent.SHIFT_MASK) == InputEvent.SHIFT_MASK) {
        int maxSelect = selectionModel.getMaxSelectionIndex();

        if ((e.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK) {
          // Shift + CTRL
          selectionModel.addSelectionInterval(maxSelect, clickedRow);
        } else {
          // Shift
          selectionModel.setSelectionInterval(maxSelect, clickedRow);
        }
      } else if ((e.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK) {
        // CTRL
        selectionModel.addSelectionInterval(clickedRow, clickedRow);
      } else {
        // No modifier key pressed
        selectionModel.setSelectionInterval(clickedRow, clickedRow);
      }
    }
  }

  private void doPop(MouseEvent e) {
    if (table.getSelectedRowCount() == 0) {
      return;
    }
    contextMenu.setVisible(true);
    contextMenu.show(e.getComponent(), e.getX(), e.getY());
  }

  private void hidePop() {
    contextMenu.setVisible(false);
  }
});
person Markus Weninger    schedule 01.08.2016
comment
Нет необходимости в ручной обработке выбора, JTable уже учитывает клавиши SHIFT и CTRL и так далее. Единственное изменение, необходимое в исходном решении, — не использовать setRowSelectionInterval() в случае, если сфокусированная строка уже выбрана, например: if (!table.getSelectionModel().isSelectedIndex(r)) table.setRowSelectionInterval(r, r); - person Oliver Hoffmann; 26.08.2016