Moving the visible area of a JScrollPane to a specific position

前端 未结 2 684
梦谈多话
梦谈多话 2020-12-22 08:23

I am trying to simulate the movement of a debugging cursor using java. I am having problem to get the viewable area of the JScrollPane to the right position.

Here is

2条回答
  •  [愿得一人]
    2020-12-22 09:06

    This is simple example, using a JList and JScrollPane's rowHeader support.

    The magic basically happens here...

    int index = list.getSelectedIndex();
    index++;
    if (index >= list.getModel().getSize()) {
        index = 0;
    }
    list.setSelectedIndex(index);
    Rectangle cellBounds = list.getCellBounds(index, index);
    list.scrollRectToVisible(cellBounds);
    

    Basically, we ask the view to calculate the Rectangle which is represented by the selected index and simply ask the component to scroll so that rectangle is visible

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Container;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Rectangle;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
    import javax.swing.DefaultListModel;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JList;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JViewport;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.event.ListSelectionEvent;
    import javax.swing.event.ListSelectionListener;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private JList list;
    
            public TestPane() {
                setLayout(new BorderLayout());
                DefaultListModel model = new DefaultListModel();
                try (BufferedReader br = new BufferedReader(new FileReader(new File("src/test/Test.java")))) {
                    String text = null;
                    while ((text = br.readLine()) != null) {
                        model.addElement(text);
                    }
                } catch (IOException exp) {
                    exp.printStackTrace();
                }
                list = new JList(model);
                list.setSelectedIndex(0);
                JScrollPane sp = new JScrollPane(list);
                sp.setRowHeaderView(new Header(list));
    
                add(sp);
    
                JButton next = new JButton("Next");
                next.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        int index = list.getSelectedIndex();
                        index++;
                        if (index >= list.getModel().getSize()) {
                            index = 0;
                        }
                        list.setSelectedIndex(index);
                        Rectangle cellBounds = list.getCellBounds(index, index);
                        list.scrollRectToVisible(cellBounds);
                    }
                });
    
                add(next, BorderLayout.SOUTH);
            }
    
        }
    
        protected class Header extends JPanel {
    
            private JList list;
    
            public Header(JList list) {
                this.list = list;
                list.addListSelectionListener(new ListSelectionListener() {
                    @Override
                    public void valueChanged(ListSelectionEvent e) {
                        repaint();
                    }
                });
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Container parent = list.getParent();
                if (parent instanceof JViewport) {
                    JViewport viewport = (JViewport) parent;
                    Graphics2D g2d = (Graphics2D) g.create();
                    int selectedRow = list.getSelectedIndex();
                    if (selectedRow >= 0) {
                        Rectangle cellBounds = list.getCellBounds(selectedRow, selectedRow);
                        cellBounds.y -= viewport.getViewPosition().y;
                        g2d.setColor(Color.RED);
                        g2d.fillRect(0, cellBounds.y, getWidth(), cellBounds.height);
                    }
                    g2d.dispose();
                }
            }
    
        }
    
    }
    

提交回复
热议问题