Saturday, April 13, 2013

Painting in Java SWT

Painting in Java SWT

In this part of the Java SWT tutorial, we will do some painting.
When do we need to paint? There are situations, when we need to create a widget from scratch. In such a case, we need to do painting. Or we want to create charts, special ornaments, effects or widget enhancements.

Colors

In the first example, we will work with colors. A color is an object representing a combination of Red, Green, and Blue (RGB) intensity values. In Java SWT, valid RGB values are in the range 0 to 255.
package com.zetcode;

import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

/**
* ZetCode Java SWT tutorial
*
* This program draws three rectangles.
* The interiors are filled with
* different colors.
*
* @author jan bodnar
* website zetcode.com
* last modified June 2009
*/
public class SWTApp {

private Shell shell;

public SWTApp(Display display) {

shell = new Shell(display);

shell.addPaintListener(new ColorsPaintListener());

shell.setText("Colors");
shell.setSize(360, 120);
shell.setLocation(300, 300);
shell.open();

while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}

private class ColorsPaintListener implements PaintListener {

public void paintControl(PaintEvent e) {

drawRectangles(e);

e.gc.dispose();
}
}

private void drawRectangles(PaintEvent e) {
Color c1 = new Color(e.display, 50, 50, 200);
e.gc.setBackground(c1);
e.gc.fillRectangle(10, 15, 90, 60);

Color c2 = new Color(e.display, 105, 90, 60);
e.gc.setBackground(c2);
e.gc.fillRectangle(130, 15, 90, 60);

Color c3 = new Color(e.display, 33, 200, 100);
e.gc.setBackground(c3);
e.gc.fillRectangle(250, 15, 90, 60);

c1.dispose();
c2.dispose();
c3.dispose();
}

public static void main(String[] args) {
Display display = new Display();
new SWTApp(display);
display.dispose();
}
}
In our example, we will draw three rectangles and fill them with three different colors.
shell.addPaintListener(new ColorsPaintListener());
We create a listener for paint events.
private class ColorsPaintListener implements PaintListener {

public void paintControl(PaintEvent e) {

drawRectangles(e);

e.gc.dispose();
}
}
When a paint event is received, the paintControl() is executed. The actual drawing is delegated to the drawRectangles() method.
Color c1 = new Color(e.display, 50, 50, 200);
e.gc.setBackground(c1);
e.gc.fillRectangle(10, 15, 90, 60);
We create a color object and fill a rectangle with it.
c1.dispose();
c2.dispose();
c3.dispose();
e.gc.dispose();
Resources are released.
Colors
Figure: Colors

Basic shapes

The next example draws some basic shapes onto the window.
package com.zetcode;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

/**
* ZetCode Java SWT tutorial
*
* In this program, we draw some
* basic shapes of the Java SWT library
*
* @author jan bodnar
* website zetcode.com
* last modified June 2009
*/

public class SWTApp {

private Shell shell;

public SWTApp(Display display) {

shell = new Shell(display);

shell.addPaintListener(new ArcExamplePaintListener());

shell.setText("Basic shapes");
shell.setSize(430, 300);
shell.setLocation(300, 300);
shell.open();

while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}

private class ArcExamplePaintListener implements PaintListener {

public void paintControl(PaintEvent e) {

drawShapes(e);
e.gc.dispose();
}
}

private void drawShapes(PaintEvent e) {

e.gc.setAntialias(SWT.ON);

e.gc.setBackground(new Color(e.display, 150, 150, 150));

e.gc.fillRectangle(20, 20, 120, 80);
e.gc.fillRectangle(180, 20, 80, 80);
e.gc.fillOval(290, 20, 120, 70);

e.gc.fillOval(20, 150, 80, 80);
e.gc.fillRoundRectangle(150, 150, 100, 80, 25, 25);
e.gc.fillArc(280, 150, 100, 100, 0, 115);
}

public static void main(String[] args) {
Display display = new Display();
new SWTApp(display);
display.dispose();
}
}
In this example, we will create a rectangle, a square, an ellipse, a circle, a rounded rectangle, and an arc.
e.gc.fillRectangle(20, 20, 120, 80);
e.gc.fillRectangle(180, 20, 80, 80);
e.gc.fillOval(290, 20, 120, 70);
These lines draw a rectangle a square and an ellipse.
e.gc.fillOval(20, 150, 80, 80);
Here the fillOval() method draws a circle.
e.gc.fillRoundRectangle(150, 150, 100, 80, 25, 25);
e.gc.fillArc(280, 150, 100, 100, 0, 115);
These two lines draw a rounded rectangle and an arc.
Basic shapes
Figure: Basic shapes

Transparent rectangles

Transparency is the quality of being able to see through a material. The easiest way to understand transparency is to imagine a piece of glass or water. Technically, the rays of light can go through the glass and this way we can see objects behind the glass.
In computer graphics, we can achieve transparency effects using alpha compositing. Alpha compositing is the process of combining an image with a background to create the appearance of partial transparency. The composition process uses an alpha channel. (wikipedia.org, answers.com)
package com.zetcode;

import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

/**
* ZetCode Java SWT tutorial
*
* This program draws ten
* rectangles with different
* levels of transparency
*
* @author jan bodnar
* website zetcode.com
* last modified June 2009
*/

public class SWTApp {

private Shell shell;

public SWTApp(Display display) {

shell = new Shell(display);

shell.addPaintListener(new ArcExamplePaintListener());

shell.setText("Transparent rectangles");
shell.setSize(590, 120);
shell.setLocation(300, 300);
shell.open();

while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}

private class ArcExamplePaintListener implements PaintListener {

public void paintControl(PaintEvent e) {

drawRectangles(e);

e.gc.dispose();
}
}

private void drawRectangles(PaintEvent e) {

Color blue = new Color(e.display, 0, 0, 255);
e.gc.setBackground(blue);

for (int i = 1; i < 11; i++) {
e.gc.setAlpha(i * 25);
e.gc.fillRectangle(50 * i, 20, 40, 40);
}

blue.dispose();
}

public static void main(String[] args) {
Display display = new Display();
new SWTApp(display);
display.dispose();
}
}
In the example we will draw ten rectangles with different levels of transparency.
e.gc.setAlpha(i * 25);
Here we set the aplha transparency value for the painting process.
Transparent rectangles
Figure: Transparent rectangles

Donut

In the following example we create an complex shape by rotating a bunch of ellipses.
package com.zetcode;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Transform;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

/**
* ZetCode Java SWT tutorial
*
* This program creates a donut shape
*
* @author jan bodnar
* website zetcode.com
* last modified June 2009
*/
public class SWTApp {

private Shell shell;

public SWTApp(Display display) {

shell = new Shell(display);

shell.addPaintListener(new DonutPaintListener());

shell.setText("Donut");
shell.setSize(430, 300);
shell.setLocation(300, 300);
shell.open();

while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}

private class DonutPaintListener implements PaintListener {

public void paintControl(PaintEvent e) {

drawDonut(e);

e.gc.dispose();
}
}

private void drawDonut(PaintEvent e) {
int w = e.width;
int h = e.height;

e.gc.setAntialias(SWT.ON);

Transform tr = new Transform(e.display);
tr.translate(w / 2, h / 2);
e.gc.setTransform(tr);

for (int rot = 0; rot < 36; rot++) {
tr.rotate(5f);
e.gc.drawOval(-125, -40, 250, 80);
e.gc.setTransform(tr);
}
}

public static void main(String[] args) {
Display display = new Display();
new SWTApp(display);
display.dispose();
}
}
In this example, we create a donut. The shapes resembles a cookie, hence the name donut.
Transform tr = new Transform(e.display);
tr.translate(w / 2, h / 2);
e.gc.setTransform(tr);
We move the middle of the axis to the center of the window.
for (int rot = 0; rot < 36; rot++) {
tr.rotate(5f);
e.gc.drawOval(-125, -40, 250, 80);
e.gc.setTransform(tr);
}
We do several rotations and draw the ellipses.
Donut
Figure: Donut

Drawing text

In the next example, we draw some text on the window.
package com.zetcode;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

/**
* ZetCode Java SWT tutorial
*
* This program draws text
* on the window
*
* @author jan bodnar
* website zetcode.com
* last modified June 2009
*/

public class SWTApp {

Shell shell;

public SWTApp(Display display) {

shell = new Shell(display);

shell.addPaintListener(new LyricsExamplePaintListener());

shell.setText("Soulmate");
shell.setSize(380, 300);
shell.setLocation(300, 300);
shell.open();

while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}

private class LyricsExamplePaintListener implements PaintListener {

public void paintControl(PaintEvent e) {

drawLyrics(e);
e.gc.dispose();
}
}

private void drawLyrics(PaintEvent e) {
e.gc.setAntialias(SWT.ON);

Font font = new Font(e.display, "Purisa", 10, SWT.NORMAL);
Color color = new Color(e.display, 25, 25, 25);

e.gc.setForeground(color);
e.gc.setFont(font);

e.gc.drawText("Most relationships seem so transitory", 20, 30);
e.gc.drawText("They're good but not the permanent one", 20, 60);
e.gc.drawText("Who doesn't long for someone to hold", 20, 120);
e.gc.drawText("Who knows how to love without being told", 20, 150);
e.gc.drawText("Somebody tell me why I'm on my own", 20, 180);
e.gc.drawText("If there's a soulmate for everyone", 20, 210);


font.dispose();
}

public static void main(String[] args) {
Display display = new Display();
new SWTApp(display);
display.dispose();
}
}
We display part of the lyrics from the Natasha Bedingfields Soulmate song.
Font font = new Font(e.display, "Purisa", 10, SWT.NORMAL);
Here we specify the font, that we use. Purisa, 10px, normal.
e.gc.drawText("Most relationships seem so transitory", 20, 30);
The drawText() method draws text onto the window.
Soulmate
Figure: Soulmate
In this chapter of the Java SWT tutorial, we did some painting.

No comments:

Post a Comment