Выделение строки JTable правой кнопкой мыши

Совсем недавно, когда я писал своё приложение, возникла необходимость выделять строку таблицы JTable правой кнопкой мыши. В JTable у меня должен был показываться список элементов. Нужно было дать возможность при нажатии правой кнопкой мыши одновременно выделять строку в таблице и показывать контекстное меню для только что выбранного элемента. Показывать контекстное меню не составило большого труда, а вот выделение нужного элемента оказалось посложнее. Как это сделать читайте дальше.

Как только передо мной встала проблема выделения строки JTable правой кнопкой мыши, я начал поиск методов самого JTable для включения такой возможности (я наивно полагал, что они есть). Однако все мои поиски были тщетны 🙂 Но решение всё же нашлось. Для начала необходимо прослушивать события мыши JTable. Как только событие нажатия произошло, необходимо проверить, какая именно кнопка нажата пользователем. Если нажата правая кнопка, то определяем строку и столбец JTable по координатам, которые можно получить из объекта события, которое передается в обработчик. Далее, на основе полученных координат определяем эти строку и столбец и просим таблицу выделить их.

Для большей понятности рассмотрим код. JTable имеет два полезных метода columnAtPoint() и rowAtPoint(). Первый возвращает номер столбца для точки Point, которая хранит информацию о том, в каком месте находился курсор мыши в момент нажатия кнопки мыши. Второй метод возвращает номер строки. Оба метода имеют один параметр типа Point. Откуда взять этот самый Point. А взять его можно из объекта MouseEvent, который создается системой и передается в обработчик нажатия мыши MouseListener.

public void mousePressed(MouseEvent event) {
     if(event.getButton() == MouseEvent.BUTTON3) {
          int column = table.columnAtPoint(event.getPoint());
          int row = table.rowAtPoint(event.getPoint());
          table.setColumnSelectionInterval(column, column);
          table.setRowSelectionInterval(row, row);
     }
}

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

event.getButton() == MouseEvent.BUTTON3

Далее получаем номера строки и столбца, над которыми и произошло нажатие.

int column = table.columnAtPoint(event.getPoint());
int row = table.rowAtPoint(event.getPoint());

Ну и кульминация момента — говорим таблице JTable выделить только что полученные строку и столбец.

table.setColumnSelectionInterval(column, column);
table.setRowSelectionInterval(row, row);

Таблица JTable позволяет выделять по несколько строк сразу, идущих одна за другой — интервал (если позволяет SelectionModel). При выделении интервала нужно указывать начала и конец. В нашем случае мы выделяем одну строку и столбец, поэтому начало и конец интервала совпадают, то есть интервал у нас состоит из одного элемента.

Стоит упомянуть кое-что про setColumnSelectionInterval(). Если не делать его вызов, то ячейка таблицы JTable, над которой будет происходить нажатие не будет получать фокус и обрамляться соответствующим прямоугольником. Если нужно только выделять строку, то можно и не делать этот вызов.

По традиции полновесный рабочий пример, внешний вид которого представлен на рисунке ниже.

jtable_right_button_selection

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;

public class TestFrame extends JFrame {

     public static void createGUI() {
          JFrame frame = new JFrame("Test frame");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

          String[] columnNames = { "Name", "Last modified", "Type" };

          String[][] data = { { "addins", "02.11.2006 19:15", "Folder" },
                    { "AppPatch", "03.10.2006 14:10", "Folder" },
                    { "assembly", "02.11.2006 14:20", "Folder" },
                    { "Boot", "13.10.2007 10:46", "Folder" },
                    { "Branding", "13.10.2007 12:10", "Folder" },
                    { "Cursors", "23.09.2006 16:34", "Folder" },
                    { "Debug", "07.12.2006 17:45", "Folder" },
                    { "Fonts", "03.10.2006 14:08", "Folder" },
                    { "help.exe", "08.11.2006 18:23", "File" } };

          JPanel mainPanel = new JPanel();
          mainPanel.setLayout(new BorderLayout());

          final JTable table = new JTable(data, columnNames);
          JScrollPane scrollPane = new JScrollPane(table);
          mainPanel.add(scrollPane, BorderLayout.CENTER);

          table.addMouseListener(new MouseListener() {

               public void mouseClicked(MouseEvent event) {

               }

               public void mouseEntered(MouseEvent event) {

               }

               public void mouseExited(MouseEvent event) {

               }

               public void mousePressed(MouseEvent event) {
                    if (event.getButton() == MouseEvent.BUTTON3) {
                         Point point = event.getPoint();
                         int column = table.columnAtPoint(point);
                         int row = table.rowAtPoint(point);
                         table.setColumnSelectionInterval(column, column);
                         table.setRowSelectionInterval(row, row);
                    }
               }

               public void mouseReleased(MouseEvent event) {

               }

          });

          frame.getContentPane().add(mainPanel);

          frame.setPreferredSize(new Dimension(450, 180));
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
     }

     public static void main(String[] args) {
          javax.swing.SwingUtilities.invokeLater(new Runnable() {
               public void run() {
                    JFrame.setDefaultLookAndFeelDecorated(true);
                    createGUI();
               }
          });
     }
}

5 Responses to Выделение строки JTable правой кнопкой мыши

  1. cyper_:

    Необходимо еще сделать проверку, в противном случае «вылетит» исключение:

    public void mousePressed(MouseEvent event) {
    if (event.getButton() == MouseEvent.BUTTON3) {
    Point point = event.getPoint();
    int column = table.columnAtPoint(point);
    int row = table.rowAtPoint(point);

    //выполняем проверку
    if(column!=-1 && row!=-1) {
    table.setColumnSelectionInterval(column, column);
    table.setRowSelectionInterval(row, row);
    }
    }
    }

  2. О! Спасибо, то что искал. Мне как раз нужно контекстное меню для таблицы, а так же текстовых полей.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: