我有一个项目,在该项目中,我将JDesktopPane
用于主要应用程序,并将一堆JInternalFrame
用于一系列独立的分析。
分析的某些位非常耗时,因此我在SwingWorker
上运行它们,但是我想同时禁用GUI(因此没有任何操作排队)并通知用户某些操作正在进行并且是正常的。
以前,我已经为此目的使用了自定义的GlassPane,并且之前效果很好。现在,我使用与以前相同的类遇到了一些问题。具体来说,glassPane会拦截用户的输入,这是预期的,但看不到视觉提示,这使我认为paintComponent()
从未在glassPane上调用。
只是确保我在Google上搜索并遇到了“ please-wait-glassPane”概念的另一个实现(称为DisabledGlassPane
),但实际上没有成功。在尝试调试该问题时,我意识到,当我启动/激活我的glassPane时,默认情况下它是无效的,并且自身未得到验证。
如果我在激活glassPane之后专门在validate()
上调用JInternalFrame
,则根据glassPane的属性,它似乎是有效且可见的,但我在屏幕上看不到任何东西(两个GlassPane实现均具有基于颜色和文本的功能,应该立即对用户可见)。
编辑:
下面是相关的代码,从更大的方案中提取出了一个极简的,独立的(上面提到的DisabledGlassPane
类除外,为简洁起见而省略)示例。当我运行下面的DesktopFrame
类时,单击按钮,计算开始,光标变为等待模式,但是屏幕没有变灰,并且没有显示给用户的消息,因此我怀疑从未真正被调用过。
我主要想知道我是否已经明显错过了,因为我没有GUI编程和Swing的经验。
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.ExecutionException;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.SwingWorker;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
public class DesktopFrame extends JFrame implements InternalFrameListener{
private JDesktopPane dpane;
private JInternalFrame f;
static DisabledGlassPane gp = new DisabledGlassPane();
public DesktopFrame() {
dpane = new javax.swing.JDesktopPane();
dpane.setPreferredSize(new java.awt.Dimension(1020, 778));
setContentPane(dpane);
addFrame();
pack();
}
public JInternalFrame addFrame(){
f = new JInternalFrame("test");
f.setGlassPane(gp);
f.addInternalFrameListener(this);
f.setLayout(new GridLayout());
f.setPreferredSize(new java.awt.Dimension(400,300));
f.add(new javax.swing.JLabel("something something"));
f.add(new javax.swing.JTextArea(10, 10));
javax.swing.JButton but = new JButton("click me!");
but.setPreferredSize(new java.awt.Dimension(100,50));
but.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
gp.activate("Please wait...");
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
for(float i=-3000; i < 3000; i = i + 0.01f){
double exp = Math.pow(2,i);
double fac = Math.pow(i, 2);
System.out.println(exp/fac);
}
return null;
}
};
worker.execute();
try {
if(worker.get() == null)
gp.deactivate();
} catch (InterruptedException | ExecutionException e1) {
e1.printStackTrace();
}
}
});
f.add(but);
f.setVisible(true);
f.pack();
dpane.add(f);
try {
f.setSelected(true);
} catch (java.beans.PropertyVetoException e) {
e.printStackTrace();
}
dpane.repaint();
return f;
}
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
DesktopFrame df = new DesktopFrame();
df.setLocationRelativeTo(null);
df.setVisible(true);
df.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
});
}
@Override
public void internalFrameOpened(InternalFrameEvent e) {}
@Override
public void internalFrameClosing(InternalFrameEvent e) {}
@Override
public void internalFrameClosed(InternalFrameEvent e) {}
@Override
public void internalFrameIconified(InternalFrameEvent e) {}
@Override
public void internalFrameDeiconified(InternalFrameEvent e) {}
@Override
public void internalFrameActivated(InternalFrameEvent e) {}
@Override
public void internalFrameDeactivated(InternalFrameEvent e) {}
}
最佳答案
但我想同时禁用GUI(这样就不会有任何操作排队)并通知用户某些操作正在进行且很正常。
查看Disable Glass Pane以获取可能使用的一般解决方案。上面的类拦截鼠标和键事件,并允许您在可见的玻璃窗格中显示一条消息。
关于java - 为了使GlassPane可见并对于JInternalFrame有效,必须使用哪种伏都教?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24612588/