【问题标题】:JTextArea in JScrollPane, view coordinate translationJScrollPane中的JTextArea,查看坐标平移
【发布时间】:2011-04-05 00:35:18
【问题描述】:

我正在尝试在视图和视口坐标之间进行转换。 但是 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 “模型”坐标(文本中的偏移量)。我需要真正的二维坐标。

视图位置不应为 (0,0),因为视口中的第一个可见字符实际上位于 JTextArea 的第 3 行。

关于在使用 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);
}

【问题讨论】:

    标签: java swing jscrollpane jtextarea


    【解决方案1】:

    问题在于获取 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();
                }
            });
        }
    }
    

    【讨论】:

    • 美国东部时间。非常感谢。你为我节省了很多工作。如果我在测试中更加勤奋一点,我就不会错过这一点。我编辑了我的问题以包含最终的工作版本,它比你的简单一点。
    • 是的,在您的简单示例中,您只需要一个invokeLater()。出于某种原因,当您通过跟踪“插入符号移动”上的视口位置来动态执行此操作时,您需要两个 invokeLater()。我不知道为什么。
    • 此外,JViewport.toViewCoordinates() 仍然失败并为点 (0,0) 返回 (0,0),但另一个答案 SwingUtilities.convertPoint 工作正常。
    【解决方案2】:

    可以

    SwingUtilities.convertPoint
    

    有用吗?

    【讨论】:

    • 这也失败了。我将它添加到上面的问题中。谢谢。
    • 我不是故意给你投反对票的,但是系统现在不允许我改变它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-23
    • 2011-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多