Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JTable在单击时选择了错误的单元格_Java_Swing_Scroll_Jtable - Fatal编程技术网

Java JTable在单击时选择了错误的单元格

Java JTable在单击时选择了错误的单元格,java,swing,scroll,jtable,Java,Swing,Scroll,Jtable,我在一个非常复杂的基于eclipse的应用程序中工作,在JSplitPane中有一个基于JTable的自定义组件的问题。我实际上可以访问的应用程序部分是一个面板,在一个选项卡中,在一个面板中,在实际的应用程序中,所以有很多事情可能会出错 我现在遇到的具体问题是,当我单击表格组件时,它选择了错误的单元格。如果我在第0行第0列中选择一个单元格,那么实际选中的单元格位于第2行第0列,比实际点击低20像素。但是,只有当表格位于JSplitPane中时才会发生这种情况:如果我只是将表格本身添加到面板中,单

我在一个非常复杂的基于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();
                    }
        });
    }
}
//显示表/拆分窗格布局的测试类
导入javax.swing.*;
导入java.awt.*;
公共类拆分测试
{
私有静态JFrame;
私有静态JPanel buildTable()
{
JPanel tblPanel=新的JPanel();
setLayout(新的BorderLayout());
字符串[]cols=新字符串[]{“一”、“二”、“三”、“四”、“五”、“六”、“七”};
对象[][]数据=新对象[30][7];
对于(int x=0;x
由于涉及到所有自定义组件,我实际上无法得到一个显示问题的小应用程序,但我有一个次好的东西,那就是一个显示我的布局的应用程序(当然,它实际上没有相同的问题)

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

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

我要做的是一个接一个地删除组件,直到它工作为止(可能我会在代码与发布的代码相似且没有其他代码时工作)

或者你可以走另一条更容易的路。从示例代码开始,然后添加越来越多的组件,直到失败

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


祝您好运。

您是否尝试在其他框中运行它,以检查它是否与硬件相关

可能与此错误有关


事实证明,问题在于组件初始化和添加到拆分窗格的顺序。因此,最终的解决方案是延迟将表添加到拆分窗格,直到拆分窗格实际添加到面板之后,而不是在将拆分窗格添加到面板之前将表添加到拆分窗格。做这个小小的改动就解决了这个问题。

我一直在做这件事——唯一的问题是,这不是我的代码,我在另一个系统中工作,无法访问我需要的所有内容(为了弄清楚这个自定义组件中发生了什么,我不得不使用反编译器)。我已经把它放到了拆分窗格中-一切正常