[英]JFrame pane won't let another button to be clicked when re-opening it
所以我有一个问题,我需要一个乘客只能选择一个座位。 第一次运行时就可以了。 但是,在第二次,第三次,第四次等加载时,但是用户无法选择其他选择。 有任何想法吗?
import java.awt.event.*;
import java.awt.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import java.lang.reflect.Constructor;
public class APlaneSeats {
JFrame frame = new JFrame("Flight");
JPanel panel = new JPanel();
int rows = 8;
int columns = 2;
public static void main(String[] args) {
new APlaneSeats();
}
public APlaneSeats() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
panel.setLayout(new GridLayout(rows, columns));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Seatings();
frame.add(panel);
frame.setSize(250,150);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public void Seatings(){
JPanel lSeats= loadSeats();
if(lSeats == null){
for (int row = 0; row < rows; row++) {
String[] rowChar = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
for (int column = 1; column < columns + 1; column++) {
final JToggleButton button = new JToggleButton(rowChar[row] + column);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
AbstractButton abstractButton = (AbstractButton) actionEvent.getSource();
boolean selected = abstractButton.getModel().isSelected();
if (selected) {
// System.out.println(selected);
button.setText("Booked");
} else {
button.setText(" ");
}
//JPanel bComp = (JPanel)SwingUtilities.getWindowAncestor(button).getComponent(0) ;
//JButton[] buttonArray = Arrays.copyOf(bComp, bComp.length, JButton[].class);
saveSeats(panel);
SwingUtilities.getWindowAncestor(button).dispose();
}
});
panel.add(button);
}
}
panel.setSize(250,150);
}
else{
panel = lSeats;
for (int row = 0; row < rows; row++) {
String[] rowChar = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
for (int column = 1; column < columns + 1; column++) {
final JToggleButton button = new JToggleButton(rowChar[row] + column);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
AbstractButton abstractButton = (AbstractButton) actionEvent.getSource();
boolean selected = abstractButton.getModel().isSelected();
if (selected) {
// System.out.println(selected);
button.setText("Booked");
} else {
button.setText(" ");
}
//JPanel bComp = (JPanel)SwingUtilities.getWindowAncestor(button).getComponent(0) ;
//JButton[] buttonArray = Arrays.copyOf(bComp, bComp.length, JButton[].class);
saveSeats(panel);
SwingUtilities.getWindowAncestor(button).dispose();
panel.add(button);
}
});
}
}
}
}
private JPanel loadSeats(){
ObjectInputStream inputFile;
try{ //To locate and open the file
inputFile = new ObjectInputStream(new BufferedInputStream(new FileInputStream("seats.rsy")));
}catch(FileNotFoundException fnf){
return null;
}catch(IOException io){
JOptionPane.showMessageDialog(null,"An error was encountered. \n\n"+io.toString(),"Error", JOptionPane.ERROR_MESSAGE);
return null;
}
try{
JPanel loadedObject = (JPanel)inputFile.readObject(); //Loads the contents of the file.
inputFile.close(); //Closes the stream
return loadedObject;
}catch(IOException io){
JOptionPane.showMessageDialog(null,"An error was encountered. \n\n"+io.toString(),"Error", JOptionPane.ERROR_MESSAGE);
return null;
}catch(ClassNotFoundException cnf){
JOptionPane.showMessageDialog(null,"An error was encountered. \n\n"+cnf.toString(),"Error", JOptionPane.ERROR_MESSAGE);
return null;
}
}
private void saveSeats(JPanel sSeats){
try{
ObjectOutputStream outputFile = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("seats.rsy"))); //Opens the ObjectOutputStream and a FileOutputStream (whcih is used to write to files).
outputFile.writeObject(sSeats); //Writes the object into the file
outputFile.flush(); //Flushes any data from the buffer to the file
outputFile.close(); //Closes the stream since the output is done
}catch(IOException io){
JOptionPane.showMessageDialog(null,"An error was encountered. \n\n"+io.toString(),"Error", JOptionPane.ERROR_MESSAGE);
}
}
}
您需要第二次将按钮的添加移到侦听器之外:
SwingUtilities.getWindowAncestor(button).dispose();
panel.add(button);
}
});
应该是这样的:
SwingUtilities.getWindowAncestor(button).dispose();
}
});
panel.add(button);
UI组件的序列化是一个坏主意。 似乎在对JPanel
反序列化时,尚未重新注册ActionListener
。
同样,从文件加载对象时,您不应该重新构造JToggleButton
,您应该将其直接添加到屏幕上
if (lSeats == null) {
//...
} else {
frame.remove(panel);
panel = lSeats;
frame.add(panel);
}
这样就包含了您先前创建的所有按钮。 问题是, ActionListener
似乎不是序列化数据的一部分
更好的选择是序列化数据,可能使用JAXB或Properties
文件,或者仅使用纯文本。 这样可以将数据与视图分开,并使其更易于管理。
例如...
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class APlaneSeats {
JFrame frame = new JFrame("Flight");
JPanel panel = new JPanel();
int rows = 8;
int columns = 2;
private Map<String, Boolean> bookings;
public static void main(String[] args) {
new APlaneSeats();
}
public APlaneSeats() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
panel.setLayout(new GridLayout(rows, columns));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Seatings();
frame.add(panel);
frame.setSize(250, 150);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public void Seatings() {
bookings = loadSeats();
for (String key : bookings.keySet()) {
JToggleButton button = new JToggleButton(new BookingAction(key, bookings.get(key)));
panel.add(button);
}
}
private Map<String, Boolean> loadSeats() {
bookings = new HashMap<>(rows * columns);
String[] rowChar = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
for (int row = 0; row < rows; row++) {
for (int column = 1; column < columns + 1; column++) {
bookings.put(rowChar[row] + column, false);
}
}
File seats = new File("Seats.properties");
if (seats.exists()) {
Properties p = new Properties();
try (InputStream is = new FileInputStream(seats)) {
p.load(is);
for (Object key : p.keySet()) {
bookings.put(key.toString(), Boolean.parseBoolean(p.getProperty(key.toString())));
}
} catch (IOException exp) {
exp.printStackTrace();
JOptionPane.showMessageDialog(null, "An error was encountered. \n\n" + exp.toString(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
return bookings;
}
private void saveSeats() {
Properties p = new Properties();
for (String key : bookings.keySet()) {
p.put(key, bookings.get(key).toString());
}
try (OutputStream os = new FileOutputStream("Seats.properties")) {
p.store(os, "Bookings");
} catch (IOException exp) {
exp.printStackTrace();
JOptionPane.showMessageDialog(null, "An error was encountered. \n\n" + exp.toString(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
protected void setBooked(String name) {
bookings.put(name, true);
saveSeats();
frame.dispose();
}
public class BookingAction extends AbstractAction {
public BookingAction(String name, boolean booked) {
super(booked ? "Booked" : name);
putValue(SELECTED_KEY, booked);
setEnabled(!booked);
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
setBooked((String) getValue(NAME));
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.