Listening to many JTextFields and calculate value sum in a Row

余生长醉 提交于 2019-12-11 01:27:50

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!