javaglasspane

Glasspane does not work, java


I have been working on a little java application, and I wanted to add a waiting graphics on the glasspane of the rootpane of the application, here is the classes:

public class WaitPanel extends JPanel {

public WaitPanel() {
    this.setLayout(new BorderLayout());
    JLabel label = new JLabel(new ImageIcon("spin.gif"));
    this.setLayout(new BorderLayout());
    this.add(label, BorderLayout.CENTER);
    this.setOpaque(false);

    this.setLayout(new GridBagLayout());

    this.addMouseListener(new MouseAdapter() {
        public void mousePressed(MouseEvent me) {
            me.consume();
            Toolkit.getDefaultToolkit().beep();
        }
    });
}

public void paintComponent(Graphics g) {
    g.setColor(new Color(0, 0, 0, 140));
    g.fillRect(0, 0, getWidth(), getHeight());
}}

and the main class :

public class NewJFrame extends JFrame {

public NewJFrame() {
    JButton button =new JButton("Click");
    getContentPane().setLayout(new FlowLayout());
    this.getContentPane().add(button);
    button.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            getRootPane().setGlassPane(new WaitPanel());
            getRootPane().getGlassPane().setVisible(true);
        }
    });
}

but when I change the button action to :

getRootPane().setGlassPane(new WaitPanel());
getRootPane().getGlassPane().setVisible(true);
Scanner sc=new Scanner(System.in);
String s=sc.next();
getRootPane().getGlassPane().setVisible(false);

It does not work.


Solution

  • Your problem (one of them) is that your code freezes the Swing event thread with its use of a Scanner based on System.in, and in so doing prevents the GUI from updating its graphics, including it's glass pane. Solution -- don't do that. If you want to block the GUI or pause it, use a Swing Timer, or a JOptionPane.

    For instance, you could change

    getRootPane().setGlassPane(new WaitPanel());
    getRootPane().getGlassPane().setVisible(true);
    Scanner sc=new Scanner(System.in);
    String s=sc.next();
    getRootPane().getGlassPane().setVisible(false);
    

    to something like this:

    getRootPane().setGlassPane(new WaitPanel());
    getRootPane().getGlassPane().setVisible(true);
    
    int delay = 4 * 1000; // 4 second delay
    new javax.swing.Timer(delay, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            getRootPane().getGlassPane().setVisible(false);
            ((javax.swing.Timer) e).stop();
        }
    }).start();