回答你的问题,即
如何保存和更新特定月份的小时数
我会使用Map,其中Map 键是月份,值是该月的总工作时间。在 Java 1.8 中添加的 date-time API 中,有一个 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 方法使用了在 Java 1.8 中也添加的 stream API
这是正在运行的应用程序的屏幕截图。