简体   繁体   English

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

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

I have a JComboBox that holds an Enum class with months and a JTextfield(txtHours) for entering amount of workhours done for every month.我有一个 JComboBox 包含一个 Enum class 和一个 JTextfield(txtHours) 用于输入每个月完成的工作时间。

I have another JLabel that holds the value for the total of all months below我有另一个 JLabel 持有以下所有月份的总价值

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

How can i save and update the amount of hours for a specific month so that the label updates itself at runtime depending on which month is chosen from the combobox?如何保存和更新特定月份的小时数,以便 label 在运行时根据从 combobox 中选择的月份自行更新?

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

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

    }

To answer your question, namely回答你的问题,即

How can i save and update the amount of hours for a specific month如何保存和更新特定月份的小时数

I would use a Map where the Map key would be the month and the value would be the total hours worked for that month.我会使用Map ,其中Map键是月份,值是该月的总工作时间。 In the date-time API , that was added in Java 1.8, there is a Month enum so I would use that as the Map key.日期时间 API中,这是在 Java 1.8 中添加的,有一个Month枚举,所以我将其用作Map键。

Rather than using a JTextField to enter the hours worked, I would use a JSpinner .我不会使用JTextField输入工作时间,而是使用JSpinner

In order to update the total hours worked, I would add a ChangeListener to the JSpinner model so that each time its value was changed, the text of the JLabel displaying total hours worked would get updated so as to display the new total.为了更新总工作小时数,我会在JSpinner model 中添加一个ChangeListener ,这样每次更改它的值时,显示总工作小时数的JLabel的文本都会更新,以便显示新的总数。

The only thing remaining is to add an ActionListener to the JComboBox such that it displays the entered value for total hours worked whenever the user chooses a particular month.剩下的唯一事情是向JComboBox添加一个ActionListener ,以便在用户选择特定月份时显示输入的总工作时间值。

Here is a 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());
    }
}

Note that method stateChanged , in the above code, uses the stream API which was also added in Java 1.8请注意,上述代码中的方法stateChanged使用stream API ,该方法也在 Java 1.8 中添加

Here is a screen capture of the running app.这是正在运行的应用程序的屏幕截图。

正在运行的应用程序的屏幕截图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM