【问题标题】:How to set scroll to the top - JPanel that has multiple JTextareas inside Jscrollpane如何设置滚动到顶部-在 Jscrollpane 中有多个 JTextarea 的 JPanel
【发布时间】:2017-08-15 02:52:49
【问题描述】:

我在 JScrollPane 中有一个 JPanel。 JPanel 垂直包含多个 JTextArea。

我喜欢在页面刷新时将滚动窗格的滚动保持在顶部。 目前,滚动总是从底部开始。

这是我当前的代码,它不起作用..

    panel.invalidate();
    panel.revalidate();
    panel.repaint();
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            ((JPanel) panel).setLocation(new Point(0, 0));
        }
    });

我也尝试将下面的代码添加到滚动窗格,但它不起作用..

scrollPanel.getViewport().setViewPosition( new Point(0, 0) );

我研究了其他 stackoverflow 问题,他们在 Jscrollpane 中使用了 Jtextarea(他们使用 setCaretPosition(0) 解决了这个问题,但是我不能对面板使用相同的功能)。就我而言,有一个额外的层。

我该如何解决这个..?

编辑**

根据 Pavlo Viazovskyy 的建议,我也在下面尝试过,但它仍然不适合我.. :(

    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            scrollPane.getVerticalScrollBar().setValue(0);
        }
    });

【问题讨论】:

  • 如果你将在 JScrollPane 上使用 setCaretPosition(0) 来保存你的 JPanel,它应该可以解决问题。
  • 感谢您的意见。 JScrollPane 没有该方法; setCaretPosition().. 有没有办法在 JScrollPane 上使用它?
  • 知道了。希望this post能帮到你。
  • @PavloViazovskyy 我从你分享的帖子中得到了一个新想法,但它仍然不适合我。我更新了这个问题只是为了展示我迄今为止尝试过的方法。谢谢。
  • 设置视口位置应该可以。确保在 SwingUtilities.invokeLater() 中调用代码。如果您需要更多帮助,请发布适当的 minimal reproducible example 来说明问题。

标签: java swing user-interface jpanel jscrollpane


【解决方案1】:

非常感谢所有 cmets。 抱歉,我没有在问题中给出一个完整的正确示例,因为涉及到太多不同的类..

在我的例子中,Textareas inside Panel inside ScrollPane,我在invokelater方法中使用setViewPosition方法滚动到顶部,默认滚动到顶部。

SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        scrollPane.getViewport().setViewPosition( new Point(0, 0) );
    }
});

【讨论】:

  • 是的!为我解决了。后来的调用是使它起作用的原因:)
【解决方案2】:

当您无法直接访问JScrollPane 时,您可以简单地使用JComponent#scrollRectToVisible

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class ScrollTest {

    public static void main(String[] args) {
        new ScrollTest();
    }

    public ScrollTest() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Test");
                frame.add(new JScrollPane(new BigPane()));
                frame.setSize(200, 200);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class BigPane extends JPanel {

        public BigPane() {
            setLayout(new BorderLayout());
            JButton scroll = new JButton("Scroll to top");
            add(scroll, BorderLayout.SOUTH);
            scroll.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    scrollRectToVisible(new Rectangle(0, 0, 1, 1));
                }
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

    }

}

是的,您可以遍历组件层次结构,直到找到 JViewport,但是这种方法可以为您解决问题。

请记住,Rectangle 是相对于调用该方法的组件而言的,所以如果我改用JButton,它会尝试使JButton 可见,而不是面板

【讨论】:

  • panel.getBounds && JComponent#scrollRectToVisible :-)
猜你喜欢
  • 1970-01-01
  • 2023-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-06
  • 2011-07-05
  • 2016-05-28
  • 2011-12-10
相关资源
最近更新 更多