java - 如何向 JTextField 添加动态变量?

标签 java swing jtable counting

this is my output generated. As you can see the JTextField isn't being modified according to the totalValue

enter image description here

我是 Java 初学者,我需要这方面的帮助;我正在使用 JTable 制作 POS 系统。

将成本(列)加在一起时,我很难获得正确的总数,但我没有任何错误。

我目前的主要问题是:如何在 jtextfield 中添加动态变量。例如,当我在数量列中编辑一个数字时,如何才能在 jtextfield 中显示新的总数。我的 jtextfield (totalField) 永远不会更新。

这是我的一段代码;

   public class EditableTable extends JPanel {

   private JTextField filterField = new JTextField();
   private JButton filterButton = new JButton("Filter");
   public JTextField totalField = new JTextField(10);


   private JScrollPane scroll;
   public JPanel panel = new JPanel(new BorderLayout());
   public JPanel filterPanel = new JPanel(new BorderLayout());  
   public JPanel receiptPanel = new JPanel(new BorderLayout());
   public JPanel transactionPanel = new JPanel();
   JPanel cashPanel = new JPanel();
   JPanel totalPanel = new JPanel();

   private TableModelListener tableModelListener;


   ProductsTableModel model = new ProductsTableModel();
   final JTable table = new JTable(model);

   Double total;
   double totalValue; 
   double payment;

   public JLabel cashLab = new JLabel("Cash");
   public JTextField cashInput = new JTextField(10);

   public JLabel totalLab = new JLabel("Total");

   public JLabel changeLab = new JLabel("");

   public JButton confirmButton = new JButton("Confirm");
   public double change;


public EditableTable(){


    table.getModel().addTableModelListener(new CheckBoxModelListener());
    // final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
    final TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(table.getModel());
    table.setRowSorter(rowSorter);


    table.setPreferredScrollableViewportSize(new Dimension(500, 700));
    table.setFillsViewportHeight(true);
    table.setCellSelectionEnabled(true);
    KeyStroke tab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB,0);
    InputMap map = table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
    map.put(tab, "selectNextRowCell");


    scroll = new JScrollPane(table);

    filterPanel.add(new JLabel("Specify a word to match: "), BorderLayout.WEST);
    filterPanel.add(filterField, BorderLayout.CENTER);






    filterField.getDocument().addDocumentListener(new DocumentListener(){

        @Override
        public void insertUpdate(DocumentEvent e){
            String text = filterField.getText();

            if(text.trim().length() == 0){
                rowSorter.setRowFilter(null);
            }else{
                rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));
            }
        }

        @Override
        public void removeUpdate(DocumentEvent e){
            String text = filterField.getText();

            if(text.trim().length() == 0){
                rowSorter.setRowFilter(null);
            }else{
                rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));
            }
        }

        @Override
        public void changedUpdate(DocumentEvent e){
            throw new UnsupportedOperationException("Not supported yet.");
        }
    });

    panel.add(scroll, BorderLayout.CENTER);
    panel.add(filterPanel, BorderLayout.SOUTH);

    cashPanel.add(cashLab);
    cashPanel.add(cashInput);
    receiptPanel.add(cashPanel, BorderLayout.CENTER); 

    cashInput.addActionListener(new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent e){
            payment = Double.parseDouble(cashInput.getText());
            change = payment - totalValue;
            changeLab.setText("" + change);
            System.out.println("Change" + change);
        }
    });


    receiptPanel.add(new JLabel("Change " + change), BorderLayout.SOUTH);
    totalPanel.add(totalLab);
    totalPanel.add(totalField);
    receiptPanel.add(totalPanel, BorderLayout.NORTH);

   table.getModel().addTableModelListener(new TableModelListener(){
       @Override
       public void tableChanged(TableModelEvent ev){
           if(ev.getColumn() == 3|| ev.getColumn() == 4){
               calculateTotal();
            }
        }
    });


}

//Simple method to calculate the total and set it to the JTextField
public void calculateTotal(){
    double total = 0d;
    int numOfRows = table.getRowCount();
    for(int i = 0; i < numOfRows; i++){
        Object cost = table.getValueAt(i,5);
        if(cost instanceof Number){
            total += ((Number)cost).doubleValue();
        }
    }
    System.out.println("Total" + total);

    totalField.setText(NumberFormat.getNumberInstance().format(total));
    System.out.println("I DID IT");
}


}

非常感谢任何帮助

这是我的最新更新!我认为我的 receiptPanel 中可能存在问题,其中涉及 totalField

最佳答案

对于许多评论,我发布了一个答案,以便您了解如何使用 TableModel 和监听器。

    table = new JTable();
    //I override the getValueAt see @mKorbel comments so that columns 5
    //return the value of 3*4 (you should not to calculate and set this from   
    //the listener, setting the value will recall the listener again)
    table.setModel(new DefaultTableModel() {

        @Override
        public Object getValueAt(int row, int column) {
            if (column == 5) {
                Object price = super.getValueAt(row, 3);
                Object quantity = super.getValueAt(row, 4);
                if (price instanceof Number && quantity instanceof Number) {
                    return ((Number) price).doubleValue() * ((Number) quantity).intValue();

                }
                return 0d;
            }
            return super.getValueAt(row, column);
        }

    });

    //I use the listener to understand if column 3 or 4 is changed
    //to recalculate my totale. I have also added code to detect inseration/delation of rows.
    table.getModel().addTableModelListener(new TableModelListener() {

        @Override
        public void tableChanged(TableModelEvent ev) {
            switch(ev.getType()){
            case TableModelEvent.UPDATE:
                if (ev.getColumn() == 3 || ev.getColumn() == 4) {
                    calculateTotale();
                }
                return;
            case TableModelEvent.INSERT:
            case TableModelEvent.DELETE:
                calculateTotale();
                break;
            }
        }
    });
}

//Simple metod to calculate the total and set it to the JTextField.
public void calculateTotale() {
    double tot = 0d;
    int numOfRows = table.getRowCount();
    for (int i = 0; i < numOfRows; i++) {
        Object cost = table.getValueAt(i, 5);
        if (cost instanceof Number) {
            tot += ((Number) cost).doubleValue();
        }
    }
    totalField.setText(NumberFormat.getNumberInstance().format(tot));
    System.out.println("I DID IT!!");
}

请注意,这不是复制和过去的代码,它是一个简短的代码示例,可让您了解 JTable 的工作原理。

如果您在控制台中看到I DID IT!!并且JTextField没有改变,则totalField不是您认为的totalField!...我猜测可能是;您正在执行 new JTextField(),将其添加到布局中,然后再次执行 new JTextField()(这会更改其引用)。

关于java - 如何向 JTextField 添加动态变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33500981/

相关文章:

java - 将 byte[] 转换为 AES key

java - 如何获取当前单元格被点击的表格?

java - 如何将对象中的数据插入到 Eclipse 生成的 JTable 中? (请不要数据库)

java - 使用面板管理 pressButton

mysql - 如何解决 MySQLSyntaxErrorException

java - Paint 组件陷入无限循环,导致 stackoverflow 错误。为什么是这样?

java - 包含新闻文章的文本区域 - SQL 插入(开始新行)

java - Jackson 使用 Spring Boot 基于深度的序列化

java - 正确编码 - 使用 UTF-8 - java

java - 如何在 Mac OSX 上安装 Java 以允许版本切换?