You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mac下JavaFX窗口转AWT窗口方法咨询及禁用全屏替代方案

Great question! I've dealt with this exact issue when working with JavaFX on macOS, so let's break down your options to disable full-screen functionality properly.


Option 1: Convert JavaFX Window to AWT Using JFXPanel

The Apple com.apple.eawt API requires an AWT window, but you can bridge JavaFX and AWT using JFXPanel—a component that lets you embed JavaFX content inside an AWT/Swing window. This approach uses Apple's official API, so it's stable and reliable.

Step-by-Step Implementation:

  1. Ensure you have the JavaFX Swing module (javafx.swing) added as a dependency in your project.
  2. Initialize AWT and JavaFX on their respective threads (AWT uses the Event Dispatch Thread, JavaFX uses its own Application Thread).
  3. Embed your JavaFX scene into a JFXPanel, then place that panel into an AWT JFrame.
  4. Use Apple's FullScreenUtilities to disable full-screen on the AWT frame.

Code Example:

import com.apple.eawt.FullScreenUtilities;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javax.swing.JFrame;
import java.awt.EventQueue;

public class JavaFXToAWTFullScreenFix {
    public static void main(String[] args) {
        // Initialize AWT components on the Event Dispatch Thread
        EventQueue.invokeLater(() -> {
            JFrame awtFrame = new JFrame("JavaFX in AWT (No Full Screen)");
            awtFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            // Create JFXPanel to host JavaFX content
            JFXPanel fxPanel = new JFXPanel();
            awtFrame.add(fxPanel);

            // Initialize JavaFX scene on the JavaFX Application Thread
            Platform.runLater(() -> {
                Label content = new Label("This is JavaFX content in an AWT window");
                Scene fxScene = new Scene(content, 400, 300);
                fxPanel.setScene(fxScene);
            });

            awtFrame.pack();
            awtFrame.setVisible(true);

            // Disable full-screen using Apple's AWT API
            FullScreenUtilities.setWindowCanFullScreen(awtFrame, false);
        });
    }
}

Notes:

  • This approach works across all recent macOS versions and JavaFX releases (8+).
  • You'll need to ensure your JVM has access to the com.apple.eawt classes—they're included by default in Oracle/OpenJDK builds for macOS.

Option 2: Disable Full Screen Directly in JavaFX (No AWT Conversion)

If you want to keep a pure JavaFX window (no AWT dependencies), you can directly interact with the underlying macOS NSWindow using JNA and reflection. This lets you modify the window's Cocoa properties to block full-screen mode.

Step-by-Step Implementation:

  1. Add JNA dependencies (jna and jna-platform) to your project.
  2. Use reflection to get the native NSWindow pointer from your JavaFX Stage.
  3. Use JNA to call Cocoa methods and adjust the window's collectionBehavior to remove full-screen permissions.

Code Example:

import com.sun.jna.Native;
import com.sun.jna.platform.mac.Foundation;
import javafx.application.Application;
import javafx.stage.Stage;

public class JavaFXNativeFullScreenDisable extends Application {

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Pure JavaFX (No Full Screen)");
        primaryStage.setWidth(400);
        primaryStage.setHeight(300);
        primaryStage.show();

        // Get the underlying NSWindow pointer from the JavaFX Stage
        long nsWindowPtr = getNSWindowPointer(primaryStage);
        if (nsWindowPtr != 0) {
            // Remove the full-screen behavior mask from the window's collectionBehavior
            long currentBehavior = Foundation.invokeLong(nsWindowPtr, "collectionBehavior");
            final long FULL_SCREEN_MASK = 1L << 7; // NSWindowCollectionBehaviorFullScreenPrimary
            long updatedBehavior = currentBehavior & ~FULL_SCREEN_MASK;
            Foundation.invokeVoid(nsWindowPtr, "setCollectionBehavior:", updatedBehavior);
        }
    }

    private long getNSWindowPointer(Stage stage) {
        try {
            // Reflectively access internal JavaFX APIs to get the native window pointer
            Object peer = stage.getClass().getMethod("getPeer").invoke(stage);
            Object platformWindow = peer.getClass().getMethod("getPlatformWindow").invoke(peer);
            return (long) platformWindow.getClass().getMethod("getNativeWindow").invoke(platformWindow);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

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

Notes:

  • This uses internal JavaFX APIs, so it may break between JavaFX versions (tested on JavaFX 11-21).
  • It only works on macOS—you'll need to add platform checks if your app runs on other OSes.

Final Recommendation:

  • Use Option 1 if you can tolerate adding AWT/Swing dependencies—it's the most stable and future-proof solution.
  • Use Option 2 if you need a pure JavaFX implementation, but be prepared to adjust the code if JavaFX's internal APIs change.

内容的提问来源于stack exchange,提问作者Dan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:00:31