问题
I have an application that gets input from user;
it has 8 rows of JTextFields
with 3 columns:
+-----------+-----------+-----------+
| Field 1-1 | Field 1-2 | Field 1-3 |
+-----------+-----------+-----------+
| Field 2-1 | Field 2-2 | Field 2-3 |
+-----------+-----------+-----------+
| Field 3-1 | Field 3-2 | Field 3-3 |
+-----------+-----------+-----------+
In each row while user changes first or second field the sum of new values must be written in third field.
For example when user changes Filed 1-1 & Field 1-2 sum of them must be calculated and shown in Field 1-3 and so on for other rows.
I wrote a Class that implements DocumentListener
and and named it listenerClass
& called .getDocument().addDocumentListener(new listenerClass)
for all of JTextFields
in column 1 & 2 ;
Now in listenerClass
I need to know which JTextField
called listenerClass
to be able determine wich fields must be added and result must be written in which JTextField
.
How Can I find out which JTextField
called DocumentListener
?
Is there any better method to do this?
Thanks
回答1:
You have two options here:
- brute force: just one listener instance that will compute 8 sums and update 8 text fields
- smart: pass to your listener class constructor 3 text fields and then instantiate a differente listener for each row
回答2:
put a property with putClientProperty method on each JTextField. You can use that property as an id, and get it back inside the listener. For example:
JTextField 1_1 = new JTextField();
1_1.putClientProperty("id", "1_1");
EDIT: Sorry, I was forgetting that you don't have a reference to source object inside listener. SO it's better also do:
JTextField 1_1 = new JTextField();
1_1.getDocument.putProperty("source", 1_1);
the from inside the listener you can do:
public void insertUpdate(DocumentEvent documentEvent) {
//source
Object source = documentEvent.getDocument().getProperty("source");
if (source instanceof JTextField){
JTextField field = (JTextField)source;
String id = field.getClientProperty("id");
}
}
I asked a similar question some months ago: have a look here.
回答3:
consider using JTable instead of plenty of JTextFields or JFormattedTextFields and listening by some of Listeners

from code
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class TableProcessing extends JFrame implements TableModelListener {
private static final long serialVersionUID = 1L;
private JTable table;
public TableProcessing() {
String[] columnNames = {"Item", "Quantity", "Price", "Cost"};
Object[][] data = {
{"Bread", new Integer(1), new Double(1.11), new Double(1.11)},
{"Milk", new Integer(1), new Double(2.22), new Double(2.22)},
{"Tea", new Integer(1), new Double(3.33), new Double(3.33)},
{"Cofee", new Integer(1), new Double(4.44), new Double(4.44)}
};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
model.addTableModelListener(this);
table = new JTable(model) {
private static final long serialVersionUID = 1L;
@Override
public Class getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
@Override
public boolean isCellEditable(int row, int column) {
int modelColumn = convertColumnIndexToModel(column);
return (modelColumn == 3) ? false : true;
}
};
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.add(scrollPane);
frame.pack();
frame.setLocation(150, 150);
frame.setVisible(true);
}
@Override
public void tableChanged(TableModelEvent e) {
System.out.println(e.getSource());
if (e.getType() == TableModelEvent.UPDATE) {
int row = e.getFirstRow();
int column = e.getColumn();
if (column == 1 || column == 2) {
TableModel model = table.getModel();
int quantity = ((Integer) model.getValueAt(row, 1)).intValue();
double price = ((Double) model.getValueAt(row, 2)).doubleValue();
Double value = new Double(quantity * price);
model.setValueAt(value, row, 3);
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
TableProcessing frame = new TableProcessing();
}
});
}
}
回答4:
Use yourTextField.setName("Alice")
, then in your DocumentListener implementation retrieve the name with with getName()
and check for "Alice".
These methods belong to the java.awt.Component
class. Every swing JComponent extends from it.
来源:https://stackoverflow.com/questions/7483867/listening-to-many-jtextfields-and-calculate-value-sum-in-a-row