2

If I add a JTable to a JPanel and then add that JPanel to a JScrollPane, whenever that JTable gains focus, the scroll pane automatically scrolls to the very bottom, which is bad.

I have many reasons for doing it like this, so I'm hoping for some kind solution to stop this auto-scrolling.

OH, and here's the kicker...It only seems to happen when running the app through JNLP/WebStart, and it does NOT do it in Eclipse, which is even more frustrating.

Here's a quick example that if you launch through JLNP, click the text field, click the table, then it auto-scrolls to the bottom:

import java.awt.*;
import javax.swing.*;

public class ScrollDemo extends JPanel{

private static final long serialVersionUID = 1L;

public ScrollDemo() 
{
    this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    JTable table = new JTable(100,6);
    this.add(new JTextField());
    JPanel panel = new JPanel();
    panel.add(table);
    JScrollPane scroll = new JScrollPane(panel);
    this.add(scroll);
}

/**
 * Create the GUI and show it. For thread safety, this method should be
 * invoked from the event-dispatching thread.
 */
private static void createAndShowGUI() {
    // Create and set up the window.
    JFrame frame = new JFrame("ScrollDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    // Create and set up the content pane.
    JComponent newContentPane = new ScrollDemo();
    newContentPane.setOpaque(true); // content panes must be opaque     
    frame.setContentPane(newContentPane);
    frame.setPreferredSize(new Dimension(500, 500));

    // Display the window.
    frame.pack();
    frame.setVisible(true);
}

public static void main(String[] args) {
    // Schedule a job for the event-dispatching thread:
    // creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });
}
}
Sastrija
  • 3,284
  • 6
  • 47
  • 64
PAULUS
  • 212
  • 3
  • 10
  • 1
    *"Well, thanks for looking!"* No worries. ..Did you have a question? Do you have code, a JNLP file etc.? – Andrew Thompson Nov 30 '11 at 00:14
  • My guess is that it is flicking to the 'selected item' of the table, which is the last entry it puts in, unfortunately after a quick look I can't find a way to set the selected entry back to the first one, do you know a way to changed the selected entry? – dann.dev Nov 30 '11 at 02:10

5 Answers5

2

I am unable to reproduce the problem, but I can offer a few observations:

  1. The frame's add() method forwards the component to the contentPane automatically.

  2. Instead of setting the frame's preferred size, use setPreferredScrollableViewportSize() on the table.

  3. If the unwanted scrolling is due to updating the table's model, see this example of how to temporarily suspend scrolling.

  4. Kudos for using the event dispatch thread.

  5. Addendum: The nested panel having a (default) FlowLayout is superfluous.

enter image description here

import java.awt.*;
import javax.swing.*;

/** @see https://stackoverflow.com/questions/8319388 */
public class ScrollDemo extends JPanel {

    public ScrollDemo() {
        this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        JTable table = new JTable(100, 6);
        table.setPreferredScrollableViewportSize(new Dimension(320, 240));
        this.add(new JTextField());
        this.add(new JScrollPane(table));
    }

    private static void createAndShowGUI() {
        // Create and set up the window.
        JFrame frame = new JFrame("ScrollDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Create and set up the content pane.
        frame.add(new ScrollDemo());
        frame.pack();

        // Display the window.
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • as you know, this setup is different from the OPs :-) – kleopatra Nov 30 '11 at 09:07
  • @kleopatra: Excellent point. I tried to list all the variances, as I was unsure which were intended and which weren't. Like Andrew, I'm curious about the `jnlp` aspect of the problem. – trashgod Nov 30 '11 at 21:42
1

Just in case anyone cares, the problem was that the eclipse launcher and the JNLP launcher for the app had a different KeyboardFocusManager, and the JNLP one had some quirks.

I was unaware of a custom KeyboardFocusManager being added on the JLNP side, but at least it explains things.

Thanks everyone.

PAULUS
  • 212
  • 3
  • 10
0

I have had auto scrolling issue on JTables when I place them on an intermediary JPanel instead of placing them directly as the JScrollPane's viewport. In those cases, removing the extraneous panel and putting the table directly on the scrollpane has solved my issues.

Colby
  • 459
  • 3
  • 9
  • Right, I noticed that too, but like I said, there are many reasons for me wanting to have that intermediary JPanel in there. I'm glad I'm not the only person that's noticed this :) Now we just need a solution that doesn't involve me reworking my table/scroll pane layout... – PAULUS Nov 30 '11 at 21:28
0

Well, I ended up having to rework how I was adding my objects to the scroll pane to avoid this issue. Specifically, if the table is going to be taller than the viewport height, then I just have to add the table directly to the scrollpane then change how I was using the intermediary panel.

Thanks to everyone for your input!

PAULUS
  • 212
  • 3
  • 10
-1

According to this, to change the selection for your JTable you need to change the selection model. Try using the following to set the selected item to the very first one.

ListSelectionModel selectionModel = table.getSelectionModel();
selectionModel.setSelectionInterval(start, end);

See if that gives the focus to the top of the JTable?

EDIT: I have not done this before, so not sure what start and end will need to be, try 0,0 or 0,1 maybe?

dann.dev
  • 2,406
  • 3
  • 20
  • 32
  • -1 for playing guessing games. _try 0,0 or 0,1 maybe_ Maybe you could have tried it? That's what example code is good for ;-) – kleopatra Nov 30 '11 at 08:59