2014-04-09 4 views
0

안녕하세요 저는 JTextArea에서 내 자신의 명령 줄을 작성하는 것을 즐겁게하고 있습니다.JTextArea 누른 키 듣기

어떤 키를 눌렀는지에 따라 캐럿이 처리되는 방식을 좀 더 제어하고 싶습니다. JTextArea에 KeyListener를 추가했습니다. 내 문제는 : 업 키를 눌러 감지하면 캐럿 위치가 이동해야합니다. KeyListener에서 캐럿 위치를 인쇄하려고하면 이전 위치가 표시됩니다. 새롭게 적용된 위치는 키 누르기 이벤트를 포착 한 후에 고려됩니다. 구체적으로 말하면, getCaretPosition() 메소드가 15를 리턴한다고 가정하십시오. 위쪽 화살표를 누르면 getCaretPosition()에서 15를 얻습니다. 내가 이벤트 리스너를 벗어 났을 때만 캐럿 위치가 변경됩니다.

KeyListener 안에 새로운 캐럿 위치를 가져오고 싶습니다. 현재의 목표는 새로운 캐럿 위치가 개행 프롬프트보다 먼저 도착하는지 확인하는 것입니다. 그렇다면 캐럿은 전혀 움직이지 않아야합니다. 왜냐하면이 영역을 수정 가능하게 만들고 싶지 않기 때문입니다. 그래서 새로운 캐럿 위치를 얻고 싶습니다. 그런 다음이 새로운 위치를 적용할지 여부를 결정하십시오. 어떻게하면됩니까?

여기 내 코드의 덩어리입니다

public MethodCommandLine() { 
     JFrame mainFrame = new JFrame(); 
     mainFrame.setLayout(new FlowLayout(FlowLayout.LEFT)); 
     mainFrame.setLocation(200, 200); 

     mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     prompt = new JTextArea(PROMPT); 
     prompt.setCaretPosition(PROMPT.length()); 

     lastCmdPosition = prompt.getCaretPosition(); 

     prompt.setPreferredSize(new Dimension(300, 500)); 
     prompt.addKeyListener(new KeyMonitor()); 

     JScrollPane js = new JScrollPane(prompt); 
     js.setViewportView(this.prompt); 
     js.setVisible(true); 

     mainFrame.getContentPane().add(js); 

     mainFrame.pack(); 
     mainFrame.setVisible(true); 

     this.formattedFields = new FormattedFields().getFField(); 

     init(); 
} 



private class KeyMonitor extends KeyAdapter { 
     String commandRcvd; 

     public void keyPressed(KeyEvent e) { 
      System.out.println("----key pressed: ." + e.getKeyChar() + "."); 

      String bak = prompt.getText(); 
      System.out.println("\nprevious content: \n\t" + bak); 

      System.out.println("\nCaret position: " + prompt.getCaretPosition()); 
         // HERE: no matter which key is pressed, the former caret position will be returned. I would like to get there the NEW supposedly caret position. 

      if(prompt.getCaretPosition() <= lastCmdPosition) { 
       return; 
      } 
      if(e.getKeyCode() == KeyEvent.VK_TAB) { 
       if(prompt.getText().charAt(prompt.getCaretPosition() -1) == ' ') { 
        prompt.setText(prompt.getText() + "\n" + printAvailableEntries()); 
       } 
       else { 
        System.out.println("." + prompt.getText().charAt(prompt.getCaretPosition() -1) + "."); 

        System.out.println(getCurrentWord()); 
       } 
      } 

      if(e.getKeyCode() == KeyEvent.VK_DELETE || e.getKeyCode() == KeyEvent.VK_BACK_SPACE) { 
       if(prompt.getText().charAt(prompt.getCaretPosition() - 2) == '>') { 
        e.consume(); 
       } 
      } 
      if(e.getKeyCode() == KeyEvent.VK_ENTER) { 


       /* 
       int lines = prompt.getLineCount(); 
       System.out.println("getLineCount: " + lines); 
       try { 
       System.out.println("getLineEndOffset: " + prompt.getLineEndOffset(lines -1)); 
       System.out.println("getLineOfOffset: " + prompt.getLineOfOffset(lines -1)); 

       } catch (BadLocationException ex) { 
        ex.printStackTrace(); 
       }*/ 


       commandRcvd = prompt.getText().substring(lastCmdPosition); 
       System.out.println("last command : ." + commandRcvd + "."); 
       prompt.setText(prompt.getText() + "\n" + PROMPT); 
       lastCmdPosition = prompt.getCaretPosition(); 
       e.consume(); 
     } 
     if(e.getKeyCode() == KeyEvent.VK_LEFT) { 
      if(prompt.getCaretPosition() -1 < lastCmdPosition) { 
       System.out.println("out : caret=" + prompt.getCaretPosition() + "\tlast=" + lastCmdPosition); 
       prompt.setCaretPosition(lastCmdPosition); 
      } 
      e.consume(); 
     } 
     if(e.getKeyCode() == KeyEvent.VK_UP) { 
      prompt.setCaretPosition(prompt.getCaretPosition()); 
     } 

     System.out.println("\ncurrent content: ." + prompt.getText() + "."); 

     } 
} 
+2

사용의 DocumentListener 및/또는 그 대신 모든 KeyListener – mKorbel

답변

1

SwingUtilities.invokeLater()

+0

최고 멋진 감사의 JTextComponents에 대한 DocumentFilter를 함께 리스너 메소드 호출 코드를 감싸! 루프에서 JProgressBar 업데이트와 같이 Java 이벤트 Dispatcber Thread와 관련이 있습니까? – kaligne

+0

캐럿 위치를 요청하지만 편집이 진행 중이고 캐럿이 오래되었습니다. 필요한 것은 편집 처리가 끝날 때까지 수표를 연기하는 것입니다. 그것은 포장에 의해 수행됩니다. – StanislavL