Angela Hall
Angela Hall

Reputation: 37

How to stop Jframe from stealing keyboard input

I have written a program in Java that checks a restAPI every 8 seconds and, if it detects a state change, flashes a small alert on the screen in the bottom corner. The alert is intended to inform the user of a critical situation, but not interrupt their work. My problem is that when the Alert is triggered and the JFrame becomes visible, it steals the keyboard input. So while it is flashing, if the user wants to keep working in a different application, they have to continuously click back on that application.

I am using setVisible on the JFrame (changing it from false to true and back again) to create the "flashing" effect. Every time the JFrame.setVisible is set to true, Windows automatically focuses the keyboard input to the alert.

I have tried adding setFocusable(false) when initializing the JFrame, but that doesn't seem to have any effect.

Here is how I initialize the Jframe:

public AlertJFrame(int pos) {
        this.Position = pos; 
        setBounds(100, 100, 450, 300);
        setTitle("Alert"); 
        setResizable(false);
        setFocusable(false);
        setAlwaysOnTop(true);
        setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        setBounds(130, 130, 218, 120);
         GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice defaultScreen = ge.getDefaultScreenDevice();
            Rectangle rect = defaultScreen.getDefaultConfiguration().getBounds();
            int x = (int) rect.getMaxX() - this.getWidth();
            int y = (int) rect.getMaxY() - this.getHeight();
            x = x - 100; 
            y = y - pos; 
            setLocation(x,y); 
            setUndecorated(true);
            contentPane = new JPanel();
            contentPane.setBackground(new Color(255, 69, 0));
            contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
            setContentPane(contentPane);
            contentPane.setLayout(null); 
            this.message = new JLabel("<html>Starting Headsup<br>Contacting server...</html>"); 
            message.setHorizontalAlignment(SwingConstants.CENTER);
            message.setForeground(new Color(255,255,255));
            message.setFont(new Font("Tahoma", Font.PLAIN, 14));
            message.setBounds(10,11,198,98);
            contentPane.add(message); 

    }

and then I just call .setVisible(true) on the Jframe, and that's when it steals the keyboard input.

What i would like is for the window to flash on the users screen without interrupting their work.

Thanks

EDIT: It might be helpful to see an image. This is how the program looks when running. I'm using JFrames because of their ability to remove window decorations and to color, position, and resize them. Any changes I make, the basic output will still need to look like this. https://www.dropbox.com/s/x1z3isdln83stnm/headsup.png?dl=0

Thanks

Upvotes: 1

Views: 77

Answers (1)

Guillaume
Guillaume

Reputation: 14671

For alerts the SystemTray class would be better I think:

  SystemTray st = SystemTray.getSystemTray();
  TrayIcon icon = new TrayIcon(...);
  icon.displayMessage(...)

You'll find more info in the system tray documentation

Upvotes: 1

Related Questions