如何使用 JButton 单击事件关闭基于 JFrame 的窗口

发布于 2024-09-06 18:55:46 字数 3250 浏览 1 评论 0原文

我对整个 Java Swing/AWT 对话框很陌生(这解释了下面这个对话框看起来多么业余,欢迎任何帮助更好地安排它的帮助:),并且当单击两个 JButton 中的任何一个时,我正在努力关闭这个弹出窗口。

我已经尝试过诸如 frame.dispose()frame.setVisible(false) 甚至 SwingUtilities.getWindowAncestor(this).dispose(); 这样的选项 再次强调

,这是由另一个正在运行的主进程调用的辅助弹出窗口,因此我只想关闭这个特定的弹出窗口而不影响主进程。否则我可以使用 System.exit

就像我提到的那样,任何其他改善对话框整体外观和感觉的建议都是值得赞赏的。

我的整个代码如下:

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class UpgradePopupWindow extends JPanel implements ActionListener {
  public static UpgradePopupWindow mainWindow;

  static final long serialVersionUID = 0;

  final String upgrade = "Continue Upgrade";
  final String restore = "Restore";

  JPanel panels;
  JButton flashMe;
  JButton helpMe;
  JTextArea Message;
  JFrame frame;

  protected JTextArea addText(String text, boolean visible, int fontStyle) {
    JTextArea textArea = new JTextArea(text);

    textArea.setFont(new Font("SansSerif", fontStyle, 12)); //$NON-NLS-1$

    textArea.setLineWrap(true);
    textArea.setWrapStyleWord(true);
    textArea.setEditable(false);
    textArea.setForeground(Color.WHITE);
    textArea.setOpaque(false);
    textArea.setVisible(visible);
    textArea.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(textArea);

    return textArea;
  }

  public UpgradePopupWindow(Object ft) {
    String text = "This is the random text for now. I will bother about the actual content later";
    addLabel(text, Font.PLAIN, 12);

    flashMe = new JButton(upgrade);
    flashMe.setActionCommand("upgrade");
    flashMe.addActionListener(this);
    flashMe.setEnabled(true);
    add(flashMe);


    helpMe = new JButton(restore);
    helpMe.setActionCommand("restore");
    helpMe.addActionListener(this);
    helpMe.setEnabled(true);
    add(helpMe);
  }

  protected JLabel addLabel(String text, int fontStyle, int size) {
    JLabel label = new JLabel(text);
    label.setFont(new Font("SansSerif", fontStyle, size)); 
    label.setAlignmentX(Component.CENTER_ALIGNMENT);
    label.setOpaque(false);
    label.setVisible(true);
    label.setForeground(Color.BLUE);

    add(label);
    return label;
  }

  public void createGUI(Object obj) {
    //Create and set up the frame.
    frame = new JFrame("PopUp Dialog");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //create and setup the content pane
    UpgradePopupWindow popUpContentPane = new UpgradePopupWindow(obj);

    popUpContentPane.setOpaque(true);
    frame.setContentPane(popUpContentPane);

    frame.pack();
    frame.setVisible(true);
  }

  public void actionPerformed(ActionEvent e) {
    if("restore".equals(e.getActionCommand())) {
      System.out.println("restore button selected");
      frame.dispose();
      SwingUtilities.getWindowAncestor(this).dispose();
    } else if ("upgrade".equals(e.getActionCommand())) {
      System.out.println("upgrade button selected");
      frame.dispose();
    }
  }
}

I am new to the whole Java Swing/AWT dialogs (which explains how amateurish this dialog below looks like, any help in arranging it better is welcome :) and I am struggling to close this popUp window when any of the two JButtons are clicked.

I have already tried options like frame.dispose(), frame.setVisible(false) and even SwingUtilities.getWindowAncestor(this).dispose();

Again, this is a secondary popup window invoked by another main process running, so I just want this particular popUp window to close and not affect the main process. Otherwise I could use System.exit

Like I mentioned, any other suggestions to improve the overall look and feel of the dialog are appreciated.

My entire code is as below:

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class UpgradePopupWindow extends JPanel implements ActionListener {
  public static UpgradePopupWindow mainWindow;

  static final long serialVersionUID = 0;

  final String upgrade = "Continue Upgrade";
  final String restore = "Restore";

  JPanel panels;
  JButton flashMe;
  JButton helpMe;
  JTextArea Message;
  JFrame frame;

  protected JTextArea addText(String text, boolean visible, int fontStyle) {
    JTextArea textArea = new JTextArea(text);

    textArea.setFont(new Font("SansSerif", fontStyle, 12)); //$NON-NLS-1$

    textArea.setLineWrap(true);
    textArea.setWrapStyleWord(true);
    textArea.setEditable(false);
    textArea.setForeground(Color.WHITE);
    textArea.setOpaque(false);
    textArea.setVisible(visible);
    textArea.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(textArea);

    return textArea;
  }

  public UpgradePopupWindow(Object ft) {
    String text = "This is the random text for now. I will bother about the actual content later";
    addLabel(text, Font.PLAIN, 12);

    flashMe = new JButton(upgrade);
    flashMe.setActionCommand("upgrade");
    flashMe.addActionListener(this);
    flashMe.setEnabled(true);
    add(flashMe);


    helpMe = new JButton(restore);
    helpMe.setActionCommand("restore");
    helpMe.addActionListener(this);
    helpMe.setEnabled(true);
    add(helpMe);
  }

  protected JLabel addLabel(String text, int fontStyle, int size) {
    JLabel label = new JLabel(text);
    label.setFont(new Font("SansSerif", fontStyle, size)); 
    label.setAlignmentX(Component.CENTER_ALIGNMENT);
    label.setOpaque(false);
    label.setVisible(true);
    label.setForeground(Color.BLUE);

    add(label);
    return label;
  }

  public void createGUI(Object obj) {
    //Create and set up the frame.
    frame = new JFrame("PopUp Dialog");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //create and setup the content pane
    UpgradePopupWindow popUpContentPane = new UpgradePopupWindow(obj);

    popUpContentPane.setOpaque(true);
    frame.setContentPane(popUpContentPane);

    frame.pack();
    frame.setVisible(true);
  }

  public void actionPerformed(ActionEvent e) {
    if("restore".equals(e.getActionCommand())) {
      System.out.println("restore button selected");
      frame.dispose();
      SwingUtilities.getWindowAncestor(this).dispose();
    } else if ("upgrade".equals(e.getActionCommand())) {
      System.out.println("upgrade button selected");
      frame.dispose();
    }
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无远思近则忧 2024-09-13 18:55:46

问题是您的 createGUI 方法不是静态的。所以我想象您首先创建一个 UpgradePopupWindow,在其上调用 createGUI,这又创建一个 enw UpgradePopupWindow。

试试这个:

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

public class TempTest
{
    public static void main(String[] args)
    {
        UpgradePopupWindow.createGUI(null);
    }
}


class UpgradePopupWindow extends JPanel implements ActionListener {
  public static UpgradePopupWindow mainWindow;

  static final long serialVersionUID = 0;

  final String upgrade = "Continue Upgrade";
  final String restore = "Restore";

  JPanel panels;
  JButton flashMe;
  JButton helpMe;
  JTextArea Message;
    JFrame frame;


    protected JTextArea addText(String text, boolean visible, int fontStyle) {
    JTextArea textArea = new JTextArea(text);

    textArea.setFont(new Font("SansSerif", fontStyle, 12)); //$NON-NLS-1$

    textArea.setLineWrap(true);
    textArea.setWrapStyleWord(true);
    textArea.setEditable(false);
    textArea.setForeground(Color.WHITE);
    textArea.setOpaque(false);
    textArea.setVisible(visible);
    textArea.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(textArea);

    return textArea;
  }

  public UpgradePopupWindow(JFrame frm, Object ft2) {
    String text = "This is the random text for now. I will bother about the actual content later";
    addLabel(text, Font.PLAIN, 12);
      frame = frm;
    flashMe = new JButton(upgrade);
    flashMe.setActionCommand("upgrade");
    flashMe.addActionListener(this);
    flashMe.setEnabled(true);
    add(flashMe);


    helpMe = new JButton(restore);
    helpMe.setActionCommand("restore");
    helpMe.addActionListener(this);
    helpMe.setEnabled(true);
    add(helpMe);
  }

  protected JLabel addLabel(String text, int fontStyle, int size) {
    JLabel label = new JLabel(text);
    label.setFont(new Font("SansSerif", fontStyle, size));
    label.setAlignmentX(Component.CENTER_ALIGNMENT);
    label.setOpaque(false);
    label.setVisible(true);
    label.setForeground(Color.BLUE);

    add(label);
    return label;
  }

  public static void createGUI(Object obj) {
    //Create and set up the frame.
    JFrame frame = new JFrame("PopUp Dialog");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //create and setup the content pane
    UpgradePopupWindow popUpContentPane = new UpgradePopupWindow(frame, obj);

    popUpContentPane.setOpaque(true);
    frame.setContentPane(popUpContentPane);

    frame.pack();
    frame.setVisible(true);
  }

  public void actionPerformed(ActionEvent e) {
    if("restore".equals(e.getActionCommand())) {
      System.out.println("restore button selected");
      frame.dispose();
      SwingUtilities.getWindowAncestor(this).dispose();
    } else if ("upgrade".equals(e.getActionCommand())) {
      System.out.println("upgrade button selected");
      frame.dispose();
    }
  }

}

主要的变化是 createUI 是静态的,UpgradePopupWindow 在构造函数中获取框架。

The problem is that your createGUI method is not static. So I imagine you are creating first a UpgradePopupWindow, calling createGUI on that, which in turn creates a enw UpgradePopupWindow.

Try this instead:

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

public class TempTest
{
    public static void main(String[] args)
    {
        UpgradePopupWindow.createGUI(null);
    }
}


class UpgradePopupWindow extends JPanel implements ActionListener {
  public static UpgradePopupWindow mainWindow;

  static final long serialVersionUID = 0;

  final String upgrade = "Continue Upgrade";
  final String restore = "Restore";

  JPanel panels;
  JButton flashMe;
  JButton helpMe;
  JTextArea Message;
    JFrame frame;


    protected JTextArea addText(String text, boolean visible, int fontStyle) {
    JTextArea textArea = new JTextArea(text);

    textArea.setFont(new Font("SansSerif", fontStyle, 12)); //$NON-NLS-1$

    textArea.setLineWrap(true);
    textArea.setWrapStyleWord(true);
    textArea.setEditable(false);
    textArea.setForeground(Color.WHITE);
    textArea.setOpaque(false);
    textArea.setVisible(visible);
    textArea.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(textArea);

    return textArea;
  }

  public UpgradePopupWindow(JFrame frm, Object ft2) {
    String text = "This is the random text for now. I will bother about the actual content later";
    addLabel(text, Font.PLAIN, 12);
      frame = frm;
    flashMe = new JButton(upgrade);
    flashMe.setActionCommand("upgrade");
    flashMe.addActionListener(this);
    flashMe.setEnabled(true);
    add(flashMe);


    helpMe = new JButton(restore);
    helpMe.setActionCommand("restore");
    helpMe.addActionListener(this);
    helpMe.setEnabled(true);
    add(helpMe);
  }

  protected JLabel addLabel(String text, int fontStyle, int size) {
    JLabel label = new JLabel(text);
    label.setFont(new Font("SansSerif", fontStyle, size));
    label.setAlignmentX(Component.CENTER_ALIGNMENT);
    label.setOpaque(false);
    label.setVisible(true);
    label.setForeground(Color.BLUE);

    add(label);
    return label;
  }

  public static void createGUI(Object obj) {
    //Create and set up the frame.
    JFrame frame = new JFrame("PopUp Dialog");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //create and setup the content pane
    UpgradePopupWindow popUpContentPane = new UpgradePopupWindow(frame, obj);

    popUpContentPane.setOpaque(true);
    frame.setContentPane(popUpContentPane);

    frame.pack();
    frame.setVisible(true);
  }

  public void actionPerformed(ActionEvent e) {
    if("restore".equals(e.getActionCommand())) {
      System.out.println("restore button selected");
      frame.dispose();
      SwingUtilities.getWindowAncestor(this).dispose();
    } else if ("upgrade".equals(e.getActionCommand())) {
      System.out.println("upgrade button selected");
      frame.dispose();
    }
  }

}

The main change is that the createUI is static, and the UpgradePopupWindow takes the frame in the constructor.

夏见 2024-09-13 18:55:46

您的 createGUI() 方法有点混乱,它创建了此类的另一个实例,最终您得到一个带有框架的实例和一个没有框架的实例。让它工作的最小改变是改变你的 createGUI 方法:

  public void createGUI(Object obj) {
    //Create and set up the frame.
    frame = new JFrame("PopUp Dialog");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//    //create and setup the content pane
//    UpgradePopupWindow popUpContentPane = new UpgradePopupWindow(obj);

    setOpaque(true);
    frame.setContentPane(this);

    frame.pack();
    frame.setVisible(true);
  }

Your createGUI() method is a little confused, it creates ANOTHER instance of this class and you end up with one instance with a frame and one instance without. Minimal change to get it working is to change your createGUI method:

  public void createGUI(Object obj) {
    //Create and set up the frame.
    frame = new JFrame("PopUp Dialog");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//    //create and setup the content pane
//    UpgradePopupWindow popUpContentPane = new UpgradePopupWindow(obj);

    setOpaque(true);
    frame.setContentPane(this);

    frame.pack();
    frame.setVisible(true);
  }
情仇皆在手 2024-09-13 18:55:46

问题是您有 UpgradePopupWindow 类的两个实例。首先,您需要创建一个实例,以便可以调用 createGUI() 方法。然后在 createGUI 方法中创建该类的另一个实例。我确信这不是你想要的。

一种解决方案是将 createGUI() 方法设为静态。我从类中删除了“frame”变量并进行了以下更改:

  public static void createGUI(Object obj) {
    //Create and set up the frame.
    JFrame frame = new JFrame("PopUp Dialog");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //create and setup the content pane
    UpgradePopupWindow popUpContentPane = new UpgradePopupWindow(obj);

    popUpContentPane.setOpaque(true);
    frame.setContentPane(popUpContentPane);

    frame.pack();
    frame.setVisible(true);
  }

  public void actionPerformed(ActionEvent e) {
    if("restore".equals(e.getActionCommand())) {
      System.out.println("restore button selected");
//      frame.dispose();
      SwingUtilities.getWindowAncestor(this).dispose();
    } else if ("upgrade".equals(e.getActionCommand())) {
      System.out.println("upgrade button selected");
//      frame.dispose();
      SwingUtilities.getWindowAncestor(this).dispose();
    }
  }

    public static void main(String[] args)
    {
        UpgradePopupWindow.createGUI(null);
    }

The problem is that you have two instances of your UpgradePopupWindow class. First you need to create an instance so you can invoke the createGUI() method. Then in the createGUI method you create another instance of the class. I'm sure is not what you intended.

One solution is to make the createGUI() method static. I removed the "frame" variable from the class and made the following changes:

  public static void createGUI(Object obj) {
    //Create and set up the frame.
    JFrame frame = new JFrame("PopUp Dialog");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //create and setup the content pane
    UpgradePopupWindow popUpContentPane = new UpgradePopupWindow(obj);

    popUpContentPane.setOpaque(true);
    frame.setContentPane(popUpContentPane);

    frame.pack();
    frame.setVisible(true);
  }

  public void actionPerformed(ActionEvent e) {
    if("restore".equals(e.getActionCommand())) {
      System.out.println("restore button selected");
//      frame.dispose();
      SwingUtilities.getWindowAncestor(this).dispose();
    } else if ("upgrade".equals(e.getActionCommand())) {
      System.out.println("upgrade button selected");
//      frame.dispose();
      SwingUtilities.getWindowAncestor(this).dispose();
    }
  }

    public static void main(String[] args)
    {
        UpgradePopupWindow.createGUI(null);
    }
枫以 2024-09-13 18:55:46

createGUI() 方法中,您实例化 frame 变量并将其内容窗格设置为 UpgradePopupWindow 的另一个实例。但您不会实例化第二个实例的 frame 变量。单击“恢复”或“升级”按钮时,它会调用该第二个实例的actionPerformed()方法,因此frame.dispose()frame.setVisible(false) 不起作用,因为 frame 为 null。

我建议让您的 UpgradePopupWindow 类扩展 JFrame 而不是 JPanel。这样,您就可以直接调用 dispose() 方法。另外,让一个类==一个窗口更有意义(JPanel 不是窗口,只是一组 GUI 小部件)。然后,在构造函数中创建一个 JPanel 并向其中添加小部件。您还可以摆脱那个讨厌的 mainWindow 静态变量。

另外,我不认为 JFrame.EXIT_ON_CLOSE 是您想要在这里使用的。您想要关闭窗口,而不是终止整个应用程序。 JFrame.DISPOSE_ON_CLOSE 将在关闭时仅处理窗口。

您还可以通过实现 WindowListener 接口来更精细地调整对话框对窗口事件的反应方式。

外观和感觉对我来说都不错。简单直接。

public class Main{
  public static void main(String args[]){
    //display the window from your main window
    UpgradePopupWindow upw = new UpgradePopupWindow(obj);
    upw.setVisible(true);
  }
}

public class UpgradePopupWindow extends JFrame implements ActionListener, WindowListener {
  //...

  public UpgradePopupWindow(Object ft) {
    super("PopUp Dialog");
    JPanel panel = new JPanel();
    //...
    setContentPane(panel);
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    pack();
  }

  public void actionPerformed(ActionEvent e) {
    if("restore".equals(e.getActionCommand())) {
      System.out.println("restore button selected");
      dispose();
    } else if ("upgrade".equals(e.getActionCommand())) {
      System.out.println("upgrade button selected");
      dispose();
    }
  }

  public void windowClosed(WindowEvent e) { 
    System.out.println("Window closed!");
  }
  //other WindowListener methods
}

Inside the createGUI() method, you're instantiating the frame variable and setting its content pane to another instance of UpgradePopupWindow. But you don't instantiate the frame variable of that second instance. When the Restore or Upgrade buttons are clicked, it is invoking the actionPerformed() method of that second instance, so frame.dispose() and frame.setVisible(false) won't work because frame is null.

I would suggest having your UpgradePopupWindow class extend JFrame instead of JPanel. That way, you can call the dispose() method directly. Plus, it just makes more sense to have one class == one window (a JPanel isn't a window, just a grouping of GUI widgets). Then, create a JPanel in the constructor and add the widgets to that. You can also get rid of that nasty mainWindow static variable.

Also, I don't think JFrame.EXIT_ON_CLOSE is what you want to use here. You want to close the window, not terminate the entire application. JFrame.DISPOSE_ON_CLOSE will dispose just the window when it is closed.

You can also more finely-tune the way your dialog reacts to window events by implementing the WindowListener interface.

The look and feel looks OK to me. Simple and straight forward.

public class Main{
  public static void main(String args[]){
    //display the window from your main window
    UpgradePopupWindow upw = new UpgradePopupWindow(obj);
    upw.setVisible(true);
  }
}

public class UpgradePopupWindow extends JFrame implements ActionListener, WindowListener {
  //...

  public UpgradePopupWindow(Object ft) {
    super("PopUp Dialog");
    JPanel panel = new JPanel();
    //...
    setContentPane(panel);
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    pack();
  }

  public void actionPerformed(ActionEvent e) {
    if("restore".equals(e.getActionCommand())) {
      System.out.println("restore button selected");
      dispose();
    } else if ("upgrade".equals(e.getActionCommand())) {
      System.out.println("upgrade button selected");
      dispose();
    }
  }

  public void windowClosed(WindowEvent e) { 
    System.out.println("Window closed!");
  }
  //other WindowListener methods
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文