问题描述
我正在尝试在视口和视口坐标之间转换.但是,JViewport/JScrollpane似乎无法像所记录的那样工作. JViewport.toViewCoordinates()
认为视图始终位于组件的左上方,即使事实并非如此.
I'm trying to translate between view and viewport coordinates.But the JViewport/JScrollpane doesn't seem to work as documented. JViewport.toViewCoordinates()
thinks the view is always at the top left of the component, even though that's clearly not the case.
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坐标.
The above is contrived example. My real JTextArea
is larger than one line. I don't need JTextArea "model" coordinate (the offset in the text). I need genuine 2d coordinates.
视图位置不应为(0,0),因为视口中的第一个可见字符实际上位于JTextArea的第三行.
The view position shouldn't be (0,0), as the first visible character in the viewport is actually in the 3rd line of the JTextArea.
关于使用JScrollPane时如何在视图坐标和组件坐标之间转换的任何其他建议?
Any other suggestions on how I can translate between view and component coordinates when using JScrollPane?
-添加--
这也失败.
SwingUtilities.convertPoint(viewport,0,0, textArea);
(java.awt.Point) java.awt.Point[x=0,y=0]
-添加--
这是最终版本,根据我收到的答案.它显示java.awt.Point[x=0,y=32]
这是我所期望的.
Here is the final working version, based on the answer I received.it shows java.awt.Point[x=0,y=32]
which is what I expected.
@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);
}
推荐答案
问题是获取viewPosition()的方法在实际滚动视口之前执行.这是因为有时Swing将代码添加到事件线程的末尾以进行后续处理.
The problem is that the method to get the viewPosition() executes before the viewport has actually been scrolled. This is because sometimes Swing adds code to the end of the event thread for later processing.
通常,可以通过将代码包装在SwingUtilities.invokeLater()中来解决此问题,以便在Swing完成所有处理后执行代码.但是,在下面的简单演示中,我发现我需要添加两个invokeLater()方法.我不知道为什么.
Usually this problem can be solved by wrapping your code in a SwingUtilities.invokeLater() so the code is executed after Swing has done all its processing. However in the simple demo below I found I needed to add two invokeLater() methods. I'm not sure why.
向上/向下移动插入符号,您将看到视图位置更改.第二个值将包含正确的位置:
Move the caret up/down and you will see the view position change. The second value will contain the correct position:
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();
}
});
}
}
这篇关于JScrollPane中的JTextArea,查看坐标转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!