繁体   English   中英

Java Swing - JDialog 模态问题

[英]Java Swing - JDialog Modal Issue

我正在开发一个包含多个 JMenu 项目的程序,这些项目对应于不同的用户需求。 我已经在我的主框架中为他们分配了可敬的行动。 我的问题是 EditUsers 对话框永远循环以前的 JDialog (AddUserDialog,它工作正常并响应被点击,按预期工作),因此导致 Eclipse 冻结和终止。 我要提前感谢任何会以任何可能的方式帮助我的好心人。

public class MainFrame extends JFrame implements ActionListener{
//------------------all variables and values have been assigned, JMenu Items are the focus------------
        users = new JMenu("Users");
        menuBar.add(users);
        
        addUsers = new JMenuItem("Add User");
        users.add(addUsers);
        addUsers.addActionListener(this);
        editUsers = new JMenuItem("Edit User");
        users.add(editUsers);
        editUsers.addActionListener(this);
        auditUsers = new JMenuItem("Audit User");
        users.add(auditUsers);
        auditUsers.addActionListener(this);

public void actionPerformed(ActionEvent ae) {
        // TODO Auto-generated method stub
        
        //example for ActionListener in the first JMenuItem, working
        if(ae.getSource() == interfaceOpt) {
            JOptionPane.showMessageDialog(null, "Test");
            System.out.println("Test");
        }
        //working
        else if(ae.getSource()==sql){
            System.out.println("Test1");
            
        }
        //working
        else if(ae.getSource()==addUsers) {
            try {
                AddUserDialog addDialog=new AddUserDialog();
                addDialog.setModalityType(ModalityType.APPLICATION_MODAL);
                addDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
            }catch(Exception ex) {
                ex.printStackTrace();
            }
            
            System.out.println("Test2");
        }
-------------------------------------HERE IS THE ISSUE------------------------------------------
        //not working, forever-looping the AddUserDialog class 
        else if(ae.getSource()==editUsers) {
            
            try {
                EditUsers editDialog=new EditUsers();
                editDialog.setModalityType(ModalityType.APPLICATION_MODAL);
                editDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
            }catch(Exception ex) {
                ex.printStackTrace();
            }
            System.out.println("Test3");
        }

我的上下文截图(JMenu 用户): JMenu 用户

点击添加用户: 添加用户

最后,当我尝试运行“编辑用户选项”时,CPU 卡顿了。 (所以没有截图)

目前我正在使用 class AddUserDialog:

public class AddUserDialog extends JDialog implements ActionListener{
    
    //a bunch of attributes
    //do stuff
    public AddUserDialog(){
    //construct staff
    }
}

EditUsers class:

public class EditUsers extends AddUserDialog implements ActionListener{
    //do stuff
    public EditUsers{
    //construct stuff
    }
}

注意:这些类本身可以正常工作。 如果人们有兴趣,我将分享这两个课程的内容,并大致了解我的程序的目的。

我的示例有一个带有两个菜单项的简单框架。 每个人都拥有一个不同的对话实例。 对于您,请阅读代码中的注释。 我相信您将需要不同的对话框类,这些类必须遵循我将在下面的代码中显示的模式

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;

public class JDialogDemo extends JFrame {
    
    public static void main (String[] args) {
        JDialogDemo frame = new JDialogDemo();
        
        JMenuBar menuBar = new JMenuBar();
        JMenu usersMenu = new JMenu("Users");
        menuBar.add(usersMenu);
        
        JMenuItem addUserItem = new JMenuItem("Add User");
        JMenuItem editUserItem = new JMenuItem("Edit User");
        
        // Each menu item has its own listener to handle events
        addUserItem.addActionListener(new MenuActionListener("Add User"));
        editUserItem.addActionListener(new MenuActionListener("Edit User"));
        
        usersMenu.add(addUserItem);
        usersMenu.add(editUserItem);
        
        frame.setJMenuBar(menuBar);
        frame.setBounds(100, 100, 600, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
    
    /*
     * My example is very simplistic. If you need to have different (custom)
     * dialogs, each menu item must implement the class that wraps the 
     * dialog that pertains to it. For instance, you may have an "Add"
     * dialog and an "edit" dialog. Each one, should follow this pattern.
     */
    private static class MenuActionListener implements ActionListener {
        private String title;
        public MenuActionListener(String title) {
            this.title = title;
        }

        @Override
        public void actionPerformed (ActionEvent e) {
            final JOptionPane optionPane = new JOptionPane(title,
                JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION);
            
            JMenuItem menuItem = (JMenuItem)e.getSource();
            
            final JDialog dialog = new JDialog((JFrame)menuItem.getParent().getParent(), "Click a button", true);
            dialog.setContentPane(optionPane);
            dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
            optionPane.addPropertyChangeListener(
            new PropertyChangeListener() {
                public void propertyChange(PropertyChangeEvent e) {
                    String prop = e.getPropertyName();

                    if (dialog.isVisible() 
                     && (e.getSource() == optionPane)
                     && (prop.equals(JOptionPane.VALUE_PROPERTY))) {
                        dialog.setVisible(false);
                    }
                }
            });
            dialog.pack();
            dialog.setVisible(true);
        }
    }
}

此外,您必须记住,如果在添加新用户或编辑现有用户时执行的逻辑开销很大,则需要在 UI 线程之外执行此逻辑。 事实上,即使不是,在 Java Swing 用于处理 UI 事件的同一线程中执行后台进程也是一个坏主意。 因此,您必须在后台执行这些进程。 一种方便的方法是使用SwingWorker线程。 您可能希望对此进行调查,并确保您的添加和编辑用户进程在单独的SwingWorker线程中处理。

更新

这也不是运行 Swing 应用程序的最佳方式。 您应该使用SwingUtilities#invokeLater()来“创建和显示”GUI。 有很多关于如何做到这一点的例子。 您甚至可能自己已经知道如何做到这一点。 如果您需要这方面的帮助并希望我更新上面的代码,请告诉我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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