我在一个非常复杂的基于 Eclipse 的应用程序中工作,并且在 JSplitPane 中使用基于 JTable 的自定义组件存在问题。我实际上可以访问的应用程序部分是面板、选项卡内、面板内、实际应用程序内,所以有很多事情可能会出错。
我现在遇到的具体问题是,当我单击表格组件时,它选择了错误的单元格。如果我在第 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();
}
});
}
}