JScrollPane 问题
如果我将 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我无法重现该问题,但我可以提供一些观察结果:
框架的
add()
方法自动将组件转发到contentPane
。不要设置框架的首选大小,而是在桌子上使用
setPreferredScrollableViewportSize()
。如果不必要的滚动是由于更新表格模型造成的,请参阅此示例,了解如何暂时暂停滚动。< /p>
感谢使用事件调度线程。< /p>
附录:具有(默认)
FlowLayout
的嵌套panel
是多余的。I am unable to reproduce the problem, but I can offer a few observations:
The frame's
add()
method forwards the component to thecontentPane
automatically.Instead of setting the frame's preferred size, use
setPreferredScrollableViewportSize()
on the table.If the unwanted scrolling is due to updating the table's model, see this example of how to temporarily suspend scrolling.
Kudos for using the event dispatch thread.
Addendum: The nested
panel
having a (default)FlowLayout
is superfluous.万一有人关心,问题是应用程序的 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.
当我将 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.
好吧,我最终不得不重新设计将对象添加到滚动窗格的方式以避免这个问题。具体来说,如果表格比视口高度高,那么我只需将表格直接添加到滚动窗格,然后更改我使用中间面板的方式。
感谢大家的意见!
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!
根据this,更改
JTable<的选择/code> 您需要更改选择模型。尝试使用以下命令将所选项目设置为第一个项目。
看看这是否会将焦点移到
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.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?