如何解决由于某些原因,JFrame移至后台
昨天here,我问了一个关于这个主题的非常模糊的问题后(现在我决定关闭该问题),我能够查明问题并创建一个MCVE来显示此行为。
场景如下:
虽然某些操作正在后台进行,但可以肯定的是,在前台提供了一个模态“等待”对话框,并且还将JFrame设置为禁用。后台任务完成后,再次启用框架并放置对话框。
问题是,在启用JFrame并放置了模式对话框之后,JFrame突然移至后台。具有“背景”的含义,它在JFrame之前在具有焦点的窗口后面移动。为什么会这样?
此代码应复制问题:
private static JFrame frame;
private static JDialog dialog;
public static void main(String[] args) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
buildFrame();
buildDialog();
}
});
} catch (InvocationTargetException | InterruptedException e) {
e.printStackTrace();
}
}
protected static void buildDialog() {
dialog = new JDialog(frame);
dialog.getContentPane().add(new JLabel("This is the dialog"));
dialog.setLocationRelativeTo(frame);
javax.swing.Timer t = new javax.swing.Timer(1000,new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
frame.setEnabled(true);
}
});
t.setRepeats(false);
t.start();
dialog.pack();
dialog.setVisible(true);
}
protected static void buildFrame() {
frame = new JFrame();
frame.setMinimumSize(new Dimension(400,400));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new JLabel("This is the Frame"));
frame.setEnabled(false);
frame.pack();
frame.setVisible(true);
}
有人知道为什么会发生这种情况以及如何防止这种情况发生吗?
解决方法
问题是方法frame.setEnabled()
。我不知道为什么,但是它隐藏了框架。我的建议是删除它并使用模态概念:dialog.setModal(true)
(当显示对话框时,它也使父框架不可用。要使该框架不可用,可以在其上放置一个玻璃窗格。这是代码:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
/**
* <code>DialogFrameTest</code>.
*/
public class DialogFrameTest {
private static JFrame frame;
private static JDialog dialog;
private static Component oldGlassPane;
public static void main(String[] args) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
buildFrame();
buildDialog();
}
});
} catch (InvocationTargetException | InterruptedException e) {
e.printStackTrace();
}
}
protected static void buildDialog() {
dialog = new JDialog(frame);
dialog.getContentPane().add(new JTextField("This is the dialog"));
dialog.setLocationRelativeTo(frame);
dialog.setModal(true);
javax.swing.Timer t = new javax.swing.Timer(1000,new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
frame.setGlassPane(oldGlassPane);
oldGlassPane.setVisible(false);
}
});
t.setRepeats(false);
t.start();
dialog.pack();
dialog.setVisible(true);
}
protected static void buildFrame() {
frame = new JFrame();
frame.setMinimumSize(new Dimension(400,400));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new JTextField("This is the Frame"));
oldGlassPane = frame.getGlassPane();
frame.setGlassPane(new SplashGlassPane());
frame.getGlassPane().setVisible(true);
frame.pack();
frame.setVisible(true);
}
private static class SplashGlassPane extends JPanel implements FocusListener {
/** Holds the id of this panel. The creator of this object can submit this id to determine whether it's the owner of this object. */
private String typeId;
/**
* Creates new GlassPane.
*/
public SplashGlassPane() {
addMouseListener(new MouseAdapter() {});
addMouseMotionListener(new MouseAdapter() {});
addFocusListener(this);
setOpaque(false);
setFocusable(true);
setBackground(new Color(0,100));
}
@Override
public final void setVisible(boolean v) {
// Make sure we grab the focus so that key events don't go astray.
if (v) {
requestFocus();
}
super.setVisible(v);
}
// Once we have focus,keep it if we're visible
@Override
public final void focusLost(FocusEvent fe) {
if (isVisible()) {
requestFocus();
}
}
/**
* {@inheritDoc}
*/
@Override
public final void paint(Graphics g) {
final Color old = g.getColor();
g.setColor(getBackground());
g.fillRect(0,getSize().width,getSize().height);
g.setColor(old);
super.paint(g);
}
@Override
public void focusGained(FocusEvent fe) {
// nothing to do
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。