JScrollPane 问题

发布于 2024-12-19 04:57:01 字数 1724 浏览 0 评论 0原文

如果我将 JTable 添加到 JPanel,然后将该 JPanel 添加到 JScrollPane,每当该 JTable 获得焦点,滚动窗格自动滚动到最底部,这很糟糕。

我这样做有很多原因,所以我希望有某种解决方案来阻止这种自动滚动。

哦,更糟糕的是……它似乎只在通过 JNLP/WebStart 运行应用程序时才会发生,而在 Eclipse 中则不会,这更令人沮丧。

这是一个简单的示例,如果您通过 JLNP 启动,单击文本字段,单击表格,然后它会自动滚动到底部:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

剧终人散尽 2024-12-26 04:57:01

我无法重现该问题,但我可以提供一些观察结果:

  1. 框架的 add() 方法自动将组件转发到 contentPane

  2. 不要设置框架的首选大小,而是在桌子上使用 setPreferredScrollableViewportSize()

  3. 如果不必要的滚动是由于更新表格模型造成的,请参阅此示例,了解如何暂时暂停滚动。< /p>

  4. 感谢使用事件调度线程。< /p>

  5. 附录:具有(默认)FlowLayout 的嵌套 panel 是多余的。

在此处输入图像描述

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

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();
            }
        });
    }
}
放肆 2024-12-26 04:57:01

万一有人关心,问题是应用程序的 eclipse 启动器和 JNLP 启动器有不同的 KeyboardFocusManager,并且 JNLP 有一些怪癖。

我不知道 JLNP 端添加了自定义 KeyboardFocusManager,但至少它解释了一些事情。

谢谢大家。

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.

小清晰的声音 2024-12-26 04:57:01

当我将 JTables 放置在中间 JPanel 上而不是直接将它们放置为 JScrollPane 的视口时,我在 JTables 上遇到了自动滚动问题。在这些情况下,删除无关的面板并将表格直接放在滚动窗格上已经解决了我的问题。

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.

卷耳 2024-12-26 04:57:01

好吧,我最终不得不重新设计将对象添加到滚动窗格的方式以避免这个问题。具体来说,如果表格比视口高度高,那么我只需将表格直接添加到滚动窗格,然后更改我使用中间面板的方式。

感谢大家的意见!

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!

埖埖迣鎅 2024-12-26 04:57:01

根据this,更改JTable<的选择/code> 您需要更改选择模型。尝试使用以下命令将所选项目设置为第一个项目。

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

看看这是否会将焦点移到 JTable 的顶部?

编辑:我以前没有这样做过,所以不确定开始和结束需要是什么,尝试 0,0 或 0,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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文