|
|
Строка 1: |
Строка 1: |
- | In this part of the Java programming tutorial, we will do some drawing with the Cairo library.
| |
| | | |
- | <b>Cairo</b> is a library for creating 2D vector graphics.
| |
- | We can use it to draw our own widgets, charts or various effects or animations.
| |
- |
| |
- | == Simple drawing ==
| |
- |
| |
- | The stroke operation draws the outlines of shapes and the fill operation fills the insides of shapes. Next we will demonstrate these two operations.
| |
- |
| |
- | <source lang="java">
| |
- | package com.zetcode;
| |
- |
| |
- | import org.freedesktop.cairo.Context;
| |
- |
| |
- | import org.gnome.gdk.Event;
| |
- | import org.gnome.gdk.EventExpose;
| |
- | import org.gnome.gtk.Allocation;
| |
- | import org.gnome.gtk.DrawingArea;
| |
- | import org.gnome.gtk.Gtk;
| |
- | import org.gnome.gtk.Widget;
| |
- | import org.gnome.gtk.Window;
| |
- | import org.gnome.gtk.WindowPosition;
| |
- |
| |
- | /**
| |
- | * Java Gnome tutorial
| |
- | *
| |
- | * This program draws a simple
| |
- | * drawing with the Cairo library.
| |
- | *
| |
- | * @author jan bodnar
| |
- | * website zetcode.com
| |
- | * last modified March 2009
| |
- | */
| |
- |
| |
- | public class GSimpleDrawing extends Window implements Widget.ExposeEvent {
| |
- |
| |
- | public GSimpleDrawing() {
| |
- |
| |
- | setTitle("Simple drawing");
| |
- |
| |
- | initUI();
| |
- |
| |
- | connect(new Window.DeleteEvent() {
| |
- | public boolean onDeleteEvent(Widget source, Event event) {
| |
- | Gtk.mainQuit();
| |
- | return false;
| |
- | }
| |
- | });
| |
- |
| |
- | setDefaultSize(250, 200);
| |
- | setPosition(WindowPosition.CENTER);
| |
- | showAll();
| |
- | }
| |
- |
| |
- | public void initUI() {
| |
- | DrawingArea darea = new DrawingArea();
| |
- | darea.connect(this);
| |
- | add(darea);
| |
- | }
| |
- |
| |
- | public boolean onExposeEvent(Widget widget, EventExpose eventExpose) {
| |
- | final Context cr;
| |
- |
| |
- | cr = new Context(widget.getWindow());
| |
- | drawShape(cr);
| |
- |
| |
- | return false;
| |
- | }
| |
- |
| |
- | public void drawShape(Context cr) {
| |
- |
| |
- | cr.setLineWidth(9);
| |
- | cr.setSource(0.7, 0.2, 0.0);
| |
- |
| |
- | int width, height;
| |
- | width = getAllocation().getWidth();
| |
- | height = getAllocation().getHeight();
| |
- |
| |
- | cr.translate(width/2, height/2);
| |
- | cr.arc(0, 0, (width < height ? width : height) / 2 - 10, 0, 2*Math.PI);
| |
- | cr.strokePreserve();
| |
- |
| |
- | cr.setSource(0.3, 0.4, 0.6);
| |
- | cr.fill();
| |
- | }
| |
- |
| |
- | public static void main(String[] args) {
| |
- | Gtk.init(args);
| |
- | new GSimpleDrawing();
| |
- | Gtk.main();
| |
- | }
| |
- | }
| |
- | </source>
| |
- |
| |
- | In our example, we will draw a circle and fill it with a solid color.
| |
- |
| |
- | <source lang="java">
| |
- | DrawingArea darea = new DrawingArea();
| |
- | </source>
| |
- |
| |
- | We will be doing our drawing operations on the <b>DrawingArea</b> widget.
| |
- |
| |
- | <source lang="java">
| |
- | public boolean onExposeEvent(Widget widget, EventExpose eventExpose) {
| |
- | final Context cr;
| |
- |
| |
- | cr = new Context(widget.getWindow());
| |
- | drawShape(cr);
| |
- |
| |
- | return false;
| |
- | }
| |
- | </source>
| |
- |
| |
- | When the window needs to be redrawn, the <b>ExposeEvent</b> is created.
| |
- | The actual drawing is delegated to the <b>drawShape()</b> method.
| |
- |
| |
- | <source lang="java">
| |
- | cr = new Context(widget.getWindow());
| |
- | </source>
| |
- |
| |
- | We create the <b>Context</b> object from the gdk window of the drawing area. The context is an object onto which we do all our drawings.
| |
- |
| |
- | <source lang="java">
| |
- | cr.setLineWidth(9);
| |
- | </source>
| |
- |
| |
- | We set the width of the line to 9 pixels.
| |
- |
| |
- | <source lang="java">
| |
- | cr.setSource(0.7, 0.2, 0.0);
| |
- |
| |
- | </source>
| |
- |
| |
- | We set the color to dark red.
| |
- |
| |
- | <source lang="java">
| |
- | int width, height;
| |
- | width = getAllocation().getWidth();
| |
- | height = getAllocation().getHeight();
| |
- |
| |
- | cr.translate(width/2, height/2);
| |
- | </source>
| |
- |
| |
- | We get the width and height of the drawing area.
| |
- | We move the origin into the middle of the window.
| |
- |
| |
- | <source lang="java">
| |
- | cr.arc(0, 0, (width < height ? width : height) / 2 - 10, 0, 2*Math.PI);
| |
- | cr.strokePreserve();
| |
- |
| |
- | </source>
| |
- |
| |
- | We draw the outside shape of a circle. The <b>strokePreserve()</b> strokes the current path according to the current line width, line join, line cap, and dash settings. Unlike the <b>stroke()</b>, it preserves the path within the cairo context.
| |
- |
| |
- | <source lang="java">
| |
- | cr.setSource(0.3, 0.4, 0.6);
| |
- | cr.fill();
| |
- | </source>
| |
- |
| |
- | This fills the interior of the circle with some blue color.
| |
- |
| |
- | [[image: Java_Gnome_faq_simpledrawing.png| center]]
| |
- |
| |
- | == Basic shapes ==
| |
- |
| |
- | The next example draws some basic shapes onto the window.
| |
- |
| |
- | <source lang="java">
| |
- |
| |
- | package com.zetcode;
| |
- |
| |
- | import org.freedesktop.cairo.Context;
| |
- | import org.freedesktop.cairo.Matrix;
| |
- |
| |
- | import org.gnome.gdk.Event;
| |
- | import org.gnome.gdk.EventExpose;
| |
- | import org.gnome.gtk.DrawingArea;
| |
- | import org.gnome.gtk.Gtk;
| |
- | import org.gnome.gtk.Widget;
| |
- | import org.gnome.gtk.Window;
| |
- | import org.gnome.gtk.WindowPosition;
| |
- |
| |
- |
| |
- | /**
| |
- | * ZetCode Java Gnome tutorial
| |
- | *
| |
- | * This program draws basic shapes
| |
- | * with the cairo library.
| |
- | *
| |
- | * @author jan bodnar
| |
- | * website zetcode.com
| |
- | * last modified March 2009
| |
- | */
| |
- |
| |
- | public class GBasicShapes extends Window implements Window.ExposeEvent {
| |
- |
| |
- | public GBasicShapes() {
| |
- |
| |
- | setTitle("Basic Shapes");
| |
- |
| |
- | initUI();
| |
- |
| |
- | connect(new Window.DeleteEvent() {
| |
- | public boolean onDeleteEvent(Widget source, Event event) {
| |
- | Gtk.mainQuit();
| |
- | return false;
| |
- | }
| |
- | });
| |
- |
| |
- | setDefaultSize(390, 240);
| |
- | setPosition(WindowPosition.CENTER);
| |
- | showAll();
| |
- | }
| |
- |
| |
- | public void initUI() {
| |
- | DrawingArea darea = new DrawingArea();
| |
- | darea.connect(this);
| |
- | add(darea);
| |
- | }
| |
- |
| |
- | public boolean onExposeEvent(Widget widget, EventExpose eventExpose) {
| |
- | final Context cr;
| |
- |
| |
- | cr = new Context(widget.getWindow());
| |
- | drawShapes(cr);
| |
- |
| |
- | return false;
| |
- | }
| |
- |
| |
- | public void drawShapes(Context cr) {
| |
- |
| |
- | cr.setSource(0.6, 0.6, 0.6);
| |
- |
| |
- | cr.rectangle(20, 20, 120, 80);
| |
- | cr.rectangle(180, 20, 80, 80);
| |
- | cr.fill();
| |
- |
| |
- | cr.arc(330, 60, 40, 0, 2*Math.PI);
| |
- | cr.fill();
| |
- |
| |
- | cr.arc(90, 160, 40, Math.PI/4, Math.PI);
| |
- | cr.fill();
| |
- |
| |
- | Matrix mat = new Matrix();
| |
- | mat.translate(220, 180);
| |
- | mat.scale(1, 0.7);
| |
- | cr.transform(mat);
| |
- |
| |
- | cr.arc(0, 0, 50, 0, 2*Math.PI);
| |
- | cr.fill();
| |
- | }
| |
- |
| |
- | public static void main(String[] args) {
| |
- | Gtk.init(args);
| |
- | new GBasicShapes();
| |
- | Gtk.main();
| |
- | }
| |
- | }
| |
- | </source>
| |
- |
| |
- | In this example, we will create a rectangle, a square, a circle, an arc and an ellipse.
| |
- |
| |
- | <source lang="java">
| |
- | cr.rectangle(20, 20, 120, 80);
| |
- | cr.rectangle(180, 20, 80, 80);
| |
- | cr.fill();
| |
- | </source>
| |
- |
| |
- | These lines draw a rectangle and a square.
| |
- |
| |
- | <source lang="java">
| |
- | cr.arc(330, 60, 40, 0, 2*Math.PI);
| |
- | cr.fill();
| |
- | </source>
| |
- |
| |
- | Here the <b>arc()</b> method draws a full circle.
| |
- |
| |
- | <source lang="java">
| |
- | Matrix mat = new Matrix();
| |
- | mat.translate(220, 180);
| |
- | mat.scale(1, 0.7);
| |
- | cr.transform(mat);
| |
- |
| |
- | cr.arc(0, 0, 50, 0, 2*Math.PI);
| |
- | cr.fill();
| |
- |
| |
- | </source>
| |
- |
| |
- | If we want to draw an oval, we do some scaling first.
| |
- | The <b>scale()</b> method shrinks the y axis.
| |
- |
| |
- | [[image: Java_Gnome_faq_basicshapes.png| center]]
| |
- |
| |
- | == Colors ==
| |
- |
| |
- | A color is an object representing a combination of Red, Green, and Blue (RGB) intensity values.
| |
- | Cairo valid RGB values are in the range 0 to 1.
| |
- |
| |
- | <source lang="java">
| |
- |
| |
- | package com.zetcode;
| |
- |
| |
- | import org.freedesktop.cairo.Context;
| |
- |
| |
- | import org.gnome.gdk.Event;
| |
- | import org.gnome.gdk.EventExpose;
| |
- | import org.gnome.gtk.DrawingArea;
| |
- | import org.gnome.gtk.Gtk;
| |
- | import org.gnome.gtk.Widget;
| |
- | import org.gnome.gtk.Window;
| |
- | import org.gnome.gtk.WindowPosition;
| |
- |
| |
- | /**
| |
- | * ZetCode Java Gnome tutorial
| |
- | *
| |
- | * This program draws nine rectangles
| |
- | * on the drawing area. Each of them
| |
- | * has different color.
| |
- | *
| |
- | * @author jan bodnar
| |
- | * website zetcode.com
| |
- | * last modified March 2009
| |
- | */
| |
- |
| |
- | public class GColors extends Window
| |
- | implements Widget.ExposeEvent {
| |
- |
| |
- | public GColors() {
| |
- |
| |
- | setTitle("Colors");
| |
- |
| |
- | connect(new Window.DeleteEvent() {
| |
- | public boolean onDeleteEvent(Widget source, Event event) {
| |
- | Gtk.mainQuit();
| |
- | return false;
| |
- | }
| |
- | });
| |
- |
| |
- | initUI();
| |
- |
| |
- | setDefaultSize(350, 280);
| |
- | setPosition(WindowPosition.CENTER);
| |
- | showAll();
| |
- | }
| |
- |
| |
- | public void initUI() {
| |
- | DrawingArea darea = new DrawingArea();
| |
- | darea.connect(this);
| |
- | add(darea);
| |
- | }
| |
- |
| |
- | public boolean onExposeEvent(Widget widget, EventExpose eventExpose) {
| |
- | final Context cr;
| |
- |
| |
- | cr = new Context(widget.getWindow());
| |
- | drawRectangles(cr);
| |
- |
| |
- | return false;
| |
- | }
| |
- |
| |
- |
| |
- | public void drawRectangles(Context cr) {
| |
- | cr.setSource(0.5, 0.65, 0.45);
| |
- | cr.rectangle(10, 15, 90, 60);
| |
- | cr.fill();
| |
- |
| |
- | cr.setSource(0.16, 0.7, 0.9);
| |
- | cr.rectangle(130, 15, 90, 60);
| |
- | cr.fill();
| |
- |
| |
- | cr.setSource(0.274, 0.262, 0.48);
| |
- | cr.rectangle(250, 15, 90, 60);
| |
- | cr.fill();
| |
- |
| |
- | cr.setSource(0.5, 0.39, 0.33);
| |
- | cr.rectangle(10, 105, 90, 60);
| |
- | cr.fill();
| |
- |
| |
- | cr.setSource(0.99, 0.83, 0.24);
| |
- | cr.rectangle(130, 105, 90, 60);
| |
- | cr.fill();
| |
- |
| |
- | cr.setSource(0.95, 0.38, 0.27);
| |
- | cr.rectangle(250, 105, 90, 60);
| |
- | cr.fill();
| |
- |
| |
- | cr.setSource(0.85, 0.57, 0.21);
| |
- | cr.rectangle(10, 195, 90, 60);
| |
- | cr.fill();
| |
- |
| |
- | cr.setSource(0.25, 0.04, 0.73);
| |
- | cr.rectangle(130, 195, 90, 60);
| |
- | cr.fill();
| |
- |
| |
- | cr.setSource(0.12, 0.08, 0.03);
| |
- | cr.rectangle(250, 195, 90, 60);
| |
- | cr.fill();
| |
- | }
| |
- |
| |
- | public static void main(String[] args) {
| |
- | Gtk.init(args);
| |
- | new GColors();
| |
- | Gtk.main();
| |
- | }
| |
- | }
| |
- | </source>
| |
- |
| |
- | We draw nine rectangles in nine different colors.
| |
- |
| |
- | <source lang="java">
| |
- | cr.setSource(0.5, 0.65, 0.45);
| |
- |
| |
- | </source>
| |
- |
| |
- | The <b>setSource()</b> method sets a color for the cairo context. The three parameters of the method are the color intensity values.
| |
- |
| |
- | <source lang="java">
| |
- | cr.rectangle(10, 15, 90, 60);
| |
- | cr.fill();
| |
- | </source>
| |
- |
| |
- | We create a rectangle shape and fill it with the previously specified color.
| |
- |
| |
- | [[image: Java_Gnome_faq_colors.png| center]]
| |
- |
| |
- | == 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)
| |
- |
| |
- | <source lang="java">
| |
- | package com.zetcode;
| |
- |
| |
- | import org.freedesktop.cairo.Context;
| |
- |
| |
- | import org.gnome.gdk.Event;
| |
- | import org.gnome.gdk.EventExpose;
| |
- | import org.gnome.gtk.DrawingArea;
| |
- | import org.gnome.gtk.Gtk;
| |
- | import org.gnome.gtk.Widget;
| |
- | import org.gnome.gtk.Window;
| |
- | import org.gnome.gtk.WindowPosition;
| |
- |
| |
- | /**
| |
- | * ZetCode Java Gnome tutorial
| |
- | *
| |
- | * This program draws ten rectangles
| |
- | * with different levels of transparency.
| |
- | *
| |
- | * @author jan bodnar
| |
- | * website zetcode.com
| |
- | * last modified March 2009
| |
- | */
| |
- |
| |
- | public class GTransparentRectangles extends Window
| |
- | implements Widget.ExposeEvent {
| |
- |
| |
- | public GTransparentRectangles() {
| |
- | setTitle("Transparent Rectangles");
| |
- |
| |
- | connect(new Window.DeleteEvent() {
| |
- | public boolean onDeleteEvent(Widget source, Event event) {
| |
- | Gtk.mainQuit();
| |
- | return false;
| |
- | }
| |
- | });
| |
- |
| |
- | initUI();
| |
- |
| |
- | setSizeRequest(590, 90);
| |
- | setPosition(WindowPosition.CENTER);
| |
- | showAll();
| |
- | }
| |
- |
| |
- |
| |
- | public void initUI() {
| |
- | DrawingArea darea = new DrawingArea();
| |
- | add(darea);
| |
- | darea.connect(this);
| |
- | }
| |
- |
| |
- |
| |
- | public void doDrawing(Context cr) {
| |
- |
| |
- | for (int i = 1; i<=10; i++) {
| |
- | cr.setSource(0, 0, 1, 0.1*i);
| |
- | cr.rectangle(50*i, 20, 40, 40);
| |
- | cr.fill();
| |
- | }
| |
- | }
| |
- |
| |
- | public boolean onExposeEvent(Widget widget, EventExpose eventExpose) {
| |
- |
| |
- | Context cr = new Context(widget.getWindow());
| |
- | doDrawing(cr);
| |
- |
| |
- | return false;
| |
- | }
| |
- |
| |
- | public static void main(String[] args) {
| |
- | Gtk.init(args);
| |
- | new GTransparentRectangles();
| |
- | Gtk.main();
| |
- | }
| |
- | }
| |
- | </source>
| |
- |
| |
- | In the example we will draw ten rectangles with different levels of transparency.
| |
- |
| |
- | <source lang="java">
| |
- | cr.setSource(0, 0, 1, 0.1*i);
| |
- | </source>
| |
- |
| |
- | The last parameter of the <b>setSource()</b> method is the alpha transparency.
| |
- |
| |
- | [[image: Java_Gnome_faq_transparency.png| center]]
| |
- |
| |
- | == Donut ==
| |
- |
| |
- | In the following example we create an complex shape by rotating a bunch of ellipses.
| |
- |
| |
- | <source lang="java">
| |
- | package com.zetcode;
| |
- |
| |
- | import org.freedesktop.cairo.Context;
| |
- | import org.freedesktop.cairo.Matrix;
| |
- |
| |
- | import org.gnome.gdk.Event;
| |
- | import org.gnome.gdk.EventExpose;
| |
- | import org.gnome.gtk.DrawingArea;
| |
- | import org.gnome.gtk.Gtk;
| |
- | import org.gnome.gtk.Widget;
| |
- | import org.gnome.gtk.Window;
| |
- | import org.gnome.gtk.WindowPosition;
| |
- |
| |
- |
| |
- | /**
| |
- | * ZetCode Java Gnome tutorial
| |
- | *
| |
- | * This program draws a Donut
| |
- | * shape on the drawing area.
| |
- | *
| |
- | * @author jan bodnar
| |
- | * website zetcode.com
| |
- | * last modified March 2009
| |
- | */
| |
- |
| |
- | public class GDonut extends Window
| |
- | implements Widget.ExposeEvent {
| |
- |
| |
- |
| |
- | public GDonut() {
| |
- |
| |
- | setTitle("Donut");
| |
- |
| |
- | initUI();
| |
- |
| |
- | connect(new Window.DeleteEvent() {
| |
- | public boolean onDeleteEvent(Widget source, Event event) {
| |
- | Gtk.mainQuit();
| |
- | return false;
| |
- | }
| |
- | });
| |
- |
| |
- | setDefaultSize(300, 260);
| |
- | setPosition(WindowPosition.CENTER);
| |
- | showAll();
| |
- | }
| |
- |
| |
- |
| |
- | public void initUI() {
| |
- | DrawingArea darea = new DrawingArea();
| |
- | darea.connect(this);
| |
- | add(darea);
| |
- | }
| |
- |
| |
- | public boolean onExposeEvent(Widget widget, EventExpose eventExpose) {
| |
- | final Context cr;
| |
- |
| |
- | cr = new Context(widget.getWindow());
| |
- | drawDonut(cr);
| |
- |
| |
- | return false;
| |
- | }
| |
- |
| |
- | public void drawDonut(Context cr) {
| |
- | int width = this.getWindow().getWidth();
| |
- | int height = this.getWindow().getHeight();
| |
- |
| |
- | cr.setLineWidth(0.5);
| |
- | cr.translate(width/2, height/2);
| |
- | cr.arc( 0, 0, 120, 0, 2 * Math.PI);
| |
- | cr.stroke();
| |
- | cr.save();
| |
- |
| |
- | for ( int i = 0; i < 36; i++) {
| |
- | Matrix mat = new Matrix();
| |
- | mat.rotate(i*Math.PI/36);
| |
- | mat.scale(0.3, 1);
| |
- | cr.transform(mat);
| |
- | cr.arc(0, 0, 120, 0, 2 * Math.PI);
| |
- | cr.restore();
| |
- | cr.stroke();
| |
- | cr.save();
| |
- | }
| |
- | }
| |
- |
| |
- |
| |
- | public static void main(String[] args) {
| |
- | Gtk.init(args);
| |
- | new GDonut();
| |
- | Gtk.main();
| |
- | }
| |
- | }
| |
- | </source>
| |
- |
| |
- | In this example, we create a donut. The shape resembles a cookie, hence the name donut.
| |
- |
| |
- | <source lang="java">
| |
- | cr.translate(width/2, height/2);
| |
- | cr.arc( 0, 0, 120, 0, 2 * Math.PI);
| |
- | cr.stroke();
| |
- | </source>
| |
- |
| |
- | In the beginning there is an ellipse.
| |
- |
| |
- | <source lang="java">
| |
- | Matrix mat = new Matrix();
| |
- | mat.rotate(i*Math.PI/36);
| |
- | mat.scale(0.3, 1);
| |
- | cr.transform(mat);
| |
- | cr.arc(0, 0, 120, 0, 2 * Math.PI);
| |
- | cr.restore();
| |
- | cr.stroke();
| |
- | cr.save();
| |
- | </source>
| |
- |
| |
- | After several rotations, there is a donut.
| |
- |
| |
- | [[image: Java_Gnome_faq_donut.jpg| center]]
| |
- |
| |
- | == Gradients ==
| |
- |
| |
- | In computer graphics, gradient is a smooth blending of shades from light to dark or from one color to another.
| |
- | In 2D drawing programs and paint programs, gradients are used to create colorful backgrounds and special effects as well as to simulate lights and shadows. (answers.com)
| |
- |
| |
- | <source lang="java">
| |
- | package com.zetcode;
| |
- |
| |
- | import org.freedesktop.cairo.Context;
| |
- |
| |
- | import org.freedesktop.cairo.LinearPattern;
| |
- |
| |
- | import org.gnome.gdk.Color;
| |
- | import org.gnome.gdk.EventExpose;
| |
- | import org.gnome.gtk.DrawingArea;
| |
- | import org.gnome.gtk.Gtk;
| |
- | import org.gnome.gtk.Widget;
| |
- | import org.gnome.gtk.Window;
| |
- | import org.gnome.gtk.WindowPosition;
| |
- |
| |
- | /**
| |
- | * ZetCode Java Gnome tutorial
| |
- | *
| |
- | * This program draws gradients.
| |
- | *
| |
- | * @author jan bodnar
| |
- | * website zetcode.com
| |
- | * last modified March 2009
| |
- | */
| |
- |
| |
- |
| |
- | public class GGradients extends Window implements Widget.ExposeEvent {
| |
- |
| |
- | public GGradients() {
| |
- |
| |
- | setTitle("Gradients");
| |
- |
| |
- | initUI();
| |
- |
| |
- | connect(new Window.DeleteEvent() {
| |
- | public boolean onDeleteEvent(Widget source, Event event) {
| |
- | Gtk.mainQuit();
| |
- | return false;
| |
- | }
| |
- | });
| |
- |
| |
- | setDefaultSize(340, 390);
| |
- | setPosition(WindowPosition.CENTER);
| |
- | showAll();
| |
- | }
| |
- |
| |
- | public void initUI() {
| |
- | DrawingArea darea = new DrawingArea();
| |
- | darea.connect(this);
| |
- | add(darea);
| |
- | }
| |
- |
| |
- | public boolean onExposeEvent(Widget widget, EventExpose eventExpose) {
| |
- | final Context cr;
| |
- |
| |
- | cr = new Context(widget.getWindow());
| |
- | drawGradients(cr);
| |
- |
| |
- | return false;
| |
- | }
| |
- |
| |
- | public void drawGradients(Context cr) {
| |
- |
| |
- | LinearPattern lg1 = new LinearPattern(0.0, 0.0, 350.0, 350.0);
| |
- |
| |
- | int count = 1;
| |
- |
| |
- | for (double j=0.1; j<1.0; j+= 0.1) {
| |
- | if (count % 2 != 0) {
| |
- | lg1.addColorStopRGB(j, 0, 0, 0);
| |
- | } else {
| |
- | lg1.addColorStopRGB(j, 1, 0, 0);
| |
- | }
| |
- | count++;
| |
- | }
| |
- |
| |
- | cr.rectangle(20, 20, 300, 100);
| |
- | cr.setSource(lg1);
| |
- | cr.fill();
| |
- |
| |
- | LinearPattern lg2 = new LinearPattern(0.0, 0.0, 350.0, 0);
| |
- |
| |
- | count = 1;
| |
- |
| |
- | for (double i=0.05; i<0.95; i+= 0.025) {
| |
- | if (count % 2 != 0) {
| |
- | lg2.addColorStopRGB(i, 0, 0, 0);
| |
- | } else {
| |
- | lg2.addColorStopRGB(i, 0, 0, 1);
| |
- | }
| |
- | count++;
| |
- | }
| |
- |
| |
- | cr.rectangle(20, 140, 300, 100);
| |
- | cr.setSource(lg2);
| |
- | cr.fill();
| |
- |
| |
- | LinearPattern lg3 = new LinearPattern(20.0, 260.0, 20.0, 360.0);
| |
- |
| |
- | lg3.addColorStopRGB(0.1, 0, 0, 0 );
| |
- | lg3.addColorStopRGB(0.5, 1, 1, 0);
| |
- | lg3.addColorStopRGB(0.9, 0, 0, 0 );
| |
- |
| |
- | cr.rectangle(20, 260, 300, 100);
| |
- | cr.setSource(lg3);
| |
- | cr.fill();
| |
- | }
| |
- |
| |
- | public static void main(String[] args) {
| |
- | Gtk.init(args);
| |
- | new GGradients();
| |
- | Gtk.main();
| |
- | }
| |
- | }
| |
- |
| |
- | </source>
| |
- |
| |
- | In our example, we draw three rectangles with three different gradients.
| |
- |
| |
- | <source lang="java">
| |
- | LinearPattern lg1 = new LinearPattern(0.0, 0.0, 350.0, 350.0);
| |
- | </source>
| |
- |
| |
- | Here we create a linear gradient pattern. The parameters specify the line, along which we draw the gradient. In our case it is a diagonal line.
| |
- |
| |
- | <source lang="java">
| |
- | LinearPattern lg3 = new LinearPattern(20.0, 260.0, 20.0, 360.0);
| |
- | lg3.addColorStopRGB(0.1, 0, 0, 0 );
| |
- | lg3.addColorStopRGB(0.5, 1, 1, 0);
| |
- | lg3.addColorStopRGB(0.9, 0, 0, 0 );
| |
- |
| |
- | </source>
| |
- |
| |
- | We define color stops to produce our gradient pattern. In this case, the gradient is a blending of black and yellow colors. By adding two black and one yellow stops, we create a horizontal gradient pattern. What do these stops actually mean?
| |
- | In our case, we begin with black color, which will stop at 1/10 of the size.
| |
- | Then we begin to gradually paint in yellow, which will culminate at the centre of the shape.
| |
- | The yellow color stops at 9/10 of the size, where we begin painting in black again, until the end.
| |
- |
| |
- | [[image: Java_Gnome_faq_gradients.png| center]]
| |
- |
| |
- | == Star ==
| |
- |
| |
- | In the following example, we create a moving star. The star moves, rotates and grows/shrinks.
| |
- |
| |
- | <source lang="java">
| |
- | package com.zetcode;
| |
- |
| |
- | import java.util.Timer;
| |
- | import java.util.TimerTask;
| |
- |
| |
- | import org.freedesktop.cairo.Context;
| |
- | import org.freedesktop.cairo.Matrix;
| |
- |
| |
- | import org.gnome.gdk.Event;
| |
- | import org.gnome.gdk.EventExpose;
| |
- | import org.gnome.gtk.DrawingArea;
| |
- | import org.gnome.gtk.Gtk;
| |
- | import org.gnome.gtk.Widget;
| |
- | import org.gnome.gtk.Window;
| |
- | import org.gnome.gtk.WindowPosition;
| |
- |
| |
- | /**
| |
- | * ZetCode Java Gnome tutorial
| |
- | *
| |
- | * This program shows an animated star. Rotate,
| |
- | * translate and scale operations are
| |
- | * applied on the star.
| |
- | *
| |
- | * @author jan bodnar
| |
- | * website zetcode.com
| |
- | * last modified March 2009
| |
- | */
| |
- |
| |
- | public class GStar extends Window
| |
- | implements Widget.ExposeEvent {
| |
- |
| |
- | private static Timer timer;
| |
- | private int count;
| |
- |
| |
- | private double angle = 0;
| |
- | private double scale = 1;
| |
- | private double delta = 0.01;
| |
- |
| |
- | double points[][] = {
| |
- | { 0, 85 }, { 75, 75 }, { 100, 10 }, { 125, 75 },
| |
- | { 200, 85 }, { 150, 125 }, { 160, 190 }, { 100, 150 },
| |
- | { 40, 190 }, { 50, 125 }, { 0, 85 }
| |
- | };
| |
- |
| |
- | public GStar() {
| |
- |
| |
- | setTitle("Star");
| |
- |
| |
- | timer = new Timer();
| |
- | timer.scheduleAtFixedRate(new ScheduleTask(), 100, 20);
| |
- | count = 0;
| |
- |
| |
- | initUI();
| |
- |
| |
- | connect(new Window.DeleteEvent() {
| |
- | public boolean onDeleteEvent(Widget source, Event event) {
| |
- | timer.cancel();
| |
- | Gtk.mainQuit();
| |
- | return false;
| |
- | }
| |
- | });
| |
- |
| |
- | setSizeRequest(350, 250);
| |
- | setPosition(WindowPosition.CENTER);
| |
- | showAll();
| |
- | }
| |
- |
| |
- | public void initUI() {
| |
- | DrawingArea darea = new DrawingArea();
| |
- | darea.connect(this);
| |
- | add(darea);
| |
- | }
| |
- |
| |
- | public void drawStar(Context cr) {
| |
- |
| |
- | int width = this.getWindow().getWidth();
| |
- | int height = this.getWindow().getHeight();
| |
- |
| |
- | cr.setSource(0, 0.44, 0.7);
| |
- | cr.setLineWidth(1);
| |
- |
| |
- | Matrix mat = new Matrix();
| |
- |
| |
- | mat.translate(width/2, height/2);
| |
- | mat.rotate(angle);
| |
- | mat.scale(scale, scale);
| |
- | cr.transform(mat);
| |
- |
| |
- | for ( int i = 0; i < 10; i++ ) {
| |
- | cr.lineTo(points[i][0], points[i][1]);
| |
- | }
| |
- |
| |
- | cr.fill();
| |
- | cr.stroke();
| |
- |
| |
- | if ( scale < 0.01 ) {
| |
- | delta = -delta;
| |
- | } else if (scale > 0.99) {
| |
- | delta = -delta;
| |
- | }
| |
- |
| |
- | scale += delta;
| |
- | angle += 0.01;
| |
- | }
| |
- |
| |
- | public boolean onExposeEvent(Widget widget, EventExpose eventExpose) {
| |
- |
| |
- | Context cr = new Context(widget.getWindow());
| |
- | drawStar(cr);
| |
- |
| |
- | return false;
| |
- | }
| |
- |
| |
- | class ScheduleTask extends TimerTask {
| |
- |
| |
- | public void run() {
| |
- | count++;
| |
- | queueDraw();
| |
- | }
| |
- | }
| |
- |
| |
- | public static void main(String[] args) {
| |
- | Gtk.init(args);
| |
- | new GStar();
| |
- | Gtk.main();
| |
- | }
| |
- | }
| |
- | </source>
| |
- |
| |
- | We apply translate, scale and rotate operations on a star shape.
| |
- |
| |
- | <source lang="java">
| |
- | public boolean onDeleteEvent(Widget source, Event event) {
| |
- | timer.cancel();
| |
- | Gtk.mainQuit();
| |
- | return false;
| |
- | }
| |
- |
| |
- | </source>
| |
- |
| |
- | For a clean exit, we must not forget to stop the timer. Timer is and object of the java util library and is not stopped by the <b> Gtk.mainQuit()</b> method.
| |
- |
| |
- | <source lang="java">
| |
- | double points[][] = {
| |
- | { 0, 85 }, { 75, 75 }, { 100, 10 }, { 125, 75 },
| |
- | { 200, 85 }, { 150, 125 }, { 160, 190 }, { 100, 150 },
| |
- | { 40, 190 }, { 50, 125 }, { 0, 85 }
| |
- | };
| |
- | </source>
| |
- |
| |
- | These points are used to build the star shape.
| |
- |
| |
- | <source lang="java">
| |
- | Matrix mat = new Matrix();
| |
- |
| |
- | mat.translate(width/2, height/2);
| |
- | mat.rotate(angle);
| |
- | mat.scale(scale, scale);
| |
- | cr.transform(mat);
| |
- | </source>
| |
- |
| |
- | Here we apply the translate, rotate and scale operations on the star shape.
| |
- |
| |
- | <source lang="java">
| |
- | for ( int i = 0; i < 10; i++ ) {
| |
- | cr.lineTo(points[i][0], points[i][1]);
| |
- | }
| |
- | </source>
| |
- |
| |
- | Here we draw the star.
| |
- |
| |
- | == Waiting ==
| |
- |
| |
- | In this examle, we use transparency effect to create a waiting demo.
| |
- | We will draw 8 lines that will gradually fade out creating an illusion, that a line is moving. Such effects are often used to inform users, that a lengthy task is going on behind the scenes.
| |
- | An example is streaming video over the internet.
| |
- |
| |
- | <source lang="java">
| |
- | package com.zetcode;
| |
- |
| |
- |
| |
- | import java.util.Timer;
| |
- | import java.util.TimerTask;
| |
- |
| |
- | import org.freedesktop.cairo.Context;
| |
- |
| |
- | import org.gnome.gdk.Event;
| |
- | import org.gnome.gdk.EventExpose;
| |
- | import org.gnome.gtk.DrawingArea;
| |
- | import org.gnome.gtk.Gtk;
| |
- | import org.gnome.gtk.Widget;
| |
- | import org.gnome.gtk.Window;
| |
- | import org.gnome.gtk.WindowPosition;
| |
- |
| |
- | /**
| |
- | * ZetCode Java Gnome tutorial
| |
- | *
| |
- | * This program creates a waiting
| |
- | * effect.
| |
- | *
| |
- | * @author jan bodnar
| |
- | * website zetcode.com
| |
- | * last modified March 2009
| |
- | */
| |
- |
| |
- | public class GWaiting extends Window
| |
- | implements Widget.ExposeEvent {
| |
- |
| |
- | private static Timer timer;
| |
- | private int count;
| |
- |
| |
- | private final double[][] trs = {
| |
- | { 0.0, 0.15, 0.30, 0.5, 0.65, 0.80, 0.9, 1.0 },
| |
- | { 1.0, 0.0, 0.15, 0.30, 0.5, 0.65, 0.8, 0.9 },
| |
- | { 0.9, 1.0, 0.0, 0.15, 0.3, 0.5, 0.65, 0.8 },
| |
- | { 0.8, 0.9, 1.0, 0.0, 0.15, 0.3, 0.5, 0.65 },
| |
- | { 0.65, 0.8, 0.9, 1.0, 0.0, 0.15, 0.3, 0.5 },
| |
- | { 0.5, 0.65, 0.8, 0.9, 1.0, 0.0, 0.15, 0.3 },
| |
- | { 0.3, 0.5, 0.65, 0.8, 0.9, 1.0, 0.0, 0.15 },
| |
- | { 0.15, 0.3, 0.5, 0.65, 0.8, 0.9, 1.0, 0.0, }
| |
- | };
| |
- |
| |
- |
| |
- |
| |
- | public GWaiting() {
| |
- | setPosition(WindowPosition.CENTER);
| |
- |
| |
- | timer = new Timer();
| |
- | timer.scheduleAtFixedRate(new ScheduleTask(), 100, 80);
| |
- | count = 0;
| |
- |
| |
- | initUI();
| |
- |
| |
- | connect(new Window.DeleteEvent() {
| |
- | public boolean onDeleteEvent(Widget source, Event event) {
| |
- | timer.cancel();
| |
- | Gtk.mainQuit();
| |
- | return false;
| |
- | }
| |
- | });
| |
- |
| |
- | resize(250, 150);
| |
- | setTitle("Waiting");
| |
- | showAll();
| |
- | }
| |
- |
| |
- | public void initUI() {
| |
- | DrawingArea darea = new DrawingArea();
| |
- | add(darea);
| |
- | darea.connect(this);
| |
- | }
| |
- |
| |
- | public boolean onExposeEvent(Widget widget, EventExpose eventExpose) {
| |
- |
| |
- | Context cr = new Context(widget.getWindow());
| |
- | drawWaiting(cr);
| |
- |
| |
- | return false;
| |
- | }
| |
- |
| |
- | private void drawWaiting(Context cr) {
| |
- | int w = this.getWidth();
| |
- | int h = this.getHeight();
| |
- |
| |
- | cr.translate(w/2, h/2);
| |
- |
| |
- | for (int i = 0; i < 8; i++) {
| |
- |
| |
- | cr.setLineWidth(3);
| |
- | cr.setSource(0, 0, 0, trs[count%8][i]);
| |
- |
| |
- | cr.moveTo(0, -10);
| |
- | cr.lineTo(0, -40);
| |
- | cr.rotate(Math.PI/4f);
| |
- | cr.stroke();
| |
- | }
| |
- | }
| |
- |
| |
- | class ScheduleTask extends TimerTask {
| |
- |
| |
- | public void run() {
| |
- | count++;
| |
- | queueDraw();
| |
- | }
| |
- | }
| |
- |
| |
- | public static void main(String[] args) {
| |
- | Gtk.init(args);
| |
- | new GWaiting();
| |
- | Gtk.main();
| |
- | }
| |
- | }
| |
- |
| |
- | </source>
| |
- |
| |
- | We draw eight lines with eight different alpha values.
| |
- |
| |
- | <source lang="java">
| |
- | private final double[][] trs = {
| |
- | { 0.0, 0.15, 0.30, 0.5, 0.65, 0.80, 0.9, 1.0 },
| |
- | ....
| |
- | };
| |
- | </source>
| |
- |
| |
- | This is a two dimensional array of transparency values used in this demo.
| |
- | There are 8 rows, each for one state. Each of the 8 lines will continuosly use these values.
| |
- |
| |
- | <source lang="java">
| |
- |
| |
- | cr.setLineWidth(3);
| |
- | </source>
| |
- |
| |
- | We make the lines a bit thicker, so that they are better visible.
| |
- |
| |
- | <source lang="java">
| |
- | cr.setSource(0, 0, 0, trs[count%8][i]);
| |
- | </source>
| |
- |
| |
- | Here we define the transparency value for a line.
| |
- |
| |
- | <source lang="java">
| |
- | cr.moveTo(0, -10);
| |
- | cr.lineTo(0, -40);
| |
- | cr.rotate(Math.PI/4f);
| |
- | cr.stroke();
| |
- | </source>
| |
- |
| |
- | These code lines will draw each of the eight lines.
| |
- |
| |
- | [[image: Java_Gnome_faq_waiting.png| center]]
| |
- |
| |
- | [[Категория:GTK+]]
| |
- | [[Категория:Java]]
| |