问题描述
我有一个 JComboBox,其中包含一个带有月份的 Enum 类和一个 JTextfield(txtHours),用于输入每个月完成的工作时间。
run
如何保存和更新特定月份的小时数,以便标签在运行时根据从组合框中选择的月份自行更新?
>>> all_output = subprocess.run(["RNAcofold.exe","ATGTTGG&CCGTGT"],capture_output=True,shell=True)
>>> all_output.stdout
b'this is\nthe content\nof test.txt\n'
>>> all_output.stderr
b''
And so on...
解决方法
回答你的问题,即
如何保存和更新特定月份的小时数
我会使用 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
使用了 stream API,它也是在 Java 1.8 中添加的
这是正在运行的应用程序的屏幕截图。