JScrollPane добавляет JPanels вверху и сохраняет текущий вид прокрутки - PullRequest
2 голосов
/ 27 февраля 2011

У меня есть JScrollPane, который содержит вертикальную рамку. Я вставляю новые JPanel в верхней части окна. Если я использую полосу прокрутки для прокрутки вниз, я бы хотел, чтобы текущий вид оставался там, где я прокручивался. Например, если у меня есть 50 панелей в блоке и я использую полосу прокрутки для просмотра панели 20, я бы хотел, чтобы вид оставался на блоке 20, хотя другие блоки добавляются сверху. Кроме того, если я использую полосу прокрутки для прокрутки назад вверх, я бы хотел, чтобы представление отображало новые панели по мере их добавления. есть идеи как это сделать?

Кстати, нет необходимости использовать JScrollPane или Box. Пример кода просто для того, чтобы помочь объяснить, что я пытаюсь сделать.

Пример кода:

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

public class TestScrollPane extends JFrame {

    JScrollPane scrollPane;
    Box box;
    private static int panelCount = 0;

    public TestScrollPane() {
        setPreferredSize(new Dimension(200, 400));
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        scrollPane = new JScrollPane();
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.getVerticalScrollBar().setUnitIncrement(15);
        box = Box.createVerticalBox();
        scrollPane.getViewport().add(box);

        this.add(scrollPane);
        this.pack();
        this.setLocationRelativeTo(null);
        this.setVisible(true);

        Timer t = new Timer(500, new ActionListener() {

            public void actionPerformed(ActionEvent ae) {
                box.add(new TestPanel(), 0);
                scrollPane.validate();
            }
        });
        t.setRepeats(true);
        t.start();
    }

    public class TestPanel extends JPanel {

        int myId = panelCount++;

        public TestPanel() {
            this.setLayout(new GridBagLayout());
            this.setBorder(BorderFactory.createBevelBorder(1));
            JLabel label = new JLabel("" + myId);
            label.setHorizontalAlignment(JLabel.CENTER);
            label.setVerticalAlignment(JLabel.CENTER);

            this.setMaximumSize(new Dimension(100, 100));
            this.setPreferredSize(new Dimension(100, 100));

            this.add(label);
        }
    }

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

            public void run() {
                TestScrollPane testScrollPane = new TestScrollPane();
            }
        });
    }
}

EDIT: Вот так я и сменил код. Я чувствую себя несколько глупо, потому что не вижу очевидного. В любом случае, спасибо всем, кто помог.

            public void actionPerformed(ActionEvent ae) {
                Point view = scrollPane.getViewport().getViewPosition();
                TestPanel panel = new TestPanel();
                box.add(panel, 0);
                scrollPane.validate();
                if (view.y != 0) {
                    view.y += panel.getHeight();
                    scrollPane.getViewport().setViewPosition(view);
                }
            }

Кстати, я перевёл этот вопрос на http://www.coderanch.com/t/528829/GUI/java/JScrollPane-adding-JPanels-at-top#2398276 Просто к сведению тех, кого это может заинтересовать.

Ответы [ 2 ]

0 голосов
/ 27 февраля 2011

Что-то вроде:

    Timer t = new Timer(1000, new ActionListener() {

        public void actionPerformed(ActionEvent ae) {
            TestPanel panel = new TestPanel();
            box.add(panel, 0);
            JViewport vp = scrollPane.getViewport();
            Point p = vp.getViewPosition();
            p.y += panel.getPreferredSize().height;
            scrollPane.revalidate();
            vp.setViewPosition(p);
        }
    });
0 голосов
/ 27 февраля 2011

Вы можете получить границы компонента, который вы хотите сделать видимым (используя метод getBounds JComponent), и использовать его в качестве входных данных для метода scrollRectToVisible JViewPort.

...