Редактирование: Java Gnome FAQ Drawing with cairo

Материал из Wiki.crossplatform.ru

Перейти к: навигация, поиск
Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия Ваш текст
Строка 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]]

Пожалуйста, обратите внимание, что все ваши добавления могут быть отредактированы или удалены другими участниками. Если вы не хотите, чтобы кто-либо изменял ваши тексты, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений, или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого (см. Wiki.crossplatform.ru:Авторское право). НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ МАТЕРИАЛЫ!