【问题标题】:Go to the last scrolled position java swing JScrollPane转到最后滚动的位置 java swing JScrollPane
【发布时间】:2014-10-10 02:07:17
【问题描述】:

我有一个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);


        }
    }

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

【问题讨论】:

    标签: java image swing jscrollpane imageicon


    【解决方案1】:

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

    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);
        }
    });
    

    【讨论】:

    • 这似乎不起作用。我有滚动的点,但setViewPosition 没有设置位置。
    • @rivu,在 Windows 7 上使用 JDK7 对我来说效果很好。发布您的 SSCCE 来证明问题。唯一的其他建议是尝试将 setViewPosition(...) 语句包装在 SwingUtilities.invokeLater() 中,以确保在使用新组件重新验证滚动窗格后执行代码。
    • 可能是 flush() 的问题,这是 JLabel - IMageIcon - (资源慢)文件较大的常见问题
    • @rivu,正如 mKorbel 所建议的那样,在执行导致问题的代码时,看起来文件可能没有被完全读取。我将代码更改为使用ContainerListener
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-24
      • 2011-02-09
      • 2015-10-01
      • 2016-09-30
      • 1970-01-01
      相关资源
      最近更新 更多