Drawing a Screen

Published — Edited

This guide assumes that you have already read Creating a Screen.

Code Point

A code point is an integer which represents a Unicode character. Although there are a vast number of characters to choose from, you are limited to those that are supported by your chosen font. The default font is currently DejaVu Sans Mono and its supported characters can be found here.

You can change the code point of a specific tile by specifying both a position and a code point. The code point can be given as a character, integer, or hexadecimal value.


public class ExampleA {
	public static void main(final String[] args) {
		try {
			UIManager.setLookAndFeel(VTerminalLookAndFeel.getInstance(24));
		} catch (final UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}

		SwingUtilities.invokeLater(() -> {
			final var frame = new VFrame(40, 20);
			frame.setVisible(true);
			frame.pack();
			frame.setLocationRelativeTo(null);

			final var panel = frame.getContentPane();
			panel.setCodePointAt(0, 0, 'A');
			panel.setCodePointAt(1, 1, 66);
			panel.setCodePointAt(2, 2, 0x43);
		});
	}
}

A visual example of the preceding code.

Background Color

A background color is the base color of a tile and it is drawn behind the displayed character, if there is one. You can change the background color of a specific tile by specifying both a position and a color.

As Swing supports non-opaque components, you are allowed to use transparent colors (i.e. colors with an alpha value). However, that is beyond the scope of this guide.


public class ExampleB {
	public static void main(final String[] args) {
		try {
			UIManager.setLookAndFeel(VTerminalLookAndFeel.getInstance(24));
		} catch (final UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}

		SwingUtilities.invokeLater(() -> {
			final var frame = new VFrame(40, 20);
			frame.setVisible(true);
			frame.pack();
			frame.setLocationRelativeTo(null);

			final var panel = frame.getContentPane();
			panel.setCodePointAt(0, 0, 'A');
			panel.setBackgroundAt(0, 0, Color.MAGENTA);
		});
	}
}

A visual example of the preceding code.

You can also set the background color of every tile as follows.


public class ExampleE {
	public static void main(final String[] args) {
		try {
			UIManager.setLookAndFeel(VTerminalLookAndFeel.getInstance(24));
		} catch (final UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}

		SwingUtilities.invokeLater(() -> {
			final var frame = new VFrame(40, 20);
			frame.setVisible(true);
			frame.pack();
			frame.setLocationRelativeTo(null);

			final var panel = frame.getContentPane();
			panel.setBackground(Color.MAGENTA);

			for (int y = 0 ; y < panel.getHeightInTiles() ; y++) {
				for (int x = 0 ; x < panel.getWidthInTiles() ; x++) {
					panel.setCodePointAt(x, y, getRandomCodePoint());
				}
			}
		});
	}

	private static int getRandomCodePoint() {
		return ThreadLocalRandom.current().nextInt(33, 126);
	}
}

A visual example of the preceding code.

Foreground Color

A foreground color is the color of the character displayed on a tile. You can change the foreground color of a specific tile by specifying both a position and a color.

As Swing supports non-opaque components, you are allowed to use transparent colors (i.e. colors with an alpha value). However, that is beyond the scope of this guide.


public class ExampleC {
	public static void main(final String[] args) {
		try {
			UIManager.setLookAndFeel(VTerminalLookAndFeel.getInstance(24));
		} catch (final UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}

		SwingUtilities.invokeLater(() -> {
			final var frame = new VFrame(40, 20);
			frame.setVisible(true);
			frame.pack();
			frame.setLocationRelativeTo(null);

			final var panel = frame.getContentPane();
			panel.setCodePointAt(0, 0, 'A');
			panel.setForegroundAt(0, 0, Color.MAGENTA);
		});
	}
}

A visual example of the preceding code.

You can also set the foreground color of every tile as follows.


public class ExampleD {
	public static void main(final String[] args) {
		try {
			UIManager.setLookAndFeel(VTerminalLookAndFeel.getInstance(24));
		} catch (final UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}

		SwingUtilities.invokeLater(() -> {
			final var frame = new VFrame(40, 20);
			frame.setVisible(true);
			frame.pack();
			frame.setLocationRelativeTo(null);

			final var panel = frame.getContentPane();
			panel.setForeground(Color.MAGENTA);
			
			for (int y = 0 ; y < panel.getHeightInTiles() ; y++) {
				for (int x = 0 ; x < panel.getWidthInTiles() ; x++) {
					panel.setCodePointAt(x, y, getRandomCodePoint());
				}
			}
		});
	}

	private static int getRandomCodePoint() {
		return ThreadLocalRandom.current().nextInt(33, 126);
	}
}

A visual example of the preceding code.

Sequential Image Operation (Shader)

A sequential image operation (SequentialOp) can be thought of as a shader. It performs one or more image operations (BufferedImageOp) on the character of a tile, before the character is drawn on the tile.

Please do not attempt to run the following examples as they require the image filters by JH Labs, and the code will fail without this dependency.


public class ExampleF {
	public static void main(final String[] args) {
		try {
			UIManager.setLookAndFeel(VTerminalLookAndFeel.getInstance(24));
		} catch (final UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}

		SwingUtilities.invokeLater(() -> {
			final var frame = new VFrame(40, 20);
			frame.setVisible(true);
			frame.pack();
			frame.setLocationRelativeTo(null);

			final var sequentialOp = new SequentialOp(new GaussianFilter(6));

			final var panel = frame.getContentPane();
			panel.setCodePointAt(0, 0, 'A');
			panel.setSequentialImageOpAt(0, 0, sequentialOp);
		});
	}
}

A visual example of the preceding code.


public class ExampleG {
	public static void main(final String[] args) {
		try {
			UIManager.setLookAndFeel(VTerminalLookAndFeel.getInstance(24));
		} catch (final UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}

		SwingUtilities.invokeLater(() -> {
			final var frame = new VFrame(40, 20);
			frame.setVisible(true);
			frame.pack();
			frame.setLocationRelativeTo(null);

			final var sequentialOp = new SequentialOp(
				new MarbleFilter(),
				new GaussianFilter()
			);

			final var panel = frame.getContentPane();
			panel.setCodePointAt(0, 0, 'A');
			panel.setSequentialImageOpAt(0, 0, sequentialOp);
		});
	}
}

A visual example of the preceding code.