0

我在一个非常复杂的基于 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();
                    }
        });
    }
}
4

3 回答 3

0

由于涉及到所有自定义组件,我实际上无法获得一个显示问题的小应用程序,但我有下一个最好的东西,它是一个显示我拥有的布局的应用程序(当然,它实际上并没有有同样的问题)。

我正要告诉你发布的代码工作得很好,我读了这个。

无论如何,问题似乎在于您添加到组合中的所有自定义组件。对于 JTable 和 JSplitPane 单独工作正常。

我要做的是一个一个地删除组件,直到它起作用(当代码与发布的代码相似并且没有其他内容时,我可能会起作用)

或者你可以走相反的路,这样更容易。从您的示例代码开始,然后添加越来越多的组件,直到它失败。

您可以借此机会重构和清理代码并移动不需要的组件。甚至(为什么不)在过程中添加测试用例。

祝你好运。

于 2009-06-04T18:02:25.670 回答
0

您是否尝试在不同的盒子上运行它以检查其硬件是否相关。

可能与此错误有关

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

于 2009-06-05T00:14:24.433 回答
0

As it turns out, the problem was with the order that the components were initialized and added to the split pane. So the eventual fix was to delay adding the table to the split pane until after the split pane was actually added to the panel, rather than adding the table to the split pane before adding the split pane to the panel. Making that small change fixed the issue.

于 2009-07-27T18:42:38.037 回答