views:

405

answers:

3

I am working inside of a quite complex eclipse based application, and having a problem with a JTable based custom component inside of a JSplitPane. The part of the application that I actually have access to is a panel, within a tab, within a panel, within the actual application, so there are a lot of things that can go wrong.

The specific problem that I'm having right now is that the table component is selecting the wrong cell when I click on it. If I select a cell in row 0, column 0, the cell that actually gets selected is at row 2, column 0, which is about 20 pixels below the actual click. This only happens if the table is in a JSplitPane though: if I just add the table itself to a panel, cell selection is correct.

What it seems like to me is that because the table is in a JSplitPane, the boundaries of the table (or maybe the viewport of the scroll pane containing the table?) are off by about 20 pixels somewhere. Another problem that I had which can back this theory up, is that scrolling the table caused repaints above the table: so for example, as I scrolled down, instead of the table scrolling, it actually moved upwards (painting over the components above the table) about 20 pixels before scrolling. I was able to workaround this problem by adding

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

to the scrollpane that contained the table.

Because of all the custom components involved, I can't actually get a small app that shows the problem, but I have the next best thing, which is an app that shows the layout that I have (of course, it doesn't actually have the same problems). Any ideas on what might be causing the problem?

//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();
                    }
        });
    }
}
A: 

Because of all the custom components involved, I can't actually get a small app that shows the problem, but I have the next best thing, which is an app that shows the layout that I have (of course, it doesn't actually have the same problems).

I was about to tell you the posted code workd just fine, and the I read this.

Anyway, it seems the problem lies in all the custom components you added to the mix. For JTable and JSplitPane work fine alone.

What I would do is to remove components one by one until it works ( probably I will work when the code is similar to the one posted and there is nothing else there )

Or you can go the opposite way which is easier. Start with your sample code and then add more and more components until it fail.

You can take this opportunity to refactor and clean your code and move unneeded components. And even ( why not ) add test cases in the process.

Good luck.

OscarRyz
I've been working on doing that - the only problem is that this isn't my code, I'm working within another system, and don't have access to everything that I need (to even figure out what's going on in this custom component I've had to use a decompiler). I've gotten it to the split pane - everything works fine without it, but once the custom table is in the split pane, its positioning is off.
Matt McMinn
A: 

Have you tries running it on a different box to check if its hardware related.

May be related to this bug

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

objects
I did see that bug, and I've tried reproducing the bug on the machines that I've tried this on, but it doesn't look like that bug is the culprit here. I have tried different machines, and I get the same effect on each.
Matt McMinn
A: 

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.

Matt McMinn