En Java / Swing, est-il un moyen légalement « essayer de muter dans la notification »?
-
02-10-2019 - |
Question
Je me demandais s'il y a une sorte de magie que je peux utiliser pour se déplacer d'un IllegalStateException et permettre à un JTextField de « tenter de muter dans la notification », ou en d'autres termes pour définir son propre texte si son auditeur est déclenché.
Pour votre information, je suis en train de programmer une fonction de remplissage automatique qui retourne le plus probable dans un match de gamme de 12 énumérations en réponse à l'entrée d'un utilisateur dans le JTextField.
Voici l'exemple de code. Vous devez pardonner mon algorithme maladroit qui grince des résultats enum. J'ai mis en évidence le code qui produit l'exception d'un commentaire:
jtfElement1.addCaretListener(new CaretListener() {
@Override
public void caretUpdate(CaretEvent e) {
String s = jtfElement1.getText();
int[] attributes = new int[13];
// iterate through each enum
for (BaseEnumAttributes b: BaseEnumAttributes.values()) {
// iterate through the length of the current text in jtfElement1
for (int i = 0; i < s.length(); i++) {
if (s.length() <= b.toString().length()) {
if (b.toString().charAt(i) == s.charAt(i)) {
// increase the number of "hits" noted for that enum
attributes[b.ordinal()] = attributes[b.ordinal()] + 1;
}
}
}
}
int priorC = 0;
int rightC = 0;
// iterate through the "array" of enums to find the highest score
for (int j = 0; j < attributes.length; j++) {
if (attributes[j] > priorC) {
priorC = attributes[j];
rightC = j;
}
}
if (!s.equals("")) {
// assign to b the Enum corresponding to the "array" with highest score
BaseEnumAttributes b = BaseEnumAttributes.values()[rightC];
iController.updateInputElement1String(b.toString());
// THIS TRIGGERS EXCEPTION
jtfElement1.setText(b.toString());
}
}
});
La solution
Vous êtes probablement mieux d'utiliser un filtre ou un document personnalisé.
Quels sont les autres auditeurs devraient voir si le document ne reste pas le même lors de l'envoi de l'événement?
Autres conseils
Utilisez SwingUtilities.invokeLater () placer toutes les modifications y
Peut-être que vous pouvez retarder la setText () avec un fil à courir après caretUpdate () a pris fin.
Je trouve sur le même problème, mais j'ai trouvé une solution simple:
verrouiller le caretUpdate () par un booléen si (false) en u'r la définition du texte au JTextField que le déverrouiller après. . quelque chose comme ceci:
boolean caret = true;
listValueChanged private void (javax.swing.event.ListSelectionEvent EVT) { caret = false; name.setText ((String) list.getSelectedValue ()); caret = true; }
private void nameCaretUpdate(javax.swing.event.CaretEvent evt) {
if(caret){
model = new DefaultListModel();
this.fillList(name.getText());
list.setModel(model);
}
}
Créer une coutume document et override insertString ()
filenameText = new JTextField(new FilenameDocument(), "", 0);
...
/**
* document which adds .xml extension if not specified
*
*/
private class FilenameDocument extends PlainDocument {
@Override
public void insertString(int offset, String insertedText, AttributeSet set)
throws BadLocationException {
if (offset == 0) {
insertedText = insertedText.trim( );
}
super.insertString(offset, insertedText, set);
if (filenameText != null) {
final int caretPos = filenameText.getCaretPosition();
String text = filenameText.getText().trim();
if (text.indexOf('.') == -1) {
filenameText.setText(text + ".xml");
filenameText.setCaretPosition(caretPos);
}
}
}
}
Notez que l'appel setText se traduira par un appel récursif à insertString (), alors assurez-vous que vous avez une condition d'arrêt.
Je suis surpris que personne n'a répondu, mais would'nt vous avez été mieux mettre en œuvre un éditable JSpinner avec