我有一个项目,在该项目中,我将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/

10-12 00:36