【问题标题】:How to prevent that closing a JDialog closes the entire application如何防止关闭 JDialog 关闭整个应用程序
【发布时间】:2019-09-18 01:10:40
【问题描述】:

我有一个主(屏幕)gui 窗口,需要打开几个“多输入”窗口(jdialog 或当不可能时 jframe),例如添加首选项(4 个文本字段,2 个文件选择器和 2 个单选按钮)。 在这些 JDialogs(或 JFrames)中按 OK/Cancel 时,我的整个应用程序将关闭。 我不想要那个。我怎样才能防止这种情况发生?

第一次尝试:我尝试了 intelliJ 选项“新建 -> 创建对话框类”,它为我提供了一个带有确定/取消按钮的 JDialog。按下其中一个按钮会关闭 JDialog 和我的整个应用程序。

第二次尝试:我“手动”编写了一个创建 JDialog 的类(也尝试了 JFrame)。同样:按下其中一个按钮会关闭 JDialog 和我的整个应用程序。

我从 JDialog (JFrame) 中删除了“dispose()”和“setVisible(false)”选项,但我的整个应用程序仍然关闭。

主类方法

public class mainScreen {

    // Menu action listener (only relevant options)
    class MenuActionListener implements ActionListener {

    // menuListener
    public void actionPerformed(ActionEvent ev) {
            //myVariables myVars = new myVariables();
        String[] dummy = null;
            System.out.println("Selected: " + ev.getActionCommand());

            switch(ev.getActionCommand()) {
                case "Preferences":
                    showPreferencesDialog();
                case "Exit":
                    System.exit(0);
                    break;
    }

    // method that opens the external class (see below in following code block)
    private void showPreferencesDialog() {

        prefJDialog myprefs = new prefJDialog(prefsPanel);
        myprefs.showDialog();
        boolean okPressed = myprefs.isOkPressed();
        if (okPressed) {
            JOptionPane.showMessageDialog(mainScreen.this.rootPanel,"OK pressed","About jExifToolGUI",JOptionPane.INFORMATION_MESSAGE);
        } else {
            JOptionPane.showMessageDialog(mainScreen.this.rootPanel,"Cancel pressed","About jExifToolGUI",JOptionPane.INFORMATION_MESSAGE);
        }
    }

    // This is the class which is mention in the manifest
    public mainScreen(JFrame frame) {
        boolean preferences = false;
        Preferences prefs = Preferences.userRoot();

        createmyMenuBar(frame);
        groupRadiobuttonsandListen();
        fileNamesTableListener();
        try {
            myUtils.DisplayLogo(mainScreen.this.iconLabel);
        } catch(IOException ex) {
            System.out.println("Error reading Logo");
        }

        preferences = check_preferences();
        if (!preferences) {
            myUtils.checkExifTool(mainScreen.this.rootPanel);
        }

        programButtonListeners();
    }
    // main method in my main class for my project
    public static void main(String[] args) {

        JFrame frame = new JFrame("jExifToolGUI");
        frame.setContentPane(new mainScreen(frame).rootPanel);
        //frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

    }
}

从主类调用的 JDialog 类/方法

package org.hvdw.jexiftoolgui;

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

public class prefJDialog extends JDialog {
    private JButton okButton;
    private JButton cancelButton;

    private JPanel prefsPanel;

    private boolean okPressed;

    public prefJDialog(JPanel prefsPanel) {
        super(JOptionPane.getFrameForComponent(prefsPanel), true);
        this.prefsPanel = prefsPanel;
        setTitle("Preferences");
        initDialog();
    }

    public void showDialog() {
        setSize(800, 768);
        double x = getParent().getBounds().getCenterX();
        double y = getParent().getBounds().getCenterY();
        setLocation((int) x - getWidth() / 2, (int) y - getHeight() / 2);
        setVisible(true);
    }


    private void initDialog() {
        JPanel pane = new JPanel();
        pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
        pane.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10));
        add(pane);

        pane.add(Box.createVerticalGlue());
        FlowLayout l = new FlowLayout(FlowLayout.RIGHT);
        JPanel buttonsPane = new JPanel(l);
        okButton = new JButton("Save"); //$NON-NLS-1$
        buttonsPane.add(okButton);
        pane.getRootPane().setDefaultButton(okButton);
        cancelButton = new JButton("CANCEL"); //$NON-NLS-1$
        buttonsPane.add(cancelButton);

        buttonsPane.setMaximumSize(new Dimension(Short.MAX_VALUE, (int) l.preferredLayoutSize(buttonsPane).getHeight()));
        pane.add(buttonsPane);

        addListeners();
    }

    private void addListeners() {
        okButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //saveProperties();
                setVisible(false);
                okPressed = true;
                //close();


                // dispose();
            }

        });
        cancelButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setVisible(false);
                //dispose();
                //close();
                okPressed = false;
            }
        });

    }

    public boolean isOkPressed() {
        return okPressed;
    }

    /*public void close() {
        WindowEvent winClosingEvent = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
        Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(winClosingEvent);
    }*/
}

那么如何防止在 JDialog 中单击确定或取消时,整个应用程序关闭。这需要保持打开状态,直到用户单击右上角的“窗口关闭”X,或从菜单“文件->退出”

我已经在 Google 上搜索了几天,但找不到解决方案(同样的问题没有答案)。

编辑: 在帕特里克的回答之后,我将关闭方法更改为

    public void close() {
        this.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
    }

并删除了 /* 和 */。 我还激活了 close();再次在听众中,但这并没有什么不同。我的主应用程序仍然关闭。

【问题讨论】:

  • 我不明白你的意思。我从我的主类和我称为 JDialog 类的完整类中添加了最少的代码。
  • 我“手工”编写了一个类 - 这是正确的方法,因此您可以学习如何使用 Swing 而不是 IDE。 我添加了最少的代码 - 最少的代码意味着您创建一个带有“显示对话框”JButton 的 JFrame。当您单击该按钮时,您会显示一个带有“关闭”按钮的 JDialog。所有代码都在一个类中,我们可以复制/粘贴/编译/测试。我们不能对您的代码执行此操作,因为没有 JFrmae、没有 main() 方法等。此外,所有与框架/对话框居中相关的代码都与问题无关。只需要与问题直接相关的代码。
  • 明白。但是我的主要(清单)类现在是 530 行,还有 6 个用于所有功能的附加类。另请参阅主屏幕的共享图像 (drive.google.com/file/d/1k7NKK4ynTyc5-w9h_Bj8UuSfVpTtxIa_/…)。接下来的步骤是几个 Jdialogs。 (请注意,我暂时将提到的首选项作为选项卡式窗格中最右侧的选项卡)。它实际上是我的 pyExifToolGUI (hvdwolf.github.io/pyExifToolGUI) 的重写,因为我已经编写了 Android java。
  • 我们不是她来调试您的应用程序。我们在这里帮助您了解基本的 Swing 概念。 JDialog 专门设计用于不关闭整个应用程序。通过创建一个我在之前评论中描述的简单示例向自己证明这一点。除非您有类似System.exit() 的代码,否则关闭对话框不会关闭应用程序!如果您无法使用正确的 minimal reproducible example 复制所描述的问题,那么我们将无能为力。
  • 请不要像在 [Solved] 等其他论坛中那样编辑带有噪音的问题标题,我们在 StackOverflow 中这样做的方式是接受答案(您已经这样做了)。

标签: java swing jdialog


【解决方案1】:
     switch(ev.getActionCommand()) {
            case "Preferences":
                showPreferencesDialog();
            case "Exit":
                System.exit(0);
                break;

问题是您的 switch case 中没有 break 语句,因此代码进入“退出”逻辑并执行 System.exit(0)

这就是为什么我们需要为每个问题提供适当的“MCVE”。当您发布随机代码时,我们无法看到整个逻辑流程。

【讨论】:

  • 非常感谢您发现这一点。有 8 个(此时)case 语句,这是唯一一个缺少“break;”的语句。命令,它恰好在出口之前。我会努力改善我的生活。抱歉,由于我没有足够的帖子,我无法为你的答案投票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-01
  • 2011-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-18
相关资源
最近更新 更多