У меня есть 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(); } }); } }
РЕДАКТИРОВАТЬ: Вот как я закончил изменение кода. Я чувствую себя глупо из-за того, что не вижу очевидного. В любом случае, спасибо тем, кто помог.
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 К вашему сведению.