如何在不退出应用程序的情况下处理 JFrame 并将其重新创建为新的?
How to dispose a JFrame and recreate it as new without exiting the application?
我有一个问题,我必须使用两个 JFrame
,所以我们可以忘记 good/bad 练习。
既然我们已经过了这一点。
我的两个 JFrame
是
LoginFrame
MainFrame
我想从 MainFrame
注销到 LoginFrame
,反之亦然。这样做时,我希望两个框架都能重新打开。
就像我们如何实例化它们一样,即
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.
同样,
LoginFrame.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.
现在,这运行良好,但问题是我在 MainFrame
中有一个 keyDispatchEvent
,它在我注销后登录(不关闭应用程序)执行了很多次。
我相信即使在处置之后,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
}
}
});
我不想要的是使用相同的对象,因为它们会有以前的 state/information/changes。只想摆脱已处理的对象。
此外,在这种情况下,我必须使用 KeyboardManager
到 DispatchKeyEvent
。
我希望下面的代码能满足您的需求。因为你没有 post minimal, reproducible example I can only guess what you want from your [poor] problem description and your insistence on [your] way or the highway.
the problem is that I have a keyDispatchEvent
in MainFrame
which is executing a number of times I login after signout
我的猜测是,您不断将相同的 KeyEventDispatcher
添加到 KeyboardFocusManager
,并且每添加一个都会执行。所以如果你把相同的KeyEventDispatcher
加3次,它就会执行3次。我假设您只想添加一次,因此您需要在不再需要时将其删除。
我还假设当您启动应用程序时,您希望首先显示 LoginFrame
。因此,我在下面的 class LoginFrame
中添加了一个 main
方法。
Class 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));
}
}
Class 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
标志。
我有一个问题,我必须使用两个 JFrame
,所以我们可以忘记 good/bad 练习。
既然我们已经过了这一点。
我的两个 JFrame
是
LoginFrame
MainFrame
我想从 MainFrame
注销到 LoginFrame
,反之亦然。这样做时,我希望两个框架都能重新打开。
就像我们如何实例化它们一样,即
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.
同样,
LoginFrame.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.
现在,这运行良好,但问题是我在 MainFrame
中有一个 keyDispatchEvent
,它在我注销后登录(不关闭应用程序)执行了很多次。
我相信即使在处置之后,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
}
}
});
我不想要的是使用相同的对象,因为它们会有以前的 state/information/changes。只想摆脱已处理的对象。
此外,在这种情况下,我必须使用 KeyboardManager
到 DispatchKeyEvent
。
我希望下面的代码能满足您的需求。因为你没有 post minimal, reproducible example I can only guess what you want from your [poor] problem description and your insistence on [your] way or the highway.
the problem is that I have a
keyDispatchEvent
inMainFrame
which is executing a number of times I login after signout
我的猜测是,您不断将相同的 KeyEventDispatcher
添加到 KeyboardFocusManager
,并且每添加一个都会执行。所以如果你把相同的KeyEventDispatcher
加3次,它就会执行3次。我假设您只想添加一次,因此您需要在不再需要时将其删除。
我还假设当您启动应用程序时,您希望首先显示 LoginFrame
。因此,我在下面的 class LoginFrame
中添加了一个 main
方法。
Class 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));
}
}
Class 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
标志。