2010-12-30 19 views
6

Czy ktoś mógłby mi pomóc w znalezieniu pozycji kursora w JTextArea pod względem piksela? Użyłem txtArea.getCaretPosition(). Ale nie jest to stanowisko, którego się spodziewam. Właściwie chcę pozycję kursora w x,y współrzędne pikseli.Jak znaleźć pozycję kursora w JTextArea

Odpowiedz

0

Być może trzeba będzie użyć klasy FontMetrics.
Przeanalizuj tekst, wymyśl nowe linie/zawijanie tekstu. następnie użyć

Font font = new Font("Verdana", Font.PLAIN, 10); 
    FontMetrics metrics = new FontMetrics(font); 
    Rectangle2D bounds = metrics.getStringBounds("string", null); 
    int widthInPixels = (int) bounds.getWidth(); 

itp ....

A jeśli naprawdę chcesz, dodawać swoje rozwiązanie, żeby być cool. :)

3

TextUI mieć metoda modelToView że dam ci położenie/wielkość karetki:

import java.awt.BorderLayout; 
import java.awt.Rectangle; 

import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JTextArea; 
import javax.swing.SwingUtilities; 
import javax.swing.event.CaretEvent; 
import javax.swing.event.CaretListener; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.JTextComponent; 


public class PixelPositionOfCaretDemo 
{ 
    public PixelPositionOfCaretDemo() 
    { 
     JLabel label = new JLabel("Move the caret..."); 
     JTextArea area = new JTextArea(); 
     area.addCaretListener(new MyCaretListener(label)); 

     JFrame frame = new JFrame(); 
     frame.setLayout(new BorderLayout()); 
     frame.setBounds(new Rectangle(400, 400, 400, 400)); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(area, BorderLayout.CENTER); 
     frame.add(label, BorderLayout.SOUTH); 
     frame.setVisible(true); 
    } 

    private static class MyCaretListener implements CaretListener 
    { 
     private final JLabel label; 

     MyCaretListener(JLabel label) 
     { 
      this.label = label; 
     } 

     @Override 
     public void caretUpdate(CaretEvent e) 
     { 
      JTextComponent textComp = (JTextComponent) e.getSource(); 
      try 
      { 
       Rectangle rect = textComp.getUI().modelToView(textComp, e.getDot()); 
       label.setText(rect.toString()); 
      } 
      catch (BadLocationException ex) 
      { 
       throw new RuntimeException("Failed to get pixel position of caret", ex); 
      } 
     } 
    } 

    public static void main(String[] args) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       new PixelPositionOfCaretDemo(); 
      } 
     }); 
    } 
} 
+1

+1 , Nie musisz do tego używać interfejsu użytkownika. Możesz użyć textComponent.modelToView (...). – camickr

+0

@camickr: Dobra sprawa, jestem zaskoczony, że tęskniłem za przewijaniem interfejsu API JTextComponent, ale znalazłem go "głębiej" w TextUI :) Myślę: co to jest "najlepsza praktyka" w takich przypadkach, zaktualizuj moją odpowiedź zgodnie do twojego komentarza lub zachować go, aby zachować "historię"? – Uhlen

+0

Dobre pytanie; dwie powszechne praktyki obejmują: 1) wysłanie oddzielnej odpowiedzi z alternatywnym podejściem i 2) dodanie linku do odpowiedniej sekcji historii "edycji". – trashgod

0

Podobnie jak poniżej

Point point = textArea.getCaret().getMagicCaretPosition(); 

Należy pamiętać punkt może być zerowa

0

Zrobiłem to po wypróbowaniu innych postów tutaj. Działa tak długo, jak długo twoje textarea ma wyłączone zawijanie tekstu.

public Point getCaretPixelPosition(JTextArea a) { 
    try { 
     int cpos = a.getCaretPosition(); 
     Font font = a.getStyledDocument().getFont(a.getStyledDocument().getLogicalStyle(cpos)); 
     FontMetrics metrics = getFontMetrics(font); 

     int lineNum = a.getLineOfOffset(cpos); 
     int y = lineNum * metrics.getHeight(); 
     int lineStart = a.getLineStartOffset(lineNum); 
     int x = metrics.stringWidth(a.getText().substring(lineStart, cpos)); 

        return new Point(x,y); 

    } catch(BadLocationException e) {} 
    return null; 
} 
0
Rectangle caretRect=textPane.getUI().modelToView(textPane,textPane.getCaretPosition()); 

lub

Rectangle caretRect=textPane.modelToView(textPane.getCaretPosition()); 

na przykład; użyj tego prostego w celu wyświetlenia wyskakującego okienka:

popupMenu.show (textPane, caretRect.x, caretRect.y);

2

Należy pamiętać, że niektóre z tych odpowiedzi zwracają lokalizację w stosunku do komponentu tekstowego, z którego uzyskuje się pozycję karetki.

Jeśli chcesz uzyskać pozycję karetki jest na ekranie, proponuję użyć tej metody:

Caret caret = yourTextComponent.getCaret(); 
Point p = caret.getMagicCaretPosition(); 
p.x += yourTextComponent.getLocationOnScreen().x; 
p.y += yourTextComponent.getLocationOnScreen().y; 

aFrameYourePositioning.setLocation(p); 
+0

Ten działał jak czar. Miał problemy z wykorzystaniem dowolnego innego podejścia, aby pokazać JPopupMenu przy użyciu tych współrzędnych, ale ten był doskonały. – Alfabravo

0

Oto przykład do wyświetlania JPopup w pozycji karetki

Caret caret = logText.getCaret(); 
Point p = new Point(caret.getMagicCaretPosition()); 
p.x += logText.getLocationOnScreen().x; 
p.y += logText.getLocationOnScreen().y; 

SwingUtilities.convertPointFromScreen(p, actionsPanel); 
popup.show(actionsPanel, p.x, p.y); 
Powiązane problemy