简体   繁体   中英

Close JFrame pane when button is clicked

I'm trying to use close the pane from an airplane seat system, so each passenger chooses only 1 seat. I researched and know I need a line of code JFrame.dispose(); But I don't know where to put it and what else to put it. Thoughts? (Other than that I'm a complete noob XD)

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class APlaneJToggle {

private int rows = 15;
private int columns = 6;
private Icon res = (UIManager.getIcon("OptionPane.errorIcon"));

public APlaneJToggle() {
    JPanel panel = new JPanel(new GridLayout(rows, columns));
    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) {
                            button.setIcon(res);
                        } else {
                            button.setIcon(null);
                        }
                    }
                });
            panel.add(button);
        }
    }
    final JFrame frame = new JFrame("Flight");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(panel);
    frame.pack();
    frame.setLocation(300, 100);
    frame.resize(750,450);
    frame.isDefaultLookAndFeelDecorated();
    frame.setVisible(true);
}

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                APlaneJToggle aPlaneJToggle = new APlaneJToggle();
            }
        });
}
}

Suggestions:

  1. I'm guessing that you want to allow the user to only select one button. If so, then perhaps a better solution: use a ButtonGroup and add all the JToggleButtons to the single ButtonGroup. This way the user still can select another seat, but the previous seat will become unselected.
  2. Use an ItemListener not an ActionListener if you go this route.
  3. The calling code can easily get the selected button from the ButtonGroup object.
  4. If this window will be displayed from another top level JFrame window, it is better off as a JDialog and not a JFrame.

For example (better late than never)

import java.awt.*;
import java.awt.Dialog.ModalityType;
import java.awt.event.*;
import java.awt.image.BufferedImage;

import javax.swing.*;

@SuppressWarnings("serial")
public class APlaneJToggleTest extends JPanel {
   private DefaultListModel<String> seatListModel = new DefaultListModel<>();
   private JList<String> selectedSeatList = new JList<>(seatListModel);
   private JButton getSeatSelectionBtn = new JButton(new GetSelectionAction("Get Selected Button"));
   private JDialog getSeatDialog;
   private APlaneJToggle aPlaneJToggle = new APlaneJToggle();

   public APlaneJToggleTest() {
      selectedSeatList.setVisibleRowCount(8);
      String prototype = String.format("%20s", " ");
      selectedSeatList.setPrototypeCellValue(prototype);

      add(getSeatSelectionBtn);
      add(new JScrollPane(selectedSeatList));
   }

   private class GetSelectionAction extends AbstractAction {
      public GetSelectionAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         if (getSeatDialog == null) {
            Window win = SwingUtilities.getWindowAncestor(APlaneJToggleTest.this);
            getSeatDialog = new JDialog(win, "Choose Seat", ModalityType.APPLICATION_MODAL);
            getSeatDialog.add(aPlaneJToggle.getMainPanel());
            getSeatDialog.setResizable(false);
            getSeatDialog.pack();
         }
         getSeatDialog.setVisible(true);
         ButtonModel model = aPlaneJToggle.getSelectedModel();
         if (model != null) {
            String actionCommand = model.getActionCommand();
            seatListModel.addElement(actionCommand);
            aPlaneJToggle.clear();
         }
      }
   }

   private static void createAndShowGui() {
      APlaneJToggleTest mainPanel = new APlaneJToggleTest();

      JFrame frame = new JFrame("APlaneJToggleTest");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class APlaneJToggle {
   private int rows = 15;
   private int columns = 6;
   private Icon res = (UIManager.getIcon("OptionPane.errorIcon"));
   private Icon blankIcon;
   private ButtonGroup buttonGroup = new ButtonGroup();
   private JPanel panel = new JPanel(new BorderLayout());

   public APlaneJToggle() {
      int bi_width = res.getIconWidth();
      int bi_height = res.getIconHeight();
      BufferedImage blankImg = new BufferedImage(bi_width, bi_height,
            BufferedImage.TYPE_INT_ARGB);
      blankIcon = new ImageIcon(blankImg); 
      JPanel buttonPanel = new JPanel(new GridLayout(rows, columns));

      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++) {

            String text = rowChar[row] + column;
            final JToggleButton button = new JToggleButton(text, blankIcon);
            button.setActionCommand(text);
            buttonGroup.add(button);
            button.addItemListener(new ItemListener() {

               @Override
               public void itemStateChanged(ItemEvent e) {
                  Icon icon = e.getStateChange() == ItemEvent.SELECTED ? res
                        : blankIcon;
                  ((AbstractButton) e.getSource()).setIcon(icon);
               }
            });
            buttonPanel.add(button);
         }
      }
      JButton selectionButton = new JButton(new DisposeAction("Make Selection"));
      JPanel bottomPanel = new JPanel();
      bottomPanel.add(selectionButton);

      panel.add(buttonPanel, BorderLayout.CENTER);
      panel.add(bottomPanel, BorderLayout.PAGE_END);
   }

   public void clear() {
      ButtonModel model = buttonGroup.getSelection();
      if (model != null) {
         model.setEnabled(false);
      }
      buttonGroup.clearSelection();
   }

   public ButtonModel getSelectedModel() {
      return buttonGroup.getSelection();
   }

   public JPanel getMainPanel() {
      return panel;
   }

   private class DisposeAction extends AbstractAction {
      public DisposeAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         Component comp = (Component) e.getSource();
         Window win = SwingUtilities.getWindowAncestor(comp);
         win.dispose();
      }
   }

}

You could use SwingUtilities.getWindowAncestor to return the Window which a component resides in, this way you could dispose on the returned result.

import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private int rows = 15;
        private int columns = 6;

        public TestPane() {
            setLayout(new GridLayout(rows, columns));
            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) {
                                button.setText("X");
                            } else {
                                button.setText("");
                            }
                            SwingUtilities.getWindowAncestor(button).dispose();
                        }
                    });
                    add(button);
                }
            }
        }

    }

}

You might consider using a JDialog instead of a JFrame as it will allow you to control the program flow better. Have a look at How to Make Dialogs for more details

如果要关闭应用程序,则也可以使用System类。

System.exit(0);

In Netbeans :-

  1. Set the defaultCloseOperation to DISPOSE from the properties of the JFrame.
  2. then type this.dispose() inside the ActionPerformed() of the jButton.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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