2013-09-22 63 views
1

其實,我已經在here中提出過這個問題。但是,我犯了錯誤。我還沒有得到解決方案。在JTextArea中獲取插入位置的XY位置

首先,在問題之前,我可以

Rectangle rectangle = textArea.modelToView(textArea.getCaretPostion()); 

得到矩形我也得到X和Y位置。

我正在創建一個可以添加新文本區域的編輯器,每按一次Enter鍵。上面代碼的XY位置總是會在每個文本區域中返回相同的返回值。看我的代碼。

import java.awt.Container; 
import java.awt.Font; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 
import java.util.LinkedList; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.AbstractAction; 
import javax.swing.Action; 
import javax.swing.Box; 
import javax.swing.JFrame; 
import javax.swing.JTextArea; 
import javax.swing.KeyStroke; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.JTextComponent; 

public class forquestion extends JFrame { 

    Container textAreaBox; 
    LinkedList<JTextComponent> textArea; 
    int nameTA; 

    public forquestion() { 
      int nameTA = 0; 

      textArea = new LinkedList<>(); 

      textAreaBox = Box.createVerticalBox(); 
      textAreaBox.add(Box.createVerticalGlue()); 
      addLine(); 
      this.add(textAreaBox); 
      this.setVisible(true); 
    } 

    public static void main(String[] args) { 
      forquestion app = new forquestion(); 
      app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    public void addLine() { 

      JTextComponent temp_ta = createTextComponent(); 
      textArea.add(temp_ta); 
      textAreaBox.add(textArea.getLast()); 
      textAreaBox.add(Box.createVerticalGlue()); 
    } 

    protected JTextComponent createTextComponent() { 
      JTextArea ta = new JTextArea("test"); 

      /*if (count%2==0) 
          ta.setForeground(Color.red); 
      else 
          ta.setForeground(Color.GREEN);*/ 

      ta.setFont(new Font("Courier New",Font.PLAIN,16)); 
      ta.setLineWrap(true);                                                             
      ta.setWrapStyleWord(true); 
      ta.setName(Integer.toString(nameTA)); 
      nameTA+=1; 

      basicKey("ENTER", enter, ta); 

      ta.addMouseListener(new java.awt.event.MouseAdapter() { 
        public void mousePressed(java.awt.event.MouseEvent ev) { 
          try { 
            taMousePressed(ev); 
          } catch (BadLocationException ex) { 
            Logger.getLogger(forquestion.class.getName()).log(Level.SEVERE, null, ex); 
          } 
        } 
      }); 

      return ta; 
    } 

    public void basicKey(String s, Action a, JTextArea ta) { 

      ta.getInputMap().put(KeyStroke.getKeyStroke(s), s); 
      ta.getActionMap().put(s, a); 
    } 

    Action enter = new AbstractAction() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 

        addLine(); 
      } 
    }; 

    private void taMousePressed(java.awt.event.MouseEvent ev) throws BadLocationException { 
      int now_focus = Integer.parseInt(ev.getComponent().getName()); 
      int _caret; 
      _caret = textArea.get(now_focus).getCaretPosition(); 
      Rectangle rectangle = textArea.get(now_focus).modelToView(_caret); 
      double x = rectangle.getX(); 
      //int xc = textArea.get(now_focus).getLocation().x; 
      double y = rectangle.getY(); 
      //int yc = textArea.get(now_focus).getLocation().y; 
      //double h = rectangle.getHeight(); 
      //double w = rectangle.getWidth(); 
      System.out.println(x); 
      System.out.println(y); 
      //System.out.println(xc); 
      //System.out.println(yc); 
      //System.out.println(h); 
      //System.out.println(w); 
      System.out.println(""); 
    } 

} 

我的代碼每次按文本區域時都會打印XY位置。但是,每個文本區域的顯示總是相同的。 (嘗試製作很多文本區域並給出一些文本)順便說一句,它只是簡單的代碼。你需要改變窗口的框架大小來更新新的文本區域,然後按下輸入key ..hahaha。

所以,我的問題是:如何在任何文本區域中獲得插入符(文本光標)的XY位置。我想在那裏顯示JPopmenu。 :)

我希望這個問題明確給你。 Thx之前。

回答

3

回報的Rectangle是相對於文本區域,它的位置是0x0,位於組件的左上角。

如果你使用類似...

popup.show(textArea.get(now_focus), rectangle.x, rectangle.y + rectangle.height); 

popupJPopupMenu,它會進行必要的翻譯到屏幕本身。

現在。話說回來。就個人而言,我寧願使用Swing提供的彈出API支持。這將意味着需要創建一個從JTextArea擴展來實現它的自定義組件...

public class MyPopupTextArea extends JTextArea { 
    /*...*/ 
    public Point getPopupLocation(MouseEvent evt) { 
     Rectangle rectangle = textArea.get(now_focus).modelToView(_caret); 

     Point p = rectangle.getLoction(); 
     p.y += rectangle.height; 

     return p; 
    } 
} 

然後,根據您的需求,您可以使用setComponentPopup提供JPopupMenu或共享的情況下,如果需要爲每個自定義編輯器創建一個自定義JPopupMenu,並使用setComponentPopup,因爲您認爲合適......沒有搞亂鼠標監聽器;)

+0

我明白了。 Thx for solution.Btw,你能給我你的問題的完整代碼嗎?至少,您的代碼的構造函數將Jpopmenu添加到面板或框架。我仍然在學習JPopMenu。每次我將它添加到容器中時,它都會覆蓋其他組件。 – TblsX

+0

您不要將JPopupMenu添加到組件(通常)。您應該使用setComponentPopup將彈出框與組件關聯起來,或者,如果您有特殊需求,請使用JPopupMenu#show來顯示彈出框。更像是一個特殊的窗口,然後是一個組件。你可以看看[三明治彈出菜單](http://docs.oracle.com/javase/tutorial/uiswing/components/menu.html#popup)瞭解更多詳情... – MadProgrammer

+0

這對我來說很有意義。無論如何:D – TblsX