Best way to block all GUI input without displaying a dialog?

I'd like to achieve what is essentially the same functionality as a modal dialog but without using one. How would you go about blocking all input to a Swing component and it's ancestors? I tried walking up the containment heirarchy and adding my "wait screen" to the layered pane above everything else. Adding mouse and key listeners that consume all events seems to take care ofmost input, but hitting tab still changes focus and I'm not sure what other pitfalls await.

So what would the preferred way of handling this or is it even feasible?

[567 byte] By [kablaira] at [2007-10-3 8:15:40]
# 1

far from best, but this might suit for key input

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

class Testing

{

boolean wait = false;

public void buildGUI()

{

JPanel p = new JPanel(new BorderLayout());

p.add(new JTextField(10),BorderLayout.NORTH);

p.add(new JTextArea(5,10),BorderLayout.CENTER);

JComboBox cbo = new JComboBox(new String[]{"abc","def","xyz"});

cbo.setEditable(true);

JPanel p1 = new JPanel();

final JButton btn = new JButton("Disable Input");

p1.add(cbo);

p1.add(btn);

p.add(p1,BorderLayout.SOUTH);

JFrame f = new JFrame();

f.getContentPane().add(p);

f.pack();

f.setLocationRelativeTo(null);

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

btn.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent ae){

wait = !wait;

btn.setText((wait? "En":"Dis")+"able Input");

}

});

KeyboardFocusManager.getCurrentKeyboardFocusManager()

.addKeyEventDispatcher(new KeyEventDispatcher(){

public boolean dispatchKeyEvent(KeyEvent e){

return wait;

}

});

f.setVisible(true);

}

public static void main (String[] args)

{

SwingUtilities.invokeLater(new Runnable(){

public void run(){

new Testing().buildGUI();

}

});

}

}

also for mouse actions? if so, add a mouseListener to the frame's glasspane,

then toggle the glasspane's visibility

Michael_Dunna at 2007-7-15 3:20:43 > top of Java-index,Desktop,Core GUI APIs...
# 2

I had actually tried that approach prior to posting and it didn't work. Since you posted it as a suggestion I tried again and it works this time though my code is slightly different:

public boolean dispatchKeyEvent(final KeyEvent e) {

return SwingUtilities.isDescendingFrom(e.getComponent(), component);

}

Where component is the arbitrary JComponent that I'm blocking.

I'm noticing that adding a MouseAdapter and MouseMotionAdapter to the component that's being drawn on top is working now too where it didn't before. I suppose I can only conclude that I had something screwed up before, I have no idea what it could be. Regardless, that combination seems to be the answer and it also seems to only block for anything under my blocking component and not the entire frame which is what I wanted.

Thanks Michael. With that it looks friggin' awesome using some animation and the transparent components I've developed.

kablaira at 2007-7-15 3:20:43 > top of Java-index,Desktop,Core GUI APIs...
# 3

This might be another option. Seems to handle all KeyEvents, including tabs:

EventQueue queue = new EventQueue()

{

protected void dispatchEvent(AWTEvent event)

{

if (event.getID() == KeyEvent.KEY_TYPED

|| event.getID() == KeyEvent.KEY_PRESSED

|| event.getID() == KeyEvent.KEY_RELEASED)

{

return;

}

else

super.dispatchEvent(event);

}

};

Toolkit.getDefaultToolkit().getSystemEventQueue().push(queue);

You should be able to handle MouseEvents as well. You can then just pop() the queue to go back to the original (according to the API).

camickra at 2007-7-15 3:20:43 > top of Java-index,Desktop,Core GUI APIs...
# 4
Yeah, but wouldn't that stop all events? It shouldn't affect anything outside of the component being blocked or it's ancestors.
kablaira at 2007-7-15 3:20:43 > top of Java-index,Desktop,Core GUI APIs...
# 5
Well, I would expect you could check the source like you are currently doing.
camickra at 2007-7-15 3:20:43 > top of Java-index,Desktop,Core GUI APIs...
# 6
> Well, I would expect you could check the source like> you are currently doing.That didn't occur to me. I'll give it a try, seems like that would work a little better as it's not dependent upon using another component to intercept mouse events.
kablaira at 2007-7-15 3:20:43 > top of Java-index,Desktop,Core GUI APIs...
# 7
if the component doesn't change its state while disabled, you can replace it with an image snapshot of itself.Message was edited by: dberansky
dberanskya at 2007-7-15 3:20:43 > top of Java-index,Desktop,Core GUI APIs...
# 8
> I'd like to achieve what is essentially the same> functionality as a modal dialog private JFrame frame;...frame.setEnabled(false);
Andre_Uhresa at 2007-7-15 3:20:43 > top of Java-index,Desktop,Core GUI APIs...
# 9
That would kill the entire frame not just the component. If carnickr's suggestion works it seems best. Hopefully I'll get a chance to test it today.
kablaira at 2007-7-15 3:20:43 > top of Java-index,Desktop,Core GUI APIs...