How to determine which lines are visible in scrollable JTextArea?

后端 未结 2 2107
耶瑟儿~
耶瑟儿~ 2020-12-11 02:42

How to determine number of the first visible line and the number of lines currently visible in scrollable JTextArea (JTextArea inside a JScrollPane)?

2条回答
  •  执笔经年
    2020-12-11 03:34

    Okay, this is my take on the problem... (Nice question though)

    enter image description here

    There is a small consideration you need to have with this solution. It will return partially displayed lines.

    public class TestTextArea {
    
        public static void main(String[] args) {
            new TestTextArea();
        }
    
        public TestTextArea() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException ex) {
                    } catch (InstantiationException ex) {
                    } catch (IllegalAccessException ex) {
                    } catch (UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestTextAreaPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestTextAreaPane extends JPanel {
    
            private JTextArea textArea;
            private JTextArea viewText;
    
            public TestTextAreaPane() {
                setLayout(new GridLayout(2, 1));
                textArea = new JTextArea(20, 100);
                textArea.setWrapStyleWord(true);
                textArea.setLineWrap(true);
                textArea.setText(loadText());
    
                viewText = new JTextArea(20, 100);
                viewText.setWrapStyleWord(false);
                viewText.setLineWrap(false);
                viewText.setEditable(false);
    
                JScrollPane scrollPane = new JScrollPane(textArea);
                add(scrollPane);
    
                add(viewText);
    
                scrollPane.getViewport().addChangeListener(new ChangeListener() {
                    @Override
                    public void stateChanged(ChangeEvent e) {
                        if (textArea.getText().length() > 0) {
                            JViewport viewport = (JViewport) e.getSource();
                            Rectangle viewRect = viewport.getViewRect();
    
                            Point p = viewRect.getLocation();
                            int startIndex = textArea.viewToModel(p);
    
                            p.x += viewRect.width;
                            p.y += viewRect.height;
                            int endIndex = textArea.viewToModel(p);
    
                            if (endIndex - startIndex >= 0) {
    
                                try {
                                    viewText.setText(textArea.getText(startIndex, (endIndex - startIndex)));
                                } catch (BadLocationException ex) {
                                    ex.printStackTrace();
                                    viewText.setText(ex.getMessage());
                                }
    
                            }
    
                        }
    
                    }
                });
    
            }
    
            protected String loadText() {
                String text = null;
                File file = new File("src/testtextarea/TestTextArea.java");
    
                BufferedReader br = null;
                try {
                    br = new BufferedReader(new FileReader(file));
                    StringBuilder sb = new StringBuilder(128);
                    String read = null;
                    while ((read = br.readLine()) != null) {
                        sb.append(read).append("\n");
                    }
    
                    text = sb.toString();
                } catch (IOException exp) {
                    exp.printStackTrace();
                } finally {
                    try {
                        br.close();
                    } catch (Exception e) {
                    }
                }
    
                return text;
            }
        }
    }
    

提交回复
热议问题