JScrollPane问题

时间:2011-11-29 23:45:58

标签: java swing jtable jscrollpane autoscroll

如果我向JTable添加JPanel,然后将JPanel添加到JScrollPane,只要JTable获得焦点,滚动窗格就会自动滚动到最底层,这很糟糕。

我有很多理由这样做,所以我希望有一些解决方案来阻止这种自动滚动。

OH,这里是踢球者......只有在通过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();
        }
    });
}
}

5 个答案:

答案 0 :(得分:2)

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

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

  2. 不要设置框架的首选尺寸,而是使用表格上的setPreferredScrollableViewportSize()

  3. 如果不必要的滚动是由于更新了表格的模型,请参阅example如何暂时停止滚动。

  4. 赞赏使用event dispatch thread

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

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

答案 1 :(得分:1)

以防万一有人关心,问题是应用程序的eclipse启动程序和JNLP启动程序有一个不同的KeyboardFocusManager,而JNLP有一些怪癖。

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

谢谢大家。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

感谢大家的投入!

答案 4 :(得分:-1)

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

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

看看是否将焦点放在JTable的顶部?

编辑:我之前没有这样做,所以不确定开始和结束需要什么,尝试0,0或0,1?