2014-11-05 87 views
1

它出現在java中沒有辦法限制長度。我看了其他例子,人們創建了單獨的類等Java Textfield設置字符長度

我很好奇,如果我們可以使用動作事件而不使用其他類來做到這一點。

這是我到目前爲止。

txtTest.addKeyListener(new KeyAdapter() 
    public void keyPressed(KeyEvent e) 
     { 
      int MAX_LEN = 5; 
      char c = e.getKeyChar(); 
      int len = txtTest.getText().length(); 
      if(len < MAX_LEN) 
      { 
       return; 
      }else 
      { 
       Logging.info("TOOO LONG"); 
      } 

     } 
    }); 

所以我得到了點,如果我輸入文本更長,然後5個字符。是否有任何事件可以觸發,如果他們輸入6個字符,它會被刪除? E.g模仿退格還是刪除鍵?

回答

2

對不起,但這是一個非常脆弱的解決方案,你應該儘可能避免在文本組件上使用KeyListener。例如,當用戶試圖複製和粘貼文本時會發生什麼?恐怕在這種情況下,你的代碼會失敗。還有其他更深層的原因可以避免使用KeyListeners,但底線要好得多,因爲你會使用DocumentFilter。

例如

import javax.swing.*; 
import javax.swing.text.AttributeSet; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.Document; 
import javax.swing.text.DocumentFilter; 
import javax.swing.text.PlainDocument; 


@SuppressWarnings("serial") 
public class TextTestGui extends JPanel { 
    private JTextField limitedField = new JTextField(10); 

    public TextTestGui() { 
     add(limitedField); 
     PlainDocument doc = (PlainDocument) limitedField.getDocument(); 
     doc.setDocumentFilter(new MyDocFilter(5));; 
    } 

    private class MyDocFilter extends DocumentFilter { 

     private int limit; 

     public MyDocFilter(int limit) { 
     this.limit = limit; 
     } 

     @Override 
     public void insertString(FilterBypass fb, int offset, String string, 
      AttributeSet attr) throws BadLocationException { 
     Document innerDoc = fb.getDocument(); 
     StringBuilder sb = new StringBuilder(innerDoc.getText(0, innerDoc.getLength())); 
     sb.insert(offset, string); 
     if (textOK(sb.toString())) { 
      super.insertString(fb, offset, string, attr); 
     } 
     } 

     @Override 
     public void replace(FilterBypass fb, int offset, int length, String text, 
      AttributeSet attrs) throws BadLocationException { 
     Document innerDoc = fb.getDocument(); 
     StringBuilder sb = new StringBuilder(innerDoc.getText(0, innerDoc.getLength())); 
     int start = offset; 
     int end = offset + length; 
     sb.replace(start, end, text); 
     if (textOK(sb.toString())) { 
      super.replace(fb, offset, length, text, attrs); 
     } 
     } 

     @Override 
     public void remove(FilterBypass fb, int offset, int length) 
      throws BadLocationException { 
     super.remove(fb, offset, length); 
     } 

     private boolean textOK(String text) { 
     if (text.length() <= limit) { 
      return true; 
     } 
     return false; 
     } 
    } 

    private static void createAndShowGui() { 
     TextTestGui mainPanel = new TextTestGui(); 

     JFrame frame = new JFrame("TextTestGui"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 
+0

如果getText()的前5個字符的子字符串被substringed並使用setText設置,該怎麼辦? – Compass 2014-11-05 20:13:18

+0

有沒有在同一個類中使用DocumentFilter的方法? – user1158745 2014-11-05 20:14:03

+0

@ user1158745:當然。只需創建一個匿名內部類或私有內部類,就像您爲ActionListener所做的一樣。 – 2014-11-05 20:14:30

-1

這與KeyListener的一種方法:

txtTest.addKeyListener(new KeyAdapter(){ 
    public void keyPressed(KeyEvent e) 
    { 
     char[] letters = txtTest.getText().toCharArray(); 
     if(txtTest.getText().length() < 5) 
     { 
      return; 
     }else 
     { 
      txtTest.setText(""+letters[0]+letters[1]+letters[2]+letters[3]+letters[4]); 
     } 
    } 
}); 

但是你可以用while循環做到這一點:

public void Update(){ 
    while(true){ 
     if(txtTest.getText() != null){ 
      if(!(txtTest.getText().length() < 5)) 
      { 
       char[] letters = txtTest.getText().toCharArray(); 
       txtTest.setText(""+letters[0]+letters[1]+letters[2]+letters[3]+letters[4]); 
      } 
     } 
    } 
} 

不幸的是,這是一個有點它的處理速度太快,所以你需要調整更新速度,這會變得複雜。

+0

再次,1)當有人使用複製和粘貼將文本添加到使用您的解決方案的JTextField時會發生什麼? 2)你測試過你的第二個解決方案嗎?你正在Swing事件線程上做'while(true)'循環嗎?而GUI仍然功能? – 2014-11-05 20:47:21