Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Support for Windows-Left and Windows-Right in undecorated JFrames

I use an undecorated JFrame with a custom title bar and custom resizer. All works fine but when I make a JFrame undecorated I lose the support for Windows-Left/Right key bindings (seems that it's native implemented by Windows). I want to reimplement this feature for my application. My problem: I can detect in a key listener whether the Windows key pressed, but I cannot detect whether another key (left/right in my case) is pressed together with Windows key (no modifier WINDOWS_MASK_DOWN in InputEvent). Probably somebody knows a workaround?

Here is my code:

import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class HeadlessFrameTest {

    public static void main(String[] args) {
        final JFrame frm = new JFrame("Test");
        final JTextField field = new JTextField();
        frm.add(field, BorderLayout.NORTH);
        field.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                System.out.println(e);
            }
        });
        frm.setUndecorated(true);
        frm.setSize(500, 550);
        frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frm.setVisible(true);
    }

}
like image 774
Sergiy Medvynskyy Avatar asked Oct 06 '14 16:10

Sergiy Medvynskyy


1 Answers

Well, I couldn’t test it properly as on my system, Windows+Left or Right were intercepted and processed by Windows even for undecorated frames, however adding another case for the unused combination Windows+A proved that the following code works if the host system does not consume the key shortcut:

(Update: since it seems to be the key pressed event which Windows consumes, a key release of Windows+Left or Right can be catched)

final JFrame frm = new JFrame("Test");
final JTextField field = new JTextField();
frm.add(field, BorderLayout.NORTH);
frm.getToolkit().addAWTEventListener(new AWTEventListener() {
    boolean winDown;
    public void eventDispatched(AWTEvent event) {
        KeyEvent ev=(KeyEvent)event;
        final boolean pressed = ev.getID()==KeyEvent.KEY_PRESSED;
        if(ev.getKeyCode()==KeyEvent.VK_WINDOWS) winDown=pressed;
        else if(winDown) switch(ev.getKeyCode()) {
            case KeyEvent.VK_LEFT:
                System.out.println("windows + LEFT "+(pressed?"pressed":"released"));
                break;
            case KeyEvent.VK_RIGHT:
                System.out.println("windows + RIGHT "+(pressed?"pressed":"released"));
                break;
            case KeyEvent.VK_A:
                System.out.println("windows + A "+(pressed?"pressed":"released"));
                break;
        }
    }
}, KeyEvent.KEY_EVENT_MASK);
frm.setUndecorated(true);
frm.setSize(500, 550);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setVisible(true);

It seems that an ordinary key listener on a component does not work because the component loses the focus when Windows is pressed.

like image 152
Holger Avatar answered Nov 14 '22 22:11

Holger