In Java / Swing, c'è un modo per legalmente “tentare di mutare in comunicazione”?
-
02-10-2019 - |
Domanda
mi chiedevo se v'è una sorta di magia posso usare per andare in giro un IllegalStateException e permettere un JTextField a "tentare di mutare in comunicazione", o in altre parole per impostare il proprio testo se il suo ascoltatore viene attivato.
Per vostra informazione, sto cercando di programmare una funzione di completamento automatico che restituisce il più probabile partita in una gamma di 12 enumerazioni in risposta all'input di un utente nel JTextField.
Ecco il codice di esempio. Dovrai perdonare il mio algoritmo goffa che scricchiola fuori risultati enum. Ho evidenziato il codice che produce l'eccezione con un commento:
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());
}
}
});
Soluzione
Si sono probabilmente meglio utilizzare un filtro documento o un documento personalizzato.
Quali sono altri ascoltatori aspetta di vedere se il documento non rimane la stessa durante la propagazione dell'evento?
Altri suggerimenti
Usa SwingUtilities.invokeLater () mettendo tutte le modifiche non
Forse si può ritardare la setText () con un filo a rincorrere caretUpdate () è terminato.
sto trovato sullo stesso problema, ma ho trovato una soluzione facile:
bloccare il caretUpdate () di un valore booleano se (false), mentre u'r impostando il testo al JTextField di sblocco dopo. . qualcosa di simile a questo:
booleano cursore = true;
private void listValueChanged (javax.swing.event.ListSelectionEvent EVT) { cursore = falso; name.setText ((String) list.getSelectedValue ()); accento circonflesso = true; }
private void nameCaretUpdate(javax.swing.event.CaretEvent evt) {
if(caret){
model = new DefaultListModel();
this.fillList(name.getText());
list.setModel(model);
}
}
Creare un costume di documenti e di esclusione 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);
}
}
}
}
Si noti che chiamando setText si tradurrà in una chiamata ricorsiva a insertString (), quindi assicuratevi di avere una condizione di arresto.
Sono sorpreso che nessuno ha risposto a questa, ma would'nt sei stato meglio l'implementazione di un modificabile JSpinner con un SpinnerListModel ?