转到最后一个滚动位置java swing JScrollPane

转到最后一个滚动位置java swing JScrollPane,java,image,swing,jscrollpane,imageicon,Java,Image,Swing,Jscrollpane,Imageicon,我有一个JScrollPane显示图像。相关的代码行是 ImageIcon ii = new ImageIcon(in); scrollPane.setViewportView(new JLabel(ii)); 当点击一个按钮时调用此代码,它基本上加载了相同的图像,只需稍作修改 假设加载了一个图像,用户滚动(水平和垂直)到某个位置。下次单击按钮并加载新图像时,滚动窗格将忘记以前滚动的位置,并重新启动所有内容 我想查看上次滚动位置的图像,直到发生另一次滚动。可能吗 编辑 代码如下: impor

我有一个
JScrollPane
显示图像。相关的代码行是

ImageIcon ii = new ImageIcon(in);
scrollPane.setViewportView(new JLabel(ii)); 
当点击一个按钮时调用此代码,它基本上加载了相同的图像,只需稍作修改

假设加载了一个图像,用户滚动(水平和垂直)到某个位置。下次单击按钮并加载新图像时,滚动窗格将忘记以前滚动的位置,并重新启动所有内容

我想查看上次滚动位置的图像,直到发生另一次滚动。可能吗

编辑

代码如下:

import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class TestScrollPane extends JFrame {
    /**
     * 
     */
    static BufferedImage in = null;
    private JPanel contentPane;
    static String imageLoc=null;
    static Point p= new Point(2,2);
    /**
     * Launch the application.
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        EventQueue.invokeLater(new Runnable() {

            public void run() {
                try {
                    TestScrollPane frame = new TestScrollPane();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */

    private String getAnewImage() throws IOException {
        return "/home/abc/test.jpg"; //change this
    }
    public TestScrollPane() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(0, 0, 1300, 1000);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        //all declarations go here
        final JScrollPane scrollPane = new JScrollPane();
        final JButton btnInput = new JButton("Test");
        btnInput.setVerticalAlignment(SwingConstants.TOP);
        btnInput.setFont(new Font("Dialog", Font.BOLD, 12));
        btnInput.setHorizontalAlignment(SwingConstants.LEFT);
        final JButton btnStart = new JButton("start");
        final JViewport jv= scrollPane.getViewport();

        // all dimensions go here
        scrollPane.setBounds(2, 2, 1150, 950);
        btnInput.setBounds(1160, 100, 90, 50);
        btnStart.setBounds(1160, 300, 90, 25);

        contentPane.add(scrollPane);


        jv.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                p=jv.getViewPosition();
            }
        });



        btnInput.addActionListener(new ActionListener()  {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    in = ImageIO.read(new File(imageLoc));
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                ImageIcon ii = new ImageIcon(in);
                System.out.println("setting viewport to "+p);
                scrollPane.setViewportView(new JLabel(ii));
                scrollPane.getViewport().setViewPosition(p);
            }
        });

        contentPane.add(btnInput);


        btnStart.addActionListener(new ActionListener()  {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    imageLoc=getAnewImage();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                if (imageLoc==null)
                    return;
                else {

                    try {
                        in = ImageIO.read(new File(imageLoc));
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                    ImageIcon ii = new ImageIcon(in);
                    scrollPane.setViewportView(new JLabel(ii));
                }

            }


        });


        contentPane.add(btnStart);


        }
    }

这是我用于测试的图像::<代码>开始按钮加载新图像。在我滚动并单击“输入”按钮后,会加载另一个图像,但滚动窗格会返回到左上角(原始位置)

保存视口的位置,然后恢复其位置:

Point p = scrollPane.getViewport().getViewPostion();
scrollPane.setViewportView(new JLabel(ii));
scrollPane.getViewport.setViewPosition( p );
编辑:

我将您的SSCCE更改为使用
ContainerListener
重置视口视图位置:

jv.addContainerListener( new ContainerAdapter()
{
    @Override
    public void componentAdded(ContainerEvent e)
    {
        scrollPane.getViewport().setViewPosition(p);
    }
});

为标签创建一个
displayImage
。加载新图像时,将其绘制到显示图像并重新绘制标签。

这似乎不起作用。我有滚动到的点,但是
setViewPosition
没有设置位置。@rivu,在Windows7上使用JDK7对我来说很好。张贴你的文章,说明问题所在。另一个建议是尝试将setViewPosition(…)语句包装在SwingUtilities.invokeLater()中,以确保在使用新组件重新验证滚动窗格后执行代码。flush()可能会出现问题,这是具有较大files@rivu,正如mKorbel所建议的,当代码被执行时,文件可能没有被完全读取,这导致了一个问题。我将代码更改为使用
ContainerListener