我的用户喜欢多个JFrame
;它允许他们调整不同组件的大小,并将它们放在屏幕上的任何位置。但是,我有一个要求让所有子窗口一起到前面...换句话说,让我们说它们在所有窗口前面最大化另一个窗口,然后使用任务栏单击其中一个窗口JFrame
秒。如何设置它以便它们都能到达前面?注意:也可以关闭子窗口;如果它们实际上是隐藏的,我会不希望它们来到前面。我有一个类ApplicationModel
,可以跟踪窗口是否隐藏。
我尝试过的事情:
windowActivated()
和focusGained()
尝试将它们全部带到前面。这通常会导致无限循环。问题是我的事件框架从事件调度线程发送这些请求,因此任何类型的AtomicBoolean
阻塞都不会持续足够长的时间。
JDialog
。不幸的是,要么窗户是无模式的(因此不会与主窗口一起出现),要么它们是模态的(因此阻止主窗口)。如何解决这些问题中的任何一个,或者是否存在完全不同的第三种解决方案?
答案 0 :(得分:0)
您可以使用布尔字段作为标志来阻止无限循环:
private boolean movingAllFramesToFront;
public void windowActivated(WindowEvent event) {
if (movingAllFramesToFront) {
return;
}
movingAllFramesToFront = true;
List<Frame> frames = getAllApplicationFrames();
for (Frame frame : frames) {
if (!applicationModel.isHidden(frame)) {
frame.toFront();
}
}
event.getWindow().toFront();
event.getWindow().requestFocus();
EventQueue.invokeLater(new Runnable() {
public void run() {
movingAllFramesToFront = false;
}
);
}
您可以尝试的另一件事是Java 1.7中引入的新autoRequestFocus
属性。我从未尝试过使用它,但这是我对其工作原理的理解:
public void windowActivated(WindowEvent event) {
final List<Frame> frames = getAllApplicationFrames();
for (Frame frame : frames) {
if (!applicationModel.isHidden(frame)) {
frame.setAutoRequestFocus(false);
frame.toFront();
}
}
EventQueue.invokeLater(new Runnable() {
public void run() {
for (Frame frame : frames) {
if (!applicationModel.isHidden(frame)) {
frame.setAutoRequestFocus(true);
}
}
}
);
}
答案 1 :(得分:0)
我有一个带有很多窗口的应用程序,并且遇到了类似于你的问题。我的解决方法是:
@Override
public void windowActivated(WindowEvent e) {
if (e.getOppositeWindow() == null) {
//front every window
}
}
首先,我创建了一个类“SlveFrame”(Slve是我的应用程序的名称),一个“JFrame”的孩子。
public class SlveFrame extends JFrame implements WindowListener {
static ArrayList<SlveFrame> frames = new ArrayList<SlveFrame>();
public SlveFrame () {
addWindowListener(this); / /to make JFrame fire WindowListener's method
}
/ /... every method added from WindowListener
@Override
public void windowActivated(WindowEvent e) {
if (e.getOppositeWindow() == null) { // return null if window is not from my (or Your) work
for (SlveFrame frame : frames) { // if you have no idea what this is, look for "for each loop java" in google
frame.toFront();
}
}
}
/**
* The use of SlveFrame is almost the same as Jframe
*/
@Override
public void setVisible (boolean b) {
if (b)
frames.add(this);
else
frames.remove(this); // may raise an exception if you're not careful
super.setVisible(b); // or your window will simply not be visible.
}
@Override
public void dispose () {
frames.dispose(this) // may raise an exception you'll want to handle
}
}
诀窍是WindowEvent.getOppositeWIndow()返回Jframe 如果JFrame(或子类)来自您自己的程序,这意味着如果您切换到另一个程序或应用程序(例如eclipse,Firefox或一个文本编辑器)然后回到你的任何一个窗口,然后调用 getOppositeWindow()将返回一个'null'。一个简单的if (e.getOppositeWindow())
可以很容易地确定你的窗口是否会在需要你将每个窗口都放在前面的情况下获得焦点,或者更确切地说是让所有窗口都放在前面。
覆盖 setVisible (boolean b)
和 dispose ()
是可选的,但允许开发人员将其用作常规窗口。
我希望能得到一些帮助。真诚地〜一个喇嘛