使用Alt + Enter最大化JavaFX Stage时消除蜂鸣声

时间:2018-07-17 16:38:44

标签: java javafx

我希望通过Alt + Enter最大化JavaFX App,所以我添加了:

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

但是,默认情况下,似乎所有JavaFX应用程序在按Alt + Enter时都会播放“哔”声效果(不确定原因...)。我将如何继续消除这种音效?

2 个答案:

答案 0 :(得分:0)

我猜您正在Windows中进行编程,因此,您收到的提示音是默认的提示音。

基于this forum post,似乎没有找到ALT+KEY作为菜单快捷方式。这很可能是由于Mnemonic Parsing所致,它允许您向菜单项添加键盘快捷键,例如ALT+F代表文件,ALT+S代表保存,等等...

基于其中一篇文章,Windows似乎也希望抓住该组合键,但找不到它,因此发出哔哔声。

我不确定是否可以添加ENTER作为助记符标识符,但可以同时读取this post about javafx mnemonicsthis post about button accelerators。我知道第二个是JavaFx 2.2,但它仍然有效。这些应该给您一些关于如何更彻底地解决此问题的好主意。

答案 1 :(得分:0)

我遇到了同样的问题,并通过使用Windows API子类化了一个窗口来解决了这个问题。 如果允许您使用JNA,则以下代码将为您提供帮助。

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);

    int 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) {

        // setup 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;
        }
    }
}

参考

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?