Я работаю внутри довольно сложного приложения, основанного на затмении, и имею проблему с пользовательским компонентом на основе 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();
}
});
}
}