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:
- Ensure you have the JavaFX Swing module (
javafx.swing) added as a dependency in your project. - Initialize AWT and JavaFX on their respective threads (AWT uses the Event Dispatch Thread, JavaFX uses its own Application Thread).
- Embed your JavaFX scene into a
JFXPanel, then place that panel into an AWTJFrame. - Use Apple's
FullScreenUtilitiesto 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.eawtclasses—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:
- Add JNA dependencies (
jnaandjna-platform) to your project. - Use reflection to get the native
NSWindowpointer from your JavaFXStage. - Use JNA to call Cocoa methods and adjust the window's
collectionBehaviorto 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
相关产品推荐
相关产品推荐

