如何为 JComboBox 中的每个值创建加法分配?

How do i create Addition assignments for every value in a JComboBox?

我有一个 JComboBox,它包含一个带有月份的枚举 class 和一个用于输入每个月完成的工作时数的 JTextfield(txtHours)。

我有另一个 JLabel,它保存以下所有月份的总和值

double hours = Double.parseDouble(txtHours.getText());
            
yearHours += hours;
yLabel.setText("Hours this year: " + yearHours);

我如何保存和更新特定月份的小时数,以便标签在运行时根据从组合框中选择的月份自行更新?

 if (e.getSource() == cmbMonths){

       mLabel.setText("Hours for " + cmbMonths.getSelectedItem() +": " + monthHours);

    }

回答你的问题,即

How can i save and update the amount of hours for a specific month

我会使用 Map where the Map key would be the month and the value would be the total hours worked for that month. In the date-time API, that was added in Java 1.8, there is a Month 枚举,所以我会用它作为 Map 键。

我不会使用 JTextField 输入工作时间,而是使用 JSpinner.

为了更新总工作时数,我会在 JSpinner 模型中添加一个 ChangeListener,以便每次更改其值时,显示 JLabel 的文本总工作时数将更新以显示新的总时数。

唯一剩下的就是向 JComboBox 添加一个 ActionListener,以便在用户选择特定月份时显示输入的总工作时数。

这是一个minimal, reproducible example.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Month;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class EnumCombo implements ActionListener, ChangeListener, Runnable {
    private Map<Month, Double>  hoursWorked;
    private JComboBox<Month>  monthsCombo;
    private JFrame  frame;
    private JLabel  totalHoursLabel;
    private JSpinner  hoursSpinner;

    public EnumCombo() {
        hoursWorked = new HashMap<Month, Double>(12);
        for (Month month : Month.values()) {
            hoursWorked.put(month, Double.valueOf(0));
        }
    }

    @Override // java.awt.event.ActionListener
    public void actionPerformed(ActionEvent event) {
        Object source = event.getSource();
        if (source instanceof JComboBox<?>) {
            JComboBox<?> combo = (JComboBox<?>) source;
            Object obj = combo.getSelectedItem();
            if (obj instanceof Month) {
                Month month = (Month) obj;
                hoursSpinner.setValue(hoursWorked.get(month));
            }
        }
    }

    @Override // javax.swing.event.ChangeListener
    public void stateChanged(ChangeEvent evt) {
        Object source = evt.getSource();
        if (source instanceof SpinnerNumberModel) {
            SpinnerNumberModel snm = (SpinnerNumberModel) source;
            Object obj = snm.getValue();
            if (obj instanceof Double) {
                Double value = (Double) obj;
                hoursWorked.put((Month) monthsCombo.getSelectedItem(), value);
                Double total = hoursWorked.values()
                                          .stream()
                                          .reduce(Double.valueOf(0),
                                                  (tot, val) -> tot + val);
                totalHoursLabel.setText(total.toString());
            }
        }
    }

    @Override
    public void run() {
        showGui();
    }

    private JPanel createInputPanel() {
        JPanel inputPanel = new JPanel();
        JLabel monthLabel = new JLabel("Month");
        inputPanel.add(monthLabel);
        monthsCombo = new JComboBox<Month>(Month.values());
        monthsCombo.addActionListener(this);
        inputPanel.add(monthsCombo);
        JLabel hoursLabel = new JLabel("Hours Worked");
        inputPanel.add(hoursLabel);
        SpinnerNumberModel snm = new SpinnerNumberModel(Double.valueOf(0),
                                                        Double.valueOf(0),
                                                        Double.valueOf(999),
                                                        Double.valueOf(1));
        snm.addChangeListener(this);
        hoursSpinner = new JSpinner(snm);
        inputPanel.add(hoursSpinner);
        return inputPanel;
    }

    private JPanel createTotalPanel() {
        JPanel totalPanel = new JPanel();
        JLabel label = new JLabel("Total Hours");
        totalPanel.add(label);
        totalHoursLabel = new JLabel("0");
        totalPanel.add(totalHoursLabel);
        return totalPanel;
    }

    private void showGui() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(createInputPanel(), BorderLayout.PAGE_START);
        frame.add(createTotalPanel(), BorderLayout.PAGE_END);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new EnumCombo());
    }
}

请注意,上面代码中的方法 stateChanged 使用了 stream API,它也在 Java 1.8

中添加

这是 运行 应用程序的屏幕截图。