我正在运行一个模拟,对到达目的地的对象的移动进行计时,然后在模拟结束后将结果显示在 JTable 上。但是,当包含 JTable 的窗口关闭时,我希望能够再次运行主类。
我正在考虑使用frame.setDefaultCloseOperation();不知何故,但我不确定如何做到这一点。
这是我的代码当前的样子:
public class Main {
public static void main(String[] args) throws InterruptedException {
Scanner scan = new Scanner(System.in);
ArrayList<Integer> inputsA = new ArrayList<>();
ArrayList<Integer> timesA = new ArrayList<>();
System.out.println("Please enter the time for A: ");
int inputA = scan.nextInt();
inputsA.add(inputA);
Simulation sim = new Simulation(inputA);
sim.runSim();
timesA.add(sim.getA());
int length = timesA.size();
Object[][] tableData = new Object[length][2];
for (int i = 0; i < length; i++) {
tableData[i] = new Object[]{inputsA.get(i), timesA.get(i)};
}
JFrame frame = new JFrame();
String[] tableColumn = {"Input A", "Time A"};
TableModel model = new DefaultTableModel(tableData, tableColumn) {
public Class getColumnClass(int column) {
Class returnValue;
if ((column >= 0) && (column < getColumnCount())) {
returnValue = getValueAt(0, column).getClass();
} else {
returnValue = Object.class;
}
return returnValue;
}
};
RowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
JTable table = new JTable(tableData, tableColumn);
table.setBounds(100, 55, 300, 200);
table.setRowSorter(sorter);
JScrollPane jScrollPane = new JScrollPane(table);
frame.add(jScrollPane);
frame.setSize(300, 200);
frame.setVisible(true);
}
}
一个解决方案是
framesetDefaultCloseOperation(JFame.DISPOSE_ON_CLOSE);
以防止关闭JFrame而关闭JVM。但这是 JFrames 的默认设置,因此不需要。这个解决方案简单、直接、容易,但是错误的,因为它没有解决代码中的明显问题,这些问题包括:
相反,我建议你
例如,
import java.awt.BorderLayout;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
public class Main02 {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Simulation");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SimPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
class SimPanel extends JPanel {
private static final long serialVersionUID = 1L;
private JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, 0, 100, 1));
private JButton button = new JButton("Run Simulation");
private static final String[] COLUMN_NAMES = { "Input A", "Time A" };
private DefaultTableModel model = new DefaultTableModel(COLUMN_NAMES, 0);
private JTable table = new JTable(model);
public SimPanel() {
JPanel inputPanel = new JPanel();
inputPanel.add(new JLabel("Time for A: "));
inputPanel.add(spinner);
inputPanel.add(button);
button.addActionListener(e -> {
int inputA = (Integer) spinner.getValue();
Simulation sim = new Simulation(inputA);
sim.runSim();
model.addRow(new Object[] { inputA, sim.getA() });
});
setLayout(new BorderLayout());
add(inputPanel, BorderLayout.PAGE_START);
add(new JScrollPane(table), BorderLayout.CENTER);
}
}
改进是从后台线程(例如 SwingWorker)运行模拟,这样模拟引起的任何时间延迟都不会冻结 GUI。