I'm a beginner of JavaFX. Is there anyway to change the color of title bar. I just want to make the application all black. I have searched the JavaFX API, but I can't find any method to make it.
This is pretty much an OS dependent thing. The operating system gets to decide how titlebars and borders are displayed by default. However, it definitely can be done, if you are willing to venture into making your own title bar.
To start out, you will need to modify the application window's stage to StageStyle.UNDECORATED
. Then you will need to set up your own borders and title bar (complete with things like the title, minimize button, close button, etc.). You can then add the border pane as a scene into your application's stage, and that should render your custom titlebar then without the default Windows styling.
You can find an example implementation of that here: https://mcmap.net/q/482660/-javafx-primarystage-remove-windows-borders-duplicate
Do note that because you are implementing your own titlebar, you will also lose the OS's default window drag behavior, so you will need to implement your own window-drag/window-move code. This answer might be able to help you with that: https://mcmap.net/q/502052/-moving-an-undecorated-stage-in-javafx-2
JNA.platform.win32
? If all I want is SetSysColors
? –
Parsimonious There is a Windows API allowing you to set the color of the window title bar: DwmSetWindowAttribute and how it can be used.
With JNA you can access this API like this:
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef;
import javafx.stage.Stage;
import javafx.stage.Window;
import lombok.val;
public class FXWinUtil {
public static WinDef.HWND getNativeHandleForStage(Stage stage) {
try {
val getPeer = Window.class.getDeclaredMethod("getPeer", null);
getPeer.setAccessible(true);
val tkStage = getPeer.invoke(stage);
val getRawHandle = tkStage.getClass().getMethod("getRawHandle");
getRawHandle.setAccessible(true);
val pointer = new Pointer((Long) getRawHandle.invoke(tkStage));
return new WinDef.HWND(pointer);
} catch (Exception ex) {
System.err.println("Unable to determine native handle for window");
return null;
}
}
public static void setDarkMode(Stage stage, boolean darkMode) {
val hwnd = FXWinUtil.getNativeHandleForStage(stage);
val dwmapi = Dwmapi.INSTANCE;
WinDef.BOOLByReference darkModeRef = new WinDef.BOOLByReference(new WinDef.BOOL(darkMode));
dwmapi.DwmSetWindowAttribute(hwnd, 20, darkModeRef, Native.getNativeSize(WinDef.BOOLByReference.class));
forceRedrawOfWindowTitleBar(stage);
}
private static void forceRedrawOfWindowTitleBar(Stage stage) {
val maximized = stage.isMaximized();
stage.setMaximized(!maximized);
stage.setMaximized(maximized);
}
}
Dwmapi.java:
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.PointerType;
import com.sun.jna.platform.win32.WinDef;
public interface Dwmapi extends Library {
Dwmapi INSTANCE = Native.load("dwmapi", Dwmapi.class);
int DwmSetWindowAttribute(WinDef.HWND hwnd, int dwAttribute, PointerType pvAttribute, int cbAttribute);
}
The code allows you to activate the dark mode of the window title bar via:
FXWinUtil.setDarkMode(stage, true);
Note that Native.getNativeSize(WinDef.BOOLByReference.class)
in the sample code is somewhat incorrect. It should be BOOL.SIZE
. The example above happens to work because Native.getNativeSize(WinDef.BOOLByReference.class)
and BOOL.SIZE
happens to be the same. This is not the case when passing a DWORD
value:
DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, new BOOLByReference(new BOOL(enabled)), BOOL.SIZE);
DwmSetWindowAttribute(hwnd, DWMWA_BORDER_COLOR, new DWORDByReference(new DWORD(color)), DWORD.SIZE);
© 2022 - 2024 — McMap. All rights reserved.