Настройте JTable так, чтобы он запускал сортировку, только если у MouseEvent нет модификаторов - PullRequest
0 голосов
/ 09 января 2019

JTable.setAutoCreateRowSorter создает TableRowSorter, который работает очень хорошо *, за исключением одного: он запускает сортировку, даже если на MouseEvent есть модификаторы. Я узнал об этом только после того, как добавил Роба TableColumnManager . Когда вы щелкнете мета (control + button1 в macOS) на JTableHeader, вы увидите, что сортировка происходит непосредственно перед появлением всплывающего окна выбора столбца. Я не хочу, чтобы сортировка запускалась вообще, если есть какие-либо модификаторы.

Есть ли простой способ запустить огонь MouseAdapter, только если MouseEvent не имеет модификаторов (в частности, мета-модификатора)? Я не хочу помещать средство выбора столбцов в другое место в приложении, где это не будет так очевидно.

Ниже приведен мой пример MCV (извините, что не опубликовал класс Роба, см. Ссылку выше). Вы можете протестировать поведение модификатора мыши (то есть, доказать, что модификаторы строк игнорируют модификаторы), не обращаясь к TableColumnManager.

import javax.swing.*;
public class SorterChooser {
    private static void createAndShowGUI() {
        JFrame frame = new JFrame("SorterChooser");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Object[][] data = { {"a", "1"}, {"b", "3"}, {"c", "2"}, {"d", "4"} };
        String[] colnames = { "c1", "c2" };
        JTable tab = new JTable(data, colnames);
        JScrollPane sp = new JScrollPane(tab);
        tab.setAutoCreateRowSorter(true);
        new TableColumnManager(tab, true); // comment this out to demo mouse behavior
        frame.getContentPane().add(sp);
        frame.pack();
        frame.setVisible(true);
    }
    public static void main (String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
  • Хорошо, я имею в виду, что он обрабатывает изменения модели и многие другие вещи, которые мне нужны (например, некоторые столбцы не могут быть отсортированы).

1 Ответ

0 голосов
/ 10 января 2019

Я продлил BaseTableHeaderUI. Как я узнал, что расширение это то, что мне нужно сделать, это сложная часть:

  1. добавлено RowSorterListener к JTable.getRowSorter
  2. напечатал стек вызовов, когда sorterChanged был вызван
  3. стек вызовов возлагает вину на javax.swing.plaf.basic.BasicTableHeaderUI за событие сортировки
  4. нашел исходный код для BasicTableHeaderUI
  5. сортировка выполняется только по BasicTableHeaderUI.MouseInputHandler
  6. Extended BasicTableHeaderUI.MouseInputHandler для вызова его супер, только если нет модификаторов
  7. установить JTableHeaderUI моего стола в новый класс

Вот модифицированный SorterChooser.java:

import javax.swing.*;
public class SorterChooser {
    private static void createAndShowGUI() {
        JFrame frame = new JFrame("SorterChooser");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Object[][] data = { {"a", "1"}, {"b", "3"}, {"c", "2"}, {"d", "4"} };
        String[] colnames = { "c1", "c2" };
        JTable tab = new JTable(data, colnames);
        tab.getTableHeader().setUI(new SorterChooserTableHeaderUI());  // new code
        JScrollPane sp = new JScrollPane(tab);

        tab.setAutoCreateRowSorter(true);
        new TableColumnManager(tab, true);

        frame.getContentPane().add(sp);
        frame.pack();
        frame.setVisible(true);
    }
    public static void main (String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

А вот расширенный BasicTableHeaderUI.java:

import java.awt.event.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.plaf.basic.BasicTableHeaderUI;

public class SorterChooserTableHeaderUI extends BasicTableHeaderUI {

    public class MouseInputHandler extends BasicTableHeaderUI.MouseInputHandler {
        public void mouseClicked (MouseEvent ev) {
            if (ev.getModifiersEx() == 0)
                super.mouseClicked(ev);
        }
    }

    @Override
    protected MouseInputListener createMouseInputListener () {
        return new MouseInputHandler();
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...