I have two JFormattedTextField
objects on my JFrame
object. I want a basic Math (addition) by the values of these JFormattedTextField
objects. I want it happen when focus lost either the first or the second textfield. But when "focusLost()
", event doesn't get the last value, it gets the previous value.
For example; tf1
has 0 and tf2
has 0 at first. I write 2 to tf1
, and when focusLost()
, result (tf1+tf2
) become still 0. when I change an开发者_如何学Goy of them, the result becomes 2 (the previous value)
How do I get the last values on focusLost?
Here is my code:
JFormattedTextField tf1,tf2;
NumberFormat format=NumberFormat.getNumberInstance();
tf1=new JFormattedTextField(format);
tf1.addFocusListener(this);
tf2=new JFormattedTextField(format);
tf2.addFocusListener(this);
and 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)));
}
I think you should use a PropertyChangeListener
, see How to Write a Property Change Listener.
There is an example using 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...
}
}
is there some defalut Number value sets in your JFormattedTextField tf1,tf2;
for me works without NPE, for example
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();
}
});
}
}
The default behavior of JFormattedTextField
on focusLost
is COMMIT_OR_REVERT
, so one approach is to do the update after the focus listener has concluded. A continuation works nicely, as shown below.
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();
}
});
}
}
精彩评论