JTable выбирает неправильную ячейку при клике - PullRequest
0 голосов
/ 04 июня 2009

Я работаю внутри довольно сложного приложения, основанного на затмении, и имею проблему с пользовательским компонентом на основе JTable внутри JSplitPane. Часть приложения, к которой у меня фактически есть доступ, - это панель, вкладка, панель, внутри самого приложения, поэтому есть много вещей, которые могут пойти не так.

Конкретная проблема, с которой я сейчас сталкиваюсь, заключается в том, что компонент таблицы выбирает неправильную ячейку, когда я нажимаю на нее. Если я выберу ячейку в строке 0, столбце 0, то выбранная ячейка будет находиться в строке 2, столбце 0, что примерно на 20 пикселей ниже фактического щелчка. Это происходит только в том случае, если таблица находится в JSplitPane: если я просто добавлю саму таблицу на панель, выбор ячейки будет правильным.

Что мне кажется, так это то, что, поскольку таблица находится в JSplitPane, границы таблицы (или, возможно, область просмотра панели прокрутки, содержащей таблицу?) Где-то смещены примерно на 20 пикселей. Еще одна проблема, которая может подтвердить эту теорию, состоит в том, что прокрутка таблицы вызывала перерисовку над таблицей: так, например, когда я прокручивал вниз, вместо прокрутки таблицы, он фактически двигался вверх (закрашивая компоненты над таблицей ) около 20 пикселей перед прокруткой. Я смог обойти эту проблему, добавив

jscrollpane.getViewport().setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE);

к области прокрутки, в которой находилась таблица.

Из-за всех задействованных пользовательских компонентов я не могу получить небольшое приложение, которое показывает проблему, но у меня есть следующая лучшая вещь, это приложение, которое показывает мой макет (конечно, это не так. на самом деле нет таких же проблем). Любые идеи о том, что может быть причиной проблемы?

//Test class showing layout of table/splitpane
import javax.swing.*;
import java.awt.*;

public class SplitTest
{
    private static JFrame frame;

    private static JPanel buildTable()
    {
        JPanel tblPanel = new JPanel();
        tblPanel.setLayout(new BorderLayout());

        String[] cols = new String[]{"one", "two", "three", "four", "five", "six", "seven"};
        Object[][] data = new Object[30][7];
        for(int x = 0;x < data.length;x++)
            for(int y = 0;y < data[x].length;y++)
                data[x][y] = x + ", " + y;

        JTable tbl = new JTable(data, cols);

        JScrollPane scrollPane = new JScrollPane(tbl);
        tblPanel.add(scrollPane, BorderLayout.CENTER);

        return tblPanel;
    }

    private static JPanel buildTab()
    {
        JPanel pnl = new JPanel();
        pnl.setLayout(new BorderLayout());

        JPanel menuPnl = new JPanel();
        menuPnl.setLayout(new FlowLayout(FlowLayout.LEFT));
        menuPnl.add(new JLabel("label"));
        menuPnl.add(new JComboBox(new String[]{"one", "two"}));
        menuPnl.add(new JButton("Button"));
        pnl.add(menuPnl, BorderLayout.NORTH);

        JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        splitPane.setLeftComponent(buildTable());
        JPanel bottomPnl = new JPanel();
        bottomPnl.setPreferredSize(new Dimension(800, 200));
        bottomPnl.setBackground(Color.RED);
        splitPane.setRightComponent(bottomPnl);
        splitPane.setDividerLocation(.5);
        pnl.add(splitPane, BorderLayout.CENTER);

        return pnl;
    }

    private static JTabbedPane buildGUI()
    {
        JTabbedPane topLevelTabbedFrame = new JTabbedPane();
        topLevelTabbedFrame.addTab("Tab 1", buildTab());
        topLevelTabbedFrame.addTab("Tab 2", new JPanel());
        topLevelTabbedFrame.addTab("Tab 3", new JPanel());

        return topLevelTabbedFrame;
    }

    private static void createAndShowGUI()
    {
        frame = new JFrame("Split Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.getContentPane().add(buildGUI(), BorderLayout.CENTER);
//        frame.setSize(new Dimension(800, 600));

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) throws Exception
    {
        SwingUtilities.invokeLater(new Runnable()
                {
                    public void run()
                    {
                        createAndShowGUI();
                    }
        });
    }
}

Ответы [ 3 ]

0 голосов
/ 05 июня 2009

Вы пытаетесь запустить его в другом окне, чтобы проверить, связано ли его аппаратное обеспечение.

Может быть связано с этой ошибкой

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4763448

0 голосов
/ 27 июля 2009

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

0 голосов
/ 04 июня 2009

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

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

В любом случае, похоже, проблема заключается во всех пользовательских компонентах, которые вы добавили в микс. Для JTable и JSplitPane отлично работают в одиночку.

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

Или вы можете пойти противоположным путем, который легче. Начните с примера кода, а затем добавляйте все больше и больше компонентов, пока не произойдет сбой.

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

Удачи.

...