我有一个项目JDesktopPane
用于主要应用程序和一堆JInternalFrame
s 用于一系列独立分析。
某些分析是耗时的,因此我在SwingWorker
s 上运行它们,但我想禁用 GUI(因此没有操作排队)并通知用户某些操作正在进行并且这是正常的。
以前我为此目的使用了一个定制的 GlassPane,并且它以前工作得很好。现在我遇到了一些问题,使用与以前相同的类。具体来说,glassPane 拦截了预期的用户输入,但没有可见的视觉提示,这让我认为paintComponent()
从未在 glassPane 上调用过。
只是为了确保我在谷歌上搜索并遇到DisabledGlassPane
了“please-wait-glassPane”概念的另一个实现(称为),但实际上没有成功。在尝试调试问题时,我意识到当我启动/激活我的 glassPane 时,默认情况下它是无效的,并且不会自行验证。
如果我在激活 glassPane 后专门调用validate()
它JInternalFrame
,它似乎是有效且可见的,基于 glassPane 的属性,但我在屏幕上什么也看不到(GlassPane 实现都具有基于颜色和文本的功能,应该立即对用户)。
编辑:
下面是相关的代码片段,从更大的方案中提取到一个极简的、独立的(除了DisabledGlassPane
上面提到的类,为简洁起见省略)示例。当我运行DesktopFrame
下面的课程并单击按钮开始计算时,光标变为等待模式,但屏幕没有变灰,并且没有显示给用户的消息,因此我的怀疑paintComponent
从未真正调用过。
我主要想知道我是否有明显的失误,因为我对 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) {}
}