In Java / Swing, gibt es eine Möglichkeit, um legal „versuchen, in Benachrichtigung zu mutieren“?
-
02-10-2019 - |
Frage
Ich frage mich, ob es irgendeine Art von Magie kann ich eine Illegal umgehen und ermöglichen eine JTextField zu „versuchen, in Benachrichtigung zu mutieren“, oder mit anderen Worten, einen eigenen Text zu setzen, wenn seine Zuhörer ausgelöst wird.
Zur Information: Ich versuche, ein Auto-Vervollständigung zu programmieren, die die wahrscheinlichste Übereinstimmung in einem Bereich von 12 Aufzählungen in Reaktion kehrt zu einem Eingabe des Benutzers in der JTextField.
Hier ist das Codebeispiel. Sie müssen meinen ungeschickten Algorithmus begnadigen, die Enum Ergebnisse knarzt aus. Ich habe den Code hervorgehoben, die die Ausnahme mit einem Kommentar erzeugt:
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());
}
}
});
Lösung
Sie sind wahrscheinlich besser dran, ein Dokument Filter oder ein benutzerdefiniertes Dokument verwendet wird.
Was andere Zuhörer erwartet, um zu sehen, ob das Dokument nicht das gleiche bei Event Dispatch nicht bleiben?
Andere Tipps
Mit SwingUtilities.invokeLater () setzt alle Änderungen dort
Vielleicht können Sie die setText verzögern () mit einem Gewinde nach caretUpdate laufen () beendet hat.
Ich bin auf dem gleichen Problem gefunden, aber ich fand eine einfache Lösung:
sperrt die caretUpdate () von einer boolean if (false), während u'r den Text in die JTextField als Unlock Einstellung nach. . so etwas wie folgt aus:
boolean caret = true;
private void listValueChanged (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);
}
}
Erstellen Sie eine benutzerdefinierte Dokument und überschreiben insert ()
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);
}
}
}
}
Beachten Sie, dass setText Aufruf in einem rekursiven Aufruf insert () resultiert, so stellen Sie sicher, dass Sie eine Stoppbedingung.
Ich bin überrascht, niemand hat diese beantwortet, aber would'nt Sie besser gewesen off eine editierbare Implementierung JSpinner mit einem