Focusevent erhält nicht den letzten Wert von JFormattedTextField, wie kann ich es bekommen?
-
25-10-2019 - |
Frage
ich habe zwei JFormattedTextField
Objekte auf meinem JFrame
Objekt. Ich möchte eine grundlegende Mathematik (Zusatz) nach den Werten dieser JFormattedTextField
Objekte. Ich möchte, dass es passieren, wenn der Fokus entweder den ersten oder das zweite Textfeld verloren hat. Aber wenn "focusLost()
", Ereignis erhält nicht den letzten Wert, es erhält den vorherigen Wert.
Zum Beispiel; tf1
hat 0 und tf2
hat zuerst 0. Ich schreibe 2 zu tf1
, und wann focusLost()
, Ergebnis (tf1+tf2
) Werden Sie still 0. Wenn ich eines von ihnen ändere, wird das Ergebnis 2 (der vorherige Wert)
Wie bekomme ich die letzten Werte für Focuslost?
Hier ist mein Code:
JFormattedTextField tf1,tf2;
NumberFormat format=NumberFormat.getNumberInstance();
tf1=new JFormattedTextField(format);
tf1.addFocusListener(this);
tf2=new JFormattedTextField(format);
tf2.addFocusListener(this);
und focusLost()
:
public void focusLost(FocusEvent e) {
if(tf1.getValue() == null) tf1.setValue(0);
if(tf2.getValue() == null) tf2.setValue(0);
//because if I dont set, it throws nullPointerException for tf.getValue()
BigDecimal no1 = new BigDecimal(tf1.getValue().toString());
BigDecimal no2 = new BigDecimal(tf2.getValue().toString());
System.out.println("total: " + (no1.add(no2)));
}
Lösung
Ich denke, Sie sollten a verwenden PropertyChangeListener
, sehen So schreibe ich einen Eigenschaftswechsel -Hörer ändern kann.
Es gibt ein Beispiel verwendet JFormattedTextField
:
//...where initialization occurs:
double amount;
JFormattedTextField amountField;
...
amountField.addPropertyChangeListener("value",
new FormattedTextFieldListener());
...
class FormattedTextFieldListener implements PropertyChangeListener {
public void propertyChanged(PropertyChangeEvent e) {
Object source = e.getSource();
if (source == amountField) {
amount = ((Number)amountField.getValue()).doubleValue();
...
}
...//re-compute payment and update field...
}
}
Andere Tipps
Gibt es einige Defalut -Zahlwertsätze in Ihrem jFormattedTextfield TF1, TF2?
Für mich funktioniert zum Beispiel ohne NPE
import java.awt.*;
import java.awt.event.*;
import java.math.RoundingMode;
import java.text.NumberFormat;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
public class FormatterLimit {
private JFrame frame = new JFrame();
private JPanel pnl = new JPanel();
private JLabel focusLabel = new JLabel(" focusLost Handle ");
private JFormattedTextField formTextField;
private JLabel docLabel = new JLabel(" document Handle ");
private JFormattedTextField formTextField1;
private NumberFormat formTextFieldFormat;
private double amount = 10000.00;
public FormatterLimit() {
formTextFieldFormat = NumberFormat.getNumberInstance();
formTextFieldFormat.setMinimumFractionDigits(2);
formTextFieldFormat.setMaximumFractionDigits(2);
formTextFieldFormat.setRoundingMode(RoundingMode.HALF_UP);
focusLabel.setFont(new Font("Serif", Font.BOLD, 14));
focusLabel.setForeground(Color.blue);
focusLabel.setPreferredSize(new Dimension(120, 27));
formTextField = new JFormattedTextField(formTextFieldFormat);
formTextField.setValue(amount);
formTextField.setFont(new Font("Serif", Font.BOLD, 22));
formTextField.setForeground(Color.black);
formTextField.setBackground(Color.yellow);
formTextField.setPreferredSize(new Dimension(120, 27));
formTextField.setHorizontalAlignment(SwingConstants.RIGHT);
formTextField.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
formTextField.requestFocus();
formTextField.setText(formTextField.getText());
formTextField.selectAll();
}
@Override
public void focusLost(FocusEvent e) {
Runnable doRun = new Runnable() {
@Override
public void run() {
double t1a1 = (((Number) formTextField.getValue()).doubleValue());
if (t1a1 < 1000) {
formTextField.setValue(amount);
}
}
};
SwingUtilities.invokeLater(doRun);
}
});
docLabel.setFont(new Font("Serif", Font.BOLD, 14));
docLabel.setForeground(Color.blue);
docLabel.setPreferredSize(new Dimension(120, 27));
formTextField1 = new JFormattedTextField(formTextFieldFormat);
formTextField1.setValue(amount);
formTextField1.setFont(new Font("Serif", Font.BOLD, 22));
formTextField1.setForeground(Color.black);
formTextField1.setBackground(Color.yellow);
formTextField1.setPreferredSize(new Dimension(120, 27));
formTextField1.setHorizontalAlignment(SwingConstants.RIGHT);
formTextField1.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
formTextField1.requestFocus();
formTextField1.setText(formTextField1.getText());
formTextField1.selectAll();
}
@Override
public void focusLost(FocusEvent e) {
}
});
formTextField1.getDocument().addDocumentListener(docListener);
pnl = new JPanel();
pnl.setBorder(new EmptyBorder(2, 2, 2, 2));
pnl.setLayout(new GridLayout(2, 2));
pnl.add(focusLabel);
pnl.add(formTextField);
pnl.add(docLabel);
pnl.add(formTextField1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(pnl, BorderLayout.CENTER);
frame.setLocation(200, 200);
frame.pack();
frame.setVisible(true);
formTextFieldFocus();
}
//
private DocumentListener docListener = new DocumentListener() {
@Override
public void changedUpdate(DocumentEvent documentEvent) {
printIt(documentEvent);
}
@Override
public void insertUpdate(DocumentEvent documentEvent) {
printIt(documentEvent);
}
@Override
public void removeUpdate(DocumentEvent documentEvent) {
printIt(documentEvent);
}
private void printIt(DocumentEvent documentEvent) {
DocumentEvent.EventType type = documentEvent.getType();
double t1a1 = (((Number) formTextField1.getValue()).doubleValue());
if (t1a1 < 1000) {
Runnable doRun = new Runnable() {
@Override
public void run() {
formTextField1.setValue(amount);
}
};
SwingUtilities.invokeLater(doRun);
}
}
};
public void formTextFieldFocus1() {
Runnable doRun = new Runnable() {
@Override
public void run() {
formTextField1.grabFocus();
formTextField1.requestFocus();
formTextField1.setText(formTextField1.getText());
formTextField1.selectAll();
}
};
SwingUtilities.invokeLater(doRun);
}
public void formTextFieldFocus() {
Runnable doRun = new Runnable() {
@Override
public void run() {
formTextField.grabFocus();
formTextField.requestFocus();
formTextField.setText(formTextField.getText());
formTextField.selectAll();
formTextFieldFocus1();
}
};
SwingUtilities.invokeLater(doRun);
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
FormatterLimit fl = new FormatterLimit();
}
});
}
}
Das Standardverhalten von JFormattedTextField
an focusLost
ist COMMIT_OR_REVERT
, Ein Ansatz ist also, das Update durchzuführen nach Der Focus -Hörer hat abgeschlossen. EIN Fortsetzung funktioniert gut, wie unten gezeigt.
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.text.NumberFormat;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
/** @see http://stackoverflow.com/questions/6803976 */
public class Adder extends JPanel {
private final NumberFormat format = NumberFormat.getNumberInstance();
private final JFormattedTextField a = new JFormattedTextField(format);
private final JFormattedTextField b = new JFormattedTextField(format);
private final JFormattedTextField sum = new JFormattedTextField(format);
public Adder() {
this.setLayout(new GridLayout(0, 1));
this.add(init(a));
this.add(init(b));
sum.setEditable(false);
sum.setFocusable(false);
this.add(sum);
}
private JFormattedTextField init(JFormattedTextField jtf) {
jtf.setValue(0);
jtf.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
Number v1 = (Number) a.getValue();
Number v2 = (Number) b.getValue();
sum.setValue(v1.longValue() + v2.longValue());
}
});
}
});
return jtf;
}
private void display() {
JFrame f = new JFrame("Adder");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Adder().display();
}
});
}
}