對不起,但這是一個非常脆弱的解決方案,你應該儘可能避免在文本組件上使用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();
}
});
}
}
如果getText()的前5個字符的子字符串被substringed並使用setText設置,該怎麼辦? – Compass 2014-11-05 20:13:18
有沒有在同一個類中使用DocumentFilter的方法? – user1158745 2014-11-05 20:14:03
@ user1158745:當然。只需創建一個匿名內部類或私有內部類,就像您爲ActionListener所做的一樣。 – 2014-11-05 20:14:30