2013-05-14 65 views
1

下面是我想作爲概念驗證的一個示例:我想要一個帶有文本框和一個按鈕的框架。用戶輸入到文本字段中的任何內容都將被忽略,但如果您單擊該按鈕,則會在文本字段上設置文本。你會如何做到這一點?如何創建忽略用戶輸入但讓組件修改文本的JTextField?

我已經提前做了一些研究,想出了一個解決方案,我將作爲答案發布。但我擔心的是有一個更簡單的方法來做到這一點。我在問這個問題,看看有沒有更好的方法。

這裏是我試圖建立概念的證明了這一點的原因截圖:

capture key inputs

我試圖建立的東西就是這樣的。當用戶輸入文字時,我想忽略他們正在說的話,抓住它,然後放下我自己的解釋。例如,如果用戶按下控制+ Y,我希望它這樣說:

key input captured

我不想只是讓JTextField的不可編輯,因爲灰顯的框,隱藏光標。我希望人們知道他們應該點擊文本字段並輸入。

+0

文本字段將不會收到「控制」鍵擊,只會產生生成鍵類型事件的鍵擊。也許相反,你可以有幾個複選框(Control,Alt,Shift)和一個包含a-z 0-9的組合框。隨着使用選擇,您可以進行翻譯並將結果顯示在JLabel中。 – camickr 2013-05-14 04:08:23

+0

@camickr是的,但我已經明白了這一點。 – 2013-05-14 04:21:57

回答

0

這段代碼完全符合我的要求。但我希望有一個更簡單的方法:

package com.sandbox; 

import javax.swing.*; 
import javax.swing.text.AbstractDocument; 
import javax.swing.text.AttributeSet; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.DocumentFilter; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

public class Sandbox { 

    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

     final JTextField text = new JTextField(); 
     ((AbstractDocument) text.getDocument()).setDocumentFilter(new DocumentFilter() { 
      @Override 
      public void remove(FilterBypass fb, int offset, int length) throws BadLocationException { 
//    super.remove(fb, offset, length); 
      } 

      @Override 
      public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException { 
//    super.insertString(fb, offset, string, attr); 
      } 

      @Override 
      public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { 
//    super.replace(fb, offset, length, text, attrs); 
      } 
     }); 

     JPanel panel = new JPanel(); 
     BoxLayout layout = new BoxLayout(panel, BoxLayout.Y_AXIS); 
     panel.setLayout(layout); 

     panel.add(text); 
     JButton jButton = new JButton("Click to change text"); 
     jButton.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       DocumentFilter old = ((AbstractDocument) text.getDocument()).getDocumentFilter(); 
       ((AbstractDocument) text.getDocument()).setDocumentFilter(new DocumentFilter()); 
       text.setText("You clicked!"); 
       ((AbstractDocument) text.getDocument()).setDocumentFilter(old); 
      } 
     }); 
     panel.add(jButton); 

     frame.setContentPane(panel); 

     frame.pack(); 
     frame.setVisible(true); 
    } 


} 
1

使文本字段不可編輯。用戶不能輸入數據,但程序還是可以:

textField.setEditable(false); 
+0

我不喜歡如何灰色的文本字段和隱藏光標。我將更新我的問題更具體 – 2013-05-14 03:42:08

+0

已更新原始問題 – 2013-05-14 03:46:31

3

如果你想保持光標,你可以攔截擊鍵描述here。從上面的鏈接

代碼:

myTextField.addKeyListener(new KeyAdapter() { 
    @Override 
    public void keyTyped(KeyEvent e) { 
     char c = e.getKeyChar(); 
     if (!Character.isDigit(c)) { 
      e.consume(); // Stop the event from propagating. 
     } 
    } 
}); 

或者,您可以禁用條目,然後恢復的背景顏色很輕鬆了,但失去光標:

textField.setEditable(false); 
textField.setBackground(Color.WHITE); 
+0

回覆:您的第一個示例,這是我的理解,它不會捕獲控制+ V(粘貼),並最終顯示剪貼板。第二是沒問題,但沒有光標,我認爲它會混淆用戶。 – 2013-05-14 04:18:09

+0

由於事件通知的性質,這可能不適用於所有p,在表格中,並且不是推薦的方法來攔截輸入 – MadProgrammer 2013-05-14 04:21:31

+0

同意。DocumentFilter是正確的方法,但是根據TYL的回答,似乎正在尋求替代方案。 – pwrex 2013-05-14 04:27:37

0

這是hendalst' code編輯版。它還可以防止諸如Ctrl + V之類的事件,因爲該事件也在keyPressedkeyReleased方法中消耗。

myTextField.addKeyListener(new KeyListener() { 
    @Override 
    public void keyTyped(KeyEvent ke) { 
     ke.consume(); 
     // do what you want: 
     myTextField.setText(...); 
    } 
    @Override 
    public void keyPressed(KeyEvent ke) { 
     ke.consume(); 
    } 
    @Override 
    public void keyReleased(KeyEvent ke) { 
     ke.consume(); 
    } 
});