简体   繁体   English

重新打开JFrame窗格时,不允许单击另一个按钮

[英]JFrame pane won't let another button to be clicked when re-opening it

So I have this problem, where I need a passenger to only select on 1 seat. 所以我有一个问题,我需要一个乘客只能选择一个座位。 When running it the first time it's fine. 第一次运行时就可以了。 However on the second, third, fourth etc... times it loads but the user cannot select another selection. 但是,在第二次,第三次,第四次等加载时,但是用户无法选择其他选择。 Any ideas? 有任何想法吗?

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);
    }
}
}

You need to move the adding of the buttons at the second times out side the listener: 您需要第二次将按钮的添加移到侦听器之外:

        SwingUtilities.getWindowAncestor(button).dispose();
        panel.add(button);
    }
});

Should be look like: 应该是这样的:

        SwingUtilities.getWindowAncestor(button).dispose();
    }
});
panel.add(button);

Serialisation of UI components is bad, bad idea. UI组件的序列化是一个坏主意。 It appears that when you deserialise the JPanel , the ActionListener s are not been re-registered. 似乎在对JPanel反序列化时,尚未重新注册ActionListener

Also, you shouldn't be re-constructing the JToggleButton s when you've loaded the object from a file, you should be adding directly to the screen 同样,从文件加载对象时,您不应该重新构造JToggleButton ,您应该将其直接添加到屏幕上

    if (lSeats == null) {
        //...
    } else {
        frame.remove(panel);
        panel = lSeats;
        frame.add(panel);
    }

As that carries all the buttons you created previously. 这样就包含了您先前创建的所有按钮。 Problem is, the ActionListener s don't seem to be part of the serialised data 问题是, ActionListener似乎不是序列化数据的一部分

A better choice would be to serialise the data, maybe using JAXB or a Properties file or just plain text. 更好的选择是序列化数据,可能使用JAXB或Properties文件,或者仅使用纯文本。 This separates the data from the view and makes more manageable.... 这样可以将数据与视图分开,并使其更易于管理。

For example... 例如...

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.

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