2

我有一个项目JDesktopPane用于主要应用程序和一堆JInternalFrames 用于一系列独立分析。

某些分析是耗时的,因此我在SwingWorkers 上运行它们,但我想禁用 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) {}
}
4

1 回答 1

0

但我想禁用 GUI(因此没有操作排队)并通知用户正在进行某些操作并且这是正常的。

查看禁用玻璃窗格以获取您可以使用的通用解决方案。上面的类拦截鼠标和按键事件,并允许您在玻璃窗格可见时显示消息。

于 2014-07-07T14:13:56.180 回答