2012-04-05 12 views
11

私は現在、Swingのコンソールウィンドウで作業しています。これはJTextAreaに基づいており、一般的なコマンドラインのように機能します。 1行にコマンドを入力し、Enterキーを押します。次の行に出力が表示され、その出力の下に次のコマンドを書き込むことができます。JTextAreaの部分を編集できないようにします(JTextArea全体ではありません)

今、私はあなたのコマンドで現在の行だけを編集することができたと思います。上記のすべての行(古いコマンドと結果)は編集不可能でなければなりません。これどうやってするの?

答えて

17

独自のコンポーネントを作成する必要はありません。

これは、私が行ったように、カスタムDocumentFilterを使用して行うことができます。

textPane.getDocument()からドキュメントを入手し、document.setFilter()でフィルタを設定することができます。フィルタ内でプロンプトの位置を確認し、その位置がプロンプトの後にある場合にのみ変更を許可することができます。例えば

private class Filter extends DocumentFilter { 
    public void insertString(final FilterBypass fb, final int offset, final String string, final AttributeSet attr) 
      throws BadLocationException { 
     if (offset >= promptPosition) { 
      super.insertString(fb, offset, string, attr); 
     } 
    } 

    public void remove(final FilterBypass fb, final int offset, final int length) throws BadLocationException { 
     if (offset >= promptPosition) { 
      super.remove(fb, offset, length); 
     } 
    } 

    public void replace(final FilterBypass fb, final int offset, final int length, final String text, final AttributeSet attrs) 
      throws BadLocationException { 
     if (offset >= promptPosition) { 
      super.replace(fb, offset, length, text, attrs); 
     } 
    } 
} 

しかし、これはプログラム端子の出力(編集不可)セクションにコンテンツを挿入できなくなります。代わりに、出力を追加しようとしているときに設定したフィルタのパススルーフラグか、出力を追加する前に文書フィルタをnullに設定してから、再実行されます。

textArea.addKeyListener(new KeyAdapter() { 

    public void keyPressed(KeyEvent event) { 

     int code = event.getKeyCode();   
     int caret = textArea.getCaretPosition(); 
     int last = textArea.getText().lastIndexOf(">> ") + 3; 

     if(caret <= last) { 

      if(code == KeyEvent.VK_BACK_SPACE) { 

       textArea.append(" "); 

       textArea.setCaretPosition(last + 1); 
      } 

      textArea.setCaretPosition(textArea.getText().length()); 
     } 
    } 
}); 
+1

(AbstractDocument)jta.getDocument())。setDocumentFilter(dfilter); –

0

私の知る限り、あなたはたぶん、あなたは、テキストフィールドのリスト(でも有効と無効奇数)、またはテキストフィールド/ラベル

のミックスEDITでそれをシミュレートすることができ、独自の制御

を実装する必要があります。

私は編集不可能なテキストエリアと編集可能なテキストフィールドのために賭けるでしょう。テキストフィールドに入力してEnterキーを押し、「コマンド」を追加してテキストエリアに出力

3
import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.text.*; 
public class OnlyEditCurrentLineTest { 
    public JComponent makeUI() { 
    JTextArea textArea = new JTextArea(8,0); 
    textArea.setText("> aaa\n> "); 
    ((AbstractDocument)textArea.getDocument()).setDocumentFilter(
     new NonEditableLineDocumentFilter()); 
    JPanel p = new JPanel(new BorderLayout()); 
    p.add(new JScrollPane(textArea), BorderLayout.NORTH); 
    return p; 
    } 
    public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     @Override public void run() { createAndShowGUI(); } 
    }); 
    } 
    public static void createAndShowGUI() { 
    JFrame f = new JFrame(); 
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    f.getContentPane().add(new OnlyEditCurrentLineTest().makeUI()); 
    f.setSize(320,240); 
    f.setLocationRelativeTo(null); 
    f.setVisible(true); 
    } 
} 
class NonEditableLineDocumentFilter extends DocumentFilter { 
    @Override public void insertString(
     DocumentFilter.FilterBypass fb, int offset, String string, 
     AttributeSet attr) throws BadLocationException { 
    if(string == null) { 
     return; 
    }else{ 
     replace(fb, offset, 0, string, attr); 
    } 
    } 
    @Override public void remove(
     DocumentFilter.FilterBypass fb, int offset, 
     int length) throws BadLocationException { 
    replace(fb, offset, length, "", null); 
    } 
    private static final String PROMPT = "> "; 
    @Override public void replace(
     DocumentFilter.FilterBypass fb, int offset, int length, 
     String text, AttributeSet attrs) throws BadLocationException { 
    Document doc = fb.getDocument(); 
    Element root = doc.getDefaultRootElement(); 
    int count = root.getElementCount(); 
    int index = root.getElementIndex(offset); 
    Element cur = root.getElement(index); 
    int promptPosition = cur.getStartOffset()+PROMPT.length(); 
    //As Reverend Gonzo says: 
    if(index==count-1 && offset-promptPosition>=0) { 
     if(text.equals("\n")) { 
     String cmd = doc.getText(promptPosition, offset-promptPosition); 
     if(cmd.isEmpty()) { 
      text = "\n"+PROMPT; 
     }else{ 
      text = "\n"+cmd+"\n xxxxxxxxxx\n" + PROMPT; 
     } 
     } 
     fb.replace(offset, length, text, attrs); 
    } 
    } 
} 
0

javaのコンソールとして。 しかし、私は "コマンド領域"と "ログ領域"を持つことができるいくつかの変更により、コマンドの結果がログ領域に表示され、実際のコマンドがコマンド領域に表示されます。 ログ領域は、編集不可能な別のJtext領域です。 私はthisthreadが役に立つと思ったので、この実装に似た何かをしようとしている誰かがいくつかのポインタを見つけることができます!

class NonEditableLineDocumentFilter extends DocumentFilter 
{ 
    private static final String PROMPT = "Command> "; 

    @Override 
    public void insertString(DocumentFilter.FilterBypass fb, int offset, String string,AttributeSet attr) throws BadLocationException 
    { 
     if(string == null) 
     { 
      return; 
     } 
     else 
     { 
      replace(fb, offset, 0, string, attr); 
     } 
    } 

    @Override 
    public void remove(DocumentFilter.FilterBypass fb, int offset,int length) throws BadLocationException 
    { 
     replace(fb, offset, length, "", null); 
    } 

    @Override 
    public void replace(DocumentFilter.FilterBypass fb, int offset, int length,String text, AttributeSet attrs) throws BadLocationException 
    {  
     Document doc = fb.getDocument(); 
     Element root = doc.getDefaultRootElement(); 
     int count = root.getElementCount(); 
     int index = root.getElementIndex(offset); 
     Element cur = root.getElement(index); 
     int promptPosition = cur.getStartOffset()+PROMPT.length(); 

     if(index==count-1 && offset-promptPosition>=0) 
     { 
      if(text.equals("\n")) 
      { 
       cmd = doc.getText(promptPosition, offset-promptPosition); 

       if(cmd.trim().isEmpty()) 
       { 
        text = "\n"+PROMPT; 
       } 
       else 
       { 
        text = "\n" + PROMPT; 
       } 
      } 
      fb.replace(offset, length, text, attrs); 
     } 
    } 
} 
+1

-1 for keyListener -far低レベルで安全に要求を処理するには – kleopatra

+2

+1 KeyListenerはこのような機能を実装する最も簡単な方法です。何年も前からKeyListenerを使用してきた安全性の問題はありません。 – ShadowDoom

0

これは、文書フィルタ作用の私のimplemitationです:ユーザーが入力コマンドをできることについて、とき「>>」は、コマンドラインですべての行の先頭にある何

関連する問題