Skip to content

Instantly share code, notes, and snippets.

@jdabtieu
Last active March 28, 2022 03:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdabtieu/9c46b1ca23630e657a6262d854476320 to your computer and use it in GitHub Desktop.
Save jdabtieu/9c46b1ca23630e657a6262d854476320 to your computer and use it in GitHub Desktop.
Enables colors in the Windows terminal for Java console programs. Read the comment before blindly copy pasting!
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.net.URLClassLoader;
public class Main {
static void enableColor() {
// https://stackoverflow.com/questions/52767585/how-can-you-use-vt100-escape-codes-in-java-on-windows
try {
// Load classes
URLClassLoader loader = new URLClassLoader(new URL[] {
new URL("https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.11.0/jna-5.11.0.jar"),
new URL("https://repo1.maven.org/maven2/net/java/dev/jna/jna-platform/5.11.0/jna-platform-5.11.0.jar")});
Class<?> Function = loader.loadClass("com.sun.jna.Function");
Class<?> WinDef = loader.loadClass("com.sun.jna.platform.win32.WinDef");
Class<?> WinNT = loader.loadClass("com.sun.jna.platform.win32.WinNT");
Class<?> HANDLE = null;
Class<?> DWORD = null;
Class<?> BOOL = null;
Class<?> DWORDByReference = null;
for (Class<?> c : WinDef.getClasses()) {
if (c.getSimpleName().equals("BOOL")) BOOL = c;
else if (c.getSimpleName().equals("DWORD")) DWORD = c;
else if (c.getSimpleName().equals("DWORDByReference")) DWORDByReference = c;
}
for (Class<?> c : WinNT.getClasses()) {
if (c.getSimpleName().equals("HANDLE")) HANDLE = c;
}
Object GetStdHandleFunc = Function.getDeclaredMethod("getFunction", String.class, String.class).invoke(null, "kernel32", "GetStdHandle");
Object STD_OUTPUT_HANDLE = DWORD.getConstructor(long.class).newInstance(-11);
Object hOut = Function.getMethod("invoke", Class.class, Object[].class).invoke(GetStdHandleFunc, HANDLE, new Object[] {STD_OUTPUT_HANDLE});
Object p_dwMode = DWORDByReference.getConstructor(DWORD).newInstance(DWORD.getConstructor(long.class).newInstance(0));
Object GetConsoleModeFunc = Function.getDeclaredMethod("getFunction", String.class, String.class).invoke(null, "kernel32", "GetConsoleMode");
Function.getMethod("invoke", Class.class, Object[].class).invoke(GetConsoleModeFunc, BOOL, new Object[] {hOut, p_dwMode});
int ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4;
Object dwMode = DWORDByReference.getMethod("getValue").invoke(p_dwMode);
DWORD.getMethod("setValue", long.class).invoke(dwMode, (int) DWORD.getMethod("intValue").invoke(dwMode) | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
Object SetConsoleModeFunc = Function.getDeclaredMethod("getFunction", String.class, String.class).invoke(null, "kernel32", "SetConsoleMode");
Function.getMethod("invoke", Class.class, Object[].class).invoke(SetConsoleModeFunc, BOOL, new Object[] {hOut, dwMode});
loader.close();
} catch (IOException | ClassNotFoundException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | InstantiationException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
enableColor();
final String ANSI_RED = "\u001B[31m";
System.out.println("Demo: " + ANSI_RED + "red");
}
}
@jdabtieu
Copy link
Author

To use: simply add the call to enableColor() anywhere before the first print statement with color. Typically, right at the start of main will work.

Demo (with color enabled):
image

Demo (without enabling color):
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment