2016-12-26 2 views
2

Je veux faire une coutume JTextField, et mes exigences sont les suivantes:Comment définir différentes limites à JTextField pour montrer Conseil d'entrée et d'entrée

  1. Afficher Conseil dans le champ texte.
  2. Il faudra un nombre limité de caractères.

Les deux conditions fonctionnent. Mais le problème est que si je mets la limite à 6, alors il définit la longueur d'entrée à 6. J'ai besoin de définir une limite supplémentaire. Comme, Entrée Limite de limite: 20, Nombre limite d'entrée: 6 Exemple: Indication d'entrée: Entrer un nombre ici, Entrée: 666666 (6 chiffres maximum).

Voici les deux de la classe.

CustomTextField.java

public class CustomTextField extends JTextField implements KeyListener, FocusListener{ 
    private static final long serialVersionUID = 1L; 

    private final int CHAR_LIMIT = 6; 
    private String hint = null; 
    private boolean showingHint; 

    public CustomTextField(String hint) { 
     super(hint); 
     this.hint = hint; 
     this.showingHint = true; 
     this.setDocument(new CustomJTextFieldCharLimit(CHAR_LIMIT)); 
     super.addFocusListener(this); 
     this.addKeyListener(this); 
    } 

    @Override 
    public void keyPressed(KeyEvent arg0) { 

    } 

    @Override 
    public void keyReleased(KeyEvent arg0) { 

    } 

    @Override 
    public void keyTyped(KeyEvent event) { 
     char c = event.getKeyChar(); 

     if (!(Character.isDigit(c) || c == KeyEvent.VK_BACK_SPACE || c== KeyEvent.VK_DELETE)) { 
      event.consume(); 
     } 
    } 

    @Override 
    public void focusGained(FocusEvent e) { 
     if(this.getText().isEmpty()) { 
     super.setText(""); 
     showingHint = false; 
     } 
    } 
    @Override 
    public void focusLost(FocusEvent e) { 
     if(this.getText().isEmpty()) { 
      super.setText(hint); 
      showingHint = true; 
     } 
    } 

    @Override 
    public String getText() { 
     return showingHint ? "" : super.getText(); 
    } 
} 

CustomJTextFieldCharLimit.java

public class CustomJTextFieldCharLimit extends PlainDocument{ 
    private int limit; 

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

    public void insertString(int offset, String string, AttributeSet set) throws BadLocationException { 
     if (string == null) { 
      return ; 
     }else if ((getLength() + string.length()) <= limit) { 
      super.insertString(offset, string, set); 
     } 
    } 
} 
+0

J'ai vérifié que cela fonctionne, comment avez-vous vérifié FocusListener ne fonctionne pas? – Jerry06

+0

N'utilisez pas un document personnalisé, c'est une ancienne approche. La nouvelle approche consiste à utiliser un 'DocumentFilter'. Consultez [Implémentation d'un DocumentFilter] (http://docs.oracle.com/javase/tutorial/uiswing/components/generaltext.html#filter) pour un exemple de travail. – camickr

+0

Je viens de créer des objets CustomTextField, et je ne peux pas voir les indices. J'utilise focus listener pour montrer l'indice dans la zone de texte –

Répondre

0

Essayez redéfinissant la méthode paintComponent(Graphics graphics) de votre classe CustomTextField. Cela vous aidera à repeindre le champ de texte lorsqu'il n'y a pas d'entrée.

Voici un exemple d'implémentation:

il suffit d'ajouter ce bloc de code dans votre fichier CustomTextField.java.

@Override 
protected void paintComponent(Graphics graphics) { 
    super.paintComponent(graphics); 

    if (hint.isEmpty() || getText().isEmpty() == false) { 
     return; 
    } 

    final Graphics2D g = (Graphics2D) graphics; 
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
    g.setColor(getDisabledTextColor()); 
    g.drawString(hint, getInsets().left, graphics.getFontMetrics().getMaxAscent() + getInsets().top); 
} 

Espérons que cela aide!

1

D'accord, je vais vérifier DocumentFilter en quelques minutes

Vous avez pas changé votre code? DocumentFilter est l'approche préférée car elle est réutilisable. Vous pouvez l'ajouter à n'importe quel document afin qu'il fonctionne pour JTextField, JTextArea, JTextPane.

Les deux conditions fonctionnent. Mais le problème est que si je mets la limite à 6, alors il définit la longueur d'entrée à 6. J'ai besoin de définir une limite supplémentaire.

Vous devez utiliser une approche différente. Par exemple, vous pouvez utiliser la classe Text Prompt. L'invite est indépendante du texte réel, les longueurs peuvent donc être différentes.