JTextArea в JScrollPane, просмотр перевода координат - PullRequest
0 голосов
/ 28 августа 2010

Я пытаюсь перевести координаты вида и вида. Но JViewport / JScrollpane, похоже, не работает так, как задокументировано. JViewport.toViewCoordinates() считает, что представление всегда находится в верхнем левом углу компонента, хотя это явно не так.

String text = "blahblahblah\nblahblah\nblah";
JFrame frame = new JFrame("title");
JTextArea textArea = new JTextArea(text, 1, 30); // shows only one line
frame.add(new JScrollPane(textArea));
frame.pack();
frame.setVisible(true);
textArea.setCaretPosition(text.length()); // now showing the last line
JViewport viewport = ((JViewport)textArea.getParent());

viewport.getViewRect(); // returns java.awt.Rectangle[x=0,y=0,width=330,height=16]

viewport.getViewPosition(); // returns java.awt.Point[x=0,y=0]

viewport.toViewCoordinates(new Point(0,0)); // returns java.awt.Point[x=0,y=0]

Вышесказанное является надуманным примером. Мой настоящий JTextArea больше, чем одна строка. Мне не нужна JTextArea "модель" координата (смещение в тексте). Мне нужны подлинные 2d координаты.

Позиция представления не должна быть (0,0), поскольку первый видимый символ в области просмотра фактически находится в 3-й строке JTextArea.

Любые другие предложения о том, как я могу переводить между видом и координатами компонента при использовании JScrollPane?

--- добавлено ---

Это также не помогает.

SwingUtilities.convertPoint(viewport,0,0, textArea);
(java.awt.Point) java.awt.Point[x=0,y=0]

--- добавлено ---

Вот окончательная рабочая версия, основанная на ответе, который я получил. это показывает java.awt.Point[x=0,y=32], что я и ожидал.

@Test
public void test() throws InterruptedException {

    String text = "blahblahblah\nblahblah\nblah";
    JFrame frame = new JFrame("title");
    JTextArea textArea = new JTextArea(text, 1, 30);
    frame.add(new JScrollPane(textArea));
    frame.pack();
    frame.setVisible(true);
    textArea.setCaretPosition(text.length());
    final JViewport viewport = ((JViewport)textArea.getParent());

    SwingUtilities.invokeLater(new Runnable()
    {
        @Override
        public void run() {
            System.out.println(viewport.getViewPosition());
        }
    });

    Thread.sleep(1000);
}

Ответы [ 2 ]

2 голосов
/ 28 августа 2010

Проблема в том, что метод для получения viewPosition () выполняется до того, как область просмотра была фактически прокручена. Это связано с тем, что иногда Swing добавляет код в конец потока событий для последующей обработки.

Обычно эту проблему можно решить, обернув ваш код в SwingUtilities.invokeLater (), чтобы код выполнялся после того, как Swing выполнил всю его обработку. Однако в простой демонстрации ниже я обнаружил, что мне нужно добавить два метода invokeLater (). Я не уверен почему.

Переместите каретку вверх / вниз, и вы увидите изменение положения обзора. Второе значение будет содержать правильную позицию:

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;

public class Test5
{
    public static void createAndShowGUI()
    {
        String text = "one\ntwo\nthree\nfour\nfive";
        JFrame frame = new JFrame("title");
        JTextArea textArea = new JTextArea(text, 1, 30); // shows only one line
        JScrollPane scrollPane = new JScrollPane( textArea );
        frame.add(scrollPane);
        frame.pack();
        frame.setVisible(true);

        final JViewport viewport = scrollPane.getViewport();

        textArea.addCaretListener( new CaretListener()
        {
            public void caretUpdate(CaretEvent e)
            {
                SwingUtilities.invokeLater(new Runnable()
                {
                    public void run()
                    {
                        System.out.println("First : " + viewport.getViewPosition() );

                        SwingUtilities.invokeLater(new Runnable()
                        {
                            public void run()
                            {
                                System.out.println("Second: " + viewport.getViewPosition() );
                            }
                        });
                    }
                });
            }
        });

        textArea.setCaretPosition(text.length());
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
0 голосов
/ 28 августа 2010

может

SwingUtilities.convertPoint

пригодится?

...