6

I want my JavaFX App to be maximizable by Alt+Enter, so I added:

scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
    if (event.getCode() == KeyCode.ENTER) {
        if (event.isAltDown()) {
            setFullScreen(!stage.isFullScreen());
            event.consume();
        }
    }
});

However, it seems that all JavaFX applications by default play a "beep" sound effect when Alt+Enter is pressed (not sure why...). How would I go on removing this sound effect?

Enigo
  • 3,685
  • 5
  • 29
  • 54
user38725
  • 876
  • 1
  • 10
  • 26

2 Answers2

0

I am guessing you are programming in Windows, and thus the beep you get is the default beep sound.

Based upon this forum post, it seems that ALT+KEY is not found as a menu shortcut. This is most likely due to Mnemonic Parsing, which allows you to add keyboard shortcuts to menu items, like ALT+F for File, ALT+S for Save, etc...

Based on one of the posts, Windows seems to want to grab that key combo as well, but it can not find it, so it beeps.

I am not sure if you can add an ENTER as a mnemonic identifier, but you can read through this post about javafx mnemonics, as well as this post about button accelerators. I know the second one is JavaFx 2.2, but it should still be valid. Those should give you some good ideas on how to tackle this problem more thoroughly.

Hypnic Jerk
  • 1,192
  • 3
  • 14
  • 32
  • Well, I tried to register accelerator & mnemonic directly into scene. Then I tried to add a menubar into the scene with menu & item in it, with an accelerator "Alt+Enter", however, the beep still plays. – user38725 Jul 17 '18 at 17:51
  • 1
    My only other idea is to not use ALT and a different key. Sorry I couldn't be of further help. – Hypnic Jerk Jul 17 '18 at 17:52
0

I faced the same problem and solved it by using Windows API to subclass a window. If you are allowed to use JNA, the following code would help you.

MyUser32.java

import com.sun.jna.Callback;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.*;
import com.sun.jna.win32.W32APIOptions;

public interface MyUser32 extends User32 {
    int WM_MENUCHAR = 0x0120;
    int MNC_CLOSE = 1;
    int VK_RETURN = 0x0d;

    MyUser32 INSTANCE = Native.loadLibrary("user32", MyUser32.class, W32APIOptions.UNICODE_OPTIONS);

    LONG_PTR SetWindowLongPtr(WinDef.HWND hWnd, int nIndex, Callback callback);
    LRESULT CallWindowProc(LONG_PTR lpPrevWndProc, HWND hWnd, int Msg, WPARAM wParam, LPARAM lParam);
}

App.java

import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.*;
import com.sun.jna.platform.win32.WinDef.*;
import com.sun.jna.win32.StdCallLibrary;
import javafx.application.Application;
import javafx.stage.Stage;
import java.lang.reflect.Method;

public class App extends Application implements StdCallLibrary.StdCallCallback {

    private BaseTSD.LONG_PTR baseWndProc;

    public static void main(String[] args) { launch(args); }

    @Override
    public void start(Stage primaryStage) {

        // set up scene ...

        primaryStage.show();

        final HWND hWnd = new HWND(getWindowPointer(primaryStage));
        baseWndProc = MyUser32.INSTANCE.SetWindowLongPtr(hWnd, User32.GWL_WNDPROC, this);
    }

    public LRESULT callback(HWND hWnd, int Msg, WPARAM wParam, LPARAM lParam) {
        if (Msg == MyUser32.WM_MENUCHAR && (wParam.longValue() & 0xffff) == MyUser32.VK_RETURN) {
            return new LRESULT(MyUser32.MNC_CLOSE << 16);
        }

        return MyUser32.INSTANCE.CallWindowProc(baseWndProc, hWnd, Msg, wParam, lParam);
    }

    private Pointer getWindowPointer(Stage stage) {
        try {
            Method getPeer = stage.getClass().getMethod("impl_getPeer");
            final Object tkStage = getPeer.invoke(stage);
            Method getPlatformWindow = tkStage.getClass().getDeclaredMethod("getPlatformWindow");
            getPlatformWindow.setAccessible(true);
            final Object platformWindow = getPlatformWindow.invoke(tkStage);
            Method getNativeHandle = platformWindow.getClass().getMethod("getNativeHandle");
            return new Pointer((Long) getNativeHandle.invoke(platformWindow));
        } catch (Throwable t) {
            return null;
        }
    }
}

References

Disable MessageBeep on Invalid Syskeypress

Why my JNA using application doesn't react in a right way?

How can I get the window handle (hWnd) for a Stage in JavaFX?

hotaka
  • 1
  • 1