如何在不退出应用程序的情况下处理 JFrame 并将其重新创建为新的?

问题描述

我有一个问题,我必须使用两个 JFrame,这样我们就可以忘记好的/坏的做法。

既然我们已经过了这一点。

我的两个JFrame

  1. LoginFrame
  2. MainFrame

我想退出 MainFrameLoginFrame,反之亦然。这样做时,我希望两个框架都能重新打开。 就像我们如何实例化它们一样,即

MainFrame.class

//on signout button event
new LoginFrame().setVisible(true);
dispose(); //it will dispose this frame and destroy its UI components and free resources etc etc.

同样,

登录框架.class

//on signin button event
new MainFrame().setVisible(true);
dispose(); //it will dispose this frame and destroy its UI components and free resources etc etc.

现在,这运行良好,但问题是我在 keydispatchEvent 中有一个 MainFrame,它在我注销后登录(不关闭应用程序)执行了多次。

我相信即使在处理之后,JFrame 它实际上也没有被处理。因此,当我键入任何快捷键时,先前处理的框架对象和 MainFrame 的新对象都在调度它们的事件。我怎么能丢失(我的意思是真的处理)所有以前的对象,以便只为当前对象触发此事件?

MainFrame.class

final static KeyboardFocusManager keyManager=KeyboardFocusManager.getCurrentKeyboardFocusManager();

keyManager.addKeyEventdispatcher(new KeyEventdispatcher() 
{

        @Override
        public boolean dispatchKeyEvent(KeyEvent e) 
        {
           // if key is alt+r  
           {
               signout(); // getting called repeatedly on single key release 
           }
        }
});

我不想要的是使用相同的对象,因为它们会有以前的状态/信息/更改。只是想摆脱已处理的对象。

此外,在这种情况下,我必须使用 KeyboardManagerdispatchKeyEvent

解决方法

我希望下面的代码可以满足您的需求。由于您没有发布minimal,reproducible example,我只能从您的[糟糕] 问题描述和您对[your] way or the highway 的坚持猜测您想要什么。

问题是我在 keyDispatchEvent 中有一个 MainFrame,它在我退出后登录时执行了多次

我的猜测是,您不断向 KeyEventDispatcher 添加相同的 KeyboardFocusManager,并且每个添加的都会执行。因此,如果您将相同的 KeyEventDispatcher 添加 3 次,它将执行 3 次。我假设您只想添加一次,因此您需要在不再需要时将其删除。

我还假设当您启动应用程序时,您希望首先显示 LoginFrame。因此,我在下面的 main 类中添加了一个 LoginFrame 方法。

LoginFrame

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class LoginFrame extends JFrame implements ActionListener {

    public LoginFrame() {
        KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(MainFrame.ked);
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        JButton signin = new JButton("sign in");
        signin.addActionListener(this);
        JPanel panel = new JPanel();
        panel.add(signin);
        add(panel,BorderLayout.PAGE_END);
        pack();
        setLocationByPlatform(true);
    }

    @Override
    public void actionPerformed(ActionEvent event) {
        new MainFrame().setVisible(true);
        dispose();
    }
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> new LoginFrame().setVisible(true));
    }
}

MainFrame

import java.awt.BorderLayout;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MainFrame extends JFrame implements ActionListener {
    final static KeyboardFocusManager keyManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();

    private static boolean  done;
    static KeyEventDispatcher ked;

    public MainFrame() {
        keyManager.removeKeyEventDispatcher(ked);
        ked = new KeyEventDispatcher() {
            
            @Override
            public boolean dispatchKeyEvent(KeyEvent ke) {
                int key = ke.getKeyCode();
                int modifiers = ke.getModifiersEx();
                if (key == KeyEvent.VK_R  &&  (modifiers & KeyEvent.ALT_DOWN_MASK) == KeyEvent.ALT_DOWN_MASK) {
                    if (done) {
                        done = false;
                    }
                    else {
                        done = true;
                        actionPerformed(null);
                    }
                }
                return false;
            }
        };
        keyManager.addKeyEventDispatcher(ked);

        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        JButton signout = new JButton("sign out");
        signout.addActionListener(this);
        JPanel panel = new JPanel();
        panel.add(signout);
        add(panel,BorderLayout.PAGE_END);
        pack();
        setLocationByPlatform(true);
    }

    @Override
    public void actionPerformed(ActionEvent event) {
        new LoginFrame().setVisible(true);
        dispose();
    }
}

注意:

  • 我不知道为什么,但是每次我按键盘上的 Alt+R 时,事件调度程序都会触发两次。因此,done 标志。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...