Difference between revisions of "Tutorial: Drawing Basic Logic Gates with GWT"
(→Canvas3.java) |
(→Gate Geometry) |
||
(11 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
--[[User:Thiebaut|D. Thiebaut]] ([[User talk:Thiebaut|talk]]) 18:21, 4 July 2014 (EDT) | --[[User:Thiebaut|D. Thiebaut]] ([[User talk:Thiebaut|talk]]) 18:21, 4 July 2014 (EDT) | ||
---- | ---- | ||
+ | <br /> | ||
+ | {| style="width:100%;" | ||
+ | | style="width:60%;" | | ||
+ | __TOC__ | ||
+ | | | ||
+ | [[Image:GoogleWebKitLogo.png|100px]] | ||
+ | |} | ||
+ | <br /> | ||
+ | ---- | ||
+ | <center>[[Tutorials#Google_WebKit_.28GWT.29|GWT Tutorials]]</center> | ||
+ | ---- | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <bluebox> | ||
+ | This recipe illustrates how to draw logic gates on a GWT canvas. I found remarkably little information on the Web about the geometry and the generation of logic gates, including the OR gate and its 3 arcs, and decided to just create the 3 basic gates: AND, INVERTER, and OR. The NAND and NOR gates can easily be generated from the information presented here. Look at other [[Tutorials#Google_WebKit_.28GWT.29|GWT Tutorials]] in this Wiki for information about setting up Eclipse and generating simple GWT Web applications. | ||
+ | </bluebox> | ||
+ | <br /> | ||
+ | =Setup= | ||
+ | <br /> | ||
+ | * Mac OSX 10.8.5 with Java SDK 1.7 | ||
+ | * Eclipse Kepler | ||
+ | * Google WebKit gwt-6.2.1. | ||
+ | <br /> | ||
=Sample Output= | =Sample Output= | ||
<br /> | <br /> | ||
Line 10: | Line 33: | ||
</center> | </center> | ||
<br /> | <br /> | ||
+ | |||
=Gate Geometry= | =Gate Geometry= | ||
<br /> | <br /> | ||
− | The geometry for the gates is given by an IEEE document, with this main illustration, shown below, and found in Chapter 9 of this on-line reference on ASICS: [http://iroi.seu.edu.cn/books/asics/ASICs.htm http://iroi.seu.edu.cn/books/asics/ASICs.htm]. | + | The geometry for the gates is given by an IEEE document, with this main illustration, shown below, and found in Chapter 9 of this on-line reference on ASICS: [http://iroi.seu.edu.cn/books/asics/ASICs.htm http://iroi.seu.edu.cn/books/asics/ASICs.htm]. (The OR gate shape is better spotted in the other diagram, located toward the end of this page.) |
<br /> | <br /> | ||
<center> | <center> | ||
Line 35: | Line 59: | ||
import com.google.gwt.canvas.client.Canvas; | import com.google.gwt.canvas.client.Canvas; | ||
import com.google.gwt.canvas.dom.client.Context2d; | import com.google.gwt.canvas.dom.client.Context2d; | ||
− | |||
import com.google.gwt.core.client.EntryPoint; | import com.google.gwt.core.client.EntryPoint; | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
import com.google.gwt.user.client.ui.Label; | import com.google.gwt.user.client.ui.Label; | ||
import com.google.gwt.user.client.ui.RootPanel; | import com.google.gwt.user.client.ui.RootPanel; | ||
Line 191: | Line 201: | ||
Context2d context = null; | Context2d context = null; | ||
int inverterHeight = 20; | int inverterHeight = 20; | ||
− | + | int inverterLength = 20; | |
− | + | int inverterCircleRadius = 5; | |
− | + | int calculatedCenterx = 0; | |
− | + | int calculatedCentery = inverterHeight + inverterCircleRadius; | |
− | + | ||
− | + | public InverterDown(Context2d c, double xx, double yy) { | |
− | public InverterDown( Context2d c, double xx, double yy ) { | ||
context = c; | context = c; | ||
x = xx; | x = xx; | ||
y = yy; | y = yy; | ||
− | + | ||
xin = x; | xin = x; | ||
yin = y; | yin = y; | ||
− | yout = y + inverterLength + inverterCircleRadius*2; | + | yout = y + inverterLength + inverterCircleRadius * 2; |
xout = x; | xout = x; | ||
} | } | ||
− | + | ||
public void draw() { | public void draw() { | ||
− | + | context.moveTo(x, y); | |
− | + | context.lineTo(x - inverterHeight / 2, y); | |
− | + | context.lineTo(x, y + inverterLength); | |
− | + | context.lineTo(x + inverterHeight / 2, y); | |
− | + | context.lineTo(x, y); | |
− | + | context.stroke(); | |
− | + | ||
− | + | context.moveTo(x + calculatedCenterx + inverterCircleRadius, y | |
− | + | + calculatedCentery); | |
− | + | context.arc(x + calculatedCenterx, y + calculatedCentery, | |
− | + | inverterCircleRadius, 0, Math.PI * 2.0, true); | |
− | + | context.stroke(); | |
} | } | ||
− | + | ||
public void drawIO() { | public void drawIO() { | ||
− | context.moveTo( xin, yin); | + | context.moveTo(xin, yin); |
− | context.arc( xin, yin, 2, 0, Math.PI*2 ); | + | context.arc(xin, yin, 2, 0, Math.PI * 2); |
context.stroke(); | context.stroke(); | ||
− | + | ||
− | context.moveTo( xout, yout); | + | context.moveTo(xout, yout); |
− | context.arc( xout, yout, 2, 0, Math.PI*2 ); | + | context.arc(xout, yout, 2, 0, Math.PI * 2); |
context.stroke(); | context.stroke(); | ||
} | } | ||
} | } | ||
+ | |||
+ | |||
+ | |||
</source><br /> | </source><br /> | ||
+ | |||
== InverterRight.java == | == InverterRight.java == | ||
<br /> | <br /> | ||
Line 248: | Line 261: | ||
double y; | double y; | ||
double xin, yin, xout, yout; | double xin, yin, xout, yout; | ||
− | + | ||
Context2d context = null; | Context2d context = null; | ||
int inverterHeight = 20; | int inverterHeight = 20; | ||
− | + | int inverterLength = 20; | |
− | + | int inverterCircleRadius = 5; | |
− | + | int calculatedCenterx = inverterLength + inverterCircleRadius; | |
− | + | int calculatedCentery = 0; | |
− | + | ||
− | + | public InverterRight(Context2d c, double xx, double yy) { | |
− | public InverterRight( Context2d c, double xx, double yy ) { | ||
context = c; | context = c; | ||
x = xx; | x = xx; | ||
Line 263: | Line 275: | ||
xin = x; | xin = x; | ||
yin = y; | yin = y; | ||
− | xout = x + inverterLength + inverterCircleRadius*2; | + | xout = x + inverterLength + inverterCircleRadius * 2; |
yout = y; | yout = y; | ||
} | } | ||
− | + | ||
public void draw() { | public void draw() { | ||
− | + | context.moveTo(x, y); | |
− | + | context.lineTo(x, y - inverterHeight / 2); | |
− | + | context.lineTo(x + inverterLength, y); | |
− | + | context.lineTo(x, y + inverterHeight / 2); | |
− | + | context.lineTo(x, y); | |
− | + | context.stroke(); | |
− | + | context.moveTo(x + calculatedCenterx + inverterCircleRadius, y | |
− | + | + calculatedCentery); | |
− | + | context.arc(x + calculatedCenterx, y + calculatedCentery, | |
− | + | inverterCircleRadius, 0, Math.PI * 2.0, true); | |
− | + | context.stroke(); | |
} | } | ||
− | + | ||
public void drawIO() { | public void drawIO() { | ||
− | context.moveTo( xin, yin); | + | context.moveTo(xin, yin); |
− | context.arc( xin, yin, 2, 0, Math.PI*2 ); | + | context.arc(xin, yin, 2, 0, Math.PI * 2); |
context.stroke(); | context.stroke(); | ||
− | + | ||
− | context.moveTo( xout, yout); | + | context.moveTo(xout, yout); |
− | context.arc( xout, yout, 2, 0, Math.PI*2 ); | + | context.arc(xout, yout, 2, 0, Math.PI * 2); |
context.stroke(); | context.stroke(); | ||
} | } | ||
} | } | ||
+ | |||
</source><br /> | </source><br /> | ||
+ | |||
== OrGate.java == | == OrGate.java == | ||
+ | <br /> | ||
+ | The geometry of the OR gate is better illustrated by labeling key points in the original diagram. These (x,y) points are computed in the java code below. All the angles considered are PI/6 for the gate itself. To locate the two inputs of the gate, we use + and -PI/12 from the x6,y6 center of the left circle. | ||
+ | <br /> | ||
+ | <center>[[Image:ORGateGeometryAndLabels.png]]</center> | ||
<br /> | <br /> | ||
<source lang="java"> | <source lang="java"> | ||
Line 301: | Line 319: | ||
/** | /** | ||
* OrGate | * OrGate | ||
+ | * | ||
* @author thiebaut | * @author thiebaut | ||
− | * | + | * |
− | * Defined by geometry of IEEE pub: http://iroi.seu.edu.cn/books/asics/Book/CH09/CH09-1.gif | + | * Defined by geometry of IEEE pub: |
+ | * http://iroi.seu.edu.cn/books/asics/Book/CH09/CH09-1.gif | ||
*/ | */ | ||
public class OrGate { | public class OrGate { | ||
Line 311: | Line 331: | ||
double x, x1, x2, x3, x4, x5, x6; | double x, x1, x2, x3, x4, x5, x6; | ||
double y, y1, y2, y3, y4, y5, y6; | double y, y1, y2, y3, y4, y5, y6; | ||
− | + | ||
double radius = 26; | double radius = 26; | ||
double height = 26; | double height = 26; | ||
double flat = 10; | double flat = 10; | ||
− | double alpha, beta; | + | double alpha, beta; |
− | + | ||
// inputs and output | // inputs and output | ||
double xin1, yin1, xin2, yin2, xout, yout; | double xin1, yin1, xin2, yin2, xout, yout; | ||
− | + | ||
− | public OrGate( Context2d c, double xx, double yy ) { | + | public OrGate(Context2d c, double xx, double yy) { |
x = xx; | x = xx; | ||
y = yy; | y = yy; | ||
context = c; | context = c; | ||
− | + | ||
// compute various quantities | // compute various quantities | ||
− | alpha = Math.PI/6; | + | alpha = Math.PI / 6; |
− | beta | + | beta = alpha; |
− | y1 = y - radius/2; | + | y1 = y - radius / 2; |
y2 = y1; | y2 = y1; | ||
y3 = y; | y3 = y; | ||
Line 334: | Line 354: | ||
y5 = y4; | y5 = y4; | ||
y6 = y; | y6 = y; | ||
− | + | ||
x6 = x - flat - radius; | x6 = x - flat - radius; | ||
− | x1 = x6 + radius * Math.sqrt( 3 )/2; | + | x1 = x6 + radius * Math.sqrt(3) / 2; |
x5 = x1; | x5 = x1; | ||
x2 = x; | x2 = x; | ||
x4 = x; | x4 = x; | ||
− | x3 = x + radius * Math.sqrt( 3 )/2; | + | x3 = x + radius * Math.sqrt(3) / 2; |
// I/O Pins | // I/O Pins | ||
− | xin1 = x6 + radius * 0.96592582628; //cos( PI/12 ) | + | xin1 = x6 + radius * 0.96592582628; // cos( PI/12 ) |
yin1 = y - radius * 0.2588190451; // sin( PI/12 ) | yin1 = y - radius * 0.2588190451; // sin( PI/12 ) | ||
− | + | ||
xin2 = xin1; | xin2 = xin1; | ||
yin2 = y + radius * 0.2588190451; // sin( PI/12 ) | yin2 = y + radius * 0.2588190451; // sin( PI/12 ) | ||
− | + | ||
xout = x3; | xout = x3; | ||
yout = y3; | yout = y3; | ||
} | } | ||
− | + | ||
− | public double getXInput1() { return xin1; } | + | public double getXInput1() { |
− | public double getYInput1() { return yin1; } | + | return xin1; |
− | public double getXInput2() { return xin2; } | + | } |
− | public double getYInput2() { return yin2; } | + | |
− | public double getXOutput() { return xout; } | + | public double getYInput1() { |
− | public double getYOutput() { return yout; } | + | return yin1; |
− | + | } | |
+ | |||
+ | public double getXInput2() { | ||
+ | return xin2; | ||
+ | } | ||
+ | |||
+ | public double getYInput2() { | ||
+ | return yin2; | ||
+ | } | ||
+ | |||
+ | public double getXOutput() { | ||
+ | return xout; | ||
+ | } | ||
+ | |||
+ | public double getYOutput() { | ||
+ | return yout; | ||
+ | } | ||
+ | |||
public void draw() { | public void draw() { | ||
− | + | ||
− | /* | + | // draw 1-2 |
− | // | + | context.moveTo(x1, y1); |
− | + | context.lineTo(x2, y2); | |
− | context.moveTo( | + | context.stroke(); |
− | context.arc( | + | |
+ | // draw 2-3 | ||
+ | context.moveTo(x2, y2); | ||
+ | context.arc(x4, y4, radius, 3 * Math.PI / 2, Math.PI * 2 - Math.PI / 6); | ||
+ | context.stroke(); | ||
+ | |||
+ | // draw 4-3 | ||
+ | context.moveTo(x3, y3); | ||
+ | context.arc(x2, y2, radius, Math.PI / 6, Math.PI / 2); | ||
context.stroke(); | context.stroke(); | ||
− | + | ||
− | context.moveTo( | + | // Draw 4-5 |
− | context. | + | context.moveTo(x4, y4); |
+ | context.lineTo(x5, y5); | ||
context.stroke(); | context.stroke(); | ||
− | + | ||
− | context.moveTo( | + | // Draw 1-5 |
− | context.arc( | + | context.moveTo(x1, y1); |
+ | context.arc(x6, y6, radius, -Math.PI / 6, Math.PI / 6); | ||
context.stroke(); | context.stroke(); | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
} | } | ||
+ | |||
+ | |||
</source><br /> | </source><br /> | ||
+ | |||
== TextLabel.java == | == TextLabel.java == | ||
<br /> | <br /> | ||
Line 425: | Line 448: | ||
x = xx; | x = xx; | ||
y = yy; | y = yy; | ||
− | |||
} | } | ||
Latest revision as of 08:30, 5 July 2014
--D. Thiebaut (talk) 18:21, 4 July 2014 (EDT)
This recipe illustrates how to draw logic gates on a GWT canvas. I found remarkably little information on the Web about the geometry and the generation of logic gates, including the OR gate and its 3 arcs, and decided to just create the 3 basic gates: AND, INVERTER, and OR. The NAND and NOR gates can easily be generated from the information presented here. Look at other GWT Tutorials in this Wiki for information about setting up Eclipse and generating simple GWT Web applications.
Setup
- Mac OSX 10.8.5 with Java SDK 1.7
- Eclipse Kepler
- Google WebKit gwt-6.2.1.
Sample Output
This is what we're after, below: a way to generate simple AND, OR, and INVERTER gates on a GWT canvas.
Gate Geometry
The geometry for the gates is given by an IEEE document, with this main illustration, shown below, and found in Chapter 9 of this on-line reference on ASICS: http://iroi.seu.edu.cn/books/asics/ASICs.htm. (The OR gate shape is better spotted in the other diagram, located toward the end of this page.)
The Java Project
Canvas3.java
/*
* Canvas3.java
* D. Thiebaut
* A simple canvas application that positions a few gates in a 800x600 canvas.
*/
package dft.client;
import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
/**
* The main class for the project. Implements an empty canvas (Context2D) on which
* a few gates are drawn, along with 3 text labels
*/
public class Canvas3 implements EntryPoint {
Canvas canvas;
Context2d context;
static final int canvasHeight = 800;
static final int canvasWidth = 600;
public void onModuleLoad() {
canvas = Canvas.createIfSupported();
if (canvas == null) {
RootPanel.get().add(new Label("Sorry, your browser doesn't support the HTML5 Canvas element"));
return;
}
// standard code to size the canvas
canvas.setStyleName("mainCanvas");
canvas.setWidth(canvasWidth + "px");
canvas.setCoordinateSpaceWidth(canvasWidth);
canvas.setHeight(canvasHeight + "px");
canvas.setCoordinateSpaceHeight(canvasHeight);
RootPanel.get().add(canvas);
context = canvas.getContext2d();
// drop a few gates on the canvas
for ( int x = 100; x < 300; x += 75 ) {
// some inverters facing right
InverterRight inv = new InverterRight( context, x, 300 );
inv.draw();
// some inverters facing down
InverterDown inv2 = new InverterDown( context, 300, x );
inv2.draw();
// some AND gates (facing right)
AndGate a = new AndGate( context, x+50, 150 );
a.draw();
}
// an OR gate
OrGate or1 = new OrGate( context, 200, 200 );
or1.draw();
// Put some labels
TextLabel L1, L2, L3;
L1 = new TextLabel( context, "75-75", 75, 75);
L1.draw();
L2 = new TextLabel( context, "195-95", 195, 95);
L2.draw();
L3 = new TextLabel( context, "75-195", 75, 195);
//L3.setFont( "bold 22px sans-serif");
L3.draw();
}
}
AndGate.java
package dft.client;
import com.google.gwt.canvas.dom.client.Context2d;
public class AndGate {
Context2d context;
double x;
double y;
double andGateHeight = 30;
double andGateLength = 40;
double xin1, yin1, xin2, yin2, xout, yout;
public AndGate( Context2d c, double xx, double yy ) {
x = xx;
y = yy;
context = c;
xin1 = x;
xin2 = x;
yin1 = y + andGateHeight/4;
yin2 = y + 3*andGateHeight/4;
xout = x + andGateLength/3 + andGateHeight/2;
yout = y + andGateHeight/2;
}
public void draw() {
context.moveTo( x, y );
context.lineTo( x, y+andGateHeight );
context.lineTo( x+andGateLength/3, y+andGateHeight );
context.moveTo( x, y );
context.lineTo( x+andGateLength/3, y );
context.stroke();
context.moveTo( x+andGateLength/3, y );
context.arc( x+andGateLength/3 , y+andGateHeight/2, andGateHeight/2, -Math.PI/2, Math.PI/2);
context.stroke();
}
public void drawIO() {
context.moveTo( xin1, yin1);
context.arc( xin1, yin1, 2, 0, Math.PI*2 );
context.stroke();
context.moveTo( xin2, yin2);
context.arc( xin2, yin2, 2, 0, Math.PI*2 );
context.stroke();
context.moveTo( xout, yout);
context.arc( xout, yout, 2, 0, Math.PI*2 );
context.stroke();
}
}
InverterDown.java
package dft.client;
import com.google.gwt.canvas.dom.client.Context2d;
public class InverterDown {
double x;
double y;
double xin, yin, xout, yout;
Context2d context = null;
int inverterHeight = 20;
int inverterLength = 20;
int inverterCircleRadius = 5;
int calculatedCenterx = 0;
int calculatedCentery = inverterHeight + inverterCircleRadius;
public InverterDown(Context2d c, double xx, double yy) {
context = c;
x = xx;
y = yy;
xin = x;
yin = y;
yout = y + inverterLength + inverterCircleRadius * 2;
xout = x;
}
public void draw() {
context.moveTo(x, y);
context.lineTo(x - inverterHeight / 2, y);
context.lineTo(x, y + inverterLength);
context.lineTo(x + inverterHeight / 2, y);
context.lineTo(x, y);
context.stroke();
context.moveTo(x + calculatedCenterx + inverterCircleRadius, y
+ calculatedCentery);
context.arc(x + calculatedCenterx, y + calculatedCentery,
inverterCircleRadius, 0, Math.PI * 2.0, true);
context.stroke();
}
public void drawIO() {
context.moveTo(xin, yin);
context.arc(xin, yin, 2, 0, Math.PI * 2);
context.stroke();
context.moveTo(xout, yout);
context.arc(xout, yout, 2, 0, Math.PI * 2);
context.stroke();
}
}
InverterRight.java
package dft.client;
import com.google.gwt.canvas.dom.client.Context2d;
public class InverterRight {
double x;
double y;
double xin, yin, xout, yout;
Context2d context = null;
int inverterHeight = 20;
int inverterLength = 20;
int inverterCircleRadius = 5;
int calculatedCenterx = inverterLength + inverterCircleRadius;
int calculatedCentery = 0;
public InverterRight(Context2d c, double xx, double yy) {
context = c;
x = xx;
y = yy;
xin = x;
yin = y;
xout = x + inverterLength + inverterCircleRadius * 2;
yout = y;
}
public void draw() {
context.moveTo(x, y);
context.lineTo(x, y - inverterHeight / 2);
context.lineTo(x + inverterLength, y);
context.lineTo(x, y + inverterHeight / 2);
context.lineTo(x, y);
context.stroke();
context.moveTo(x + calculatedCenterx + inverterCircleRadius, y
+ calculatedCentery);
context.arc(x + calculatedCenterx, y + calculatedCentery,
inverterCircleRadius, 0, Math.PI * 2.0, true);
context.stroke();
}
public void drawIO() {
context.moveTo(xin, yin);
context.arc(xin, yin, 2, 0, Math.PI * 2);
context.stroke();
context.moveTo(xout, yout);
context.arc(xout, yout, 2, 0, Math.PI * 2);
context.stroke();
}
}
OrGate.java
The geometry of the OR gate is better illustrated by labeling key points in the original diagram. These (x,y) points are computed in the java code below. All the angles considered are PI/6 for the gate itself. To locate the two inputs of the gate, we use + and -PI/12 from the x6,y6 center of the left circle.
package dft.client;
import com.google.gwt.canvas.dom.client.Context2d;
/**
* OrGate
*
* @author thiebaut
*
* Defined by geometry of IEEE pub:
* http://iroi.seu.edu.cn/books/asics/Book/CH09/CH09-1.gif
*/
public class OrGate {
// various points defining the gate
Context2d context;
double x, x1, x2, x3, x4, x5, x6;
double y, y1, y2, y3, y4, y5, y6;
double radius = 26;
double height = 26;
double flat = 10;
double alpha, beta;
// inputs and output
double xin1, yin1, xin2, yin2, xout, yout;
public OrGate(Context2d c, double xx, double yy) {
x = xx;
y = yy;
context = c;
// compute various quantities
alpha = Math.PI / 6;
beta = alpha;
y1 = y - radius / 2;
y2 = y1;
y3 = y;
y4 = y2 + height;
y5 = y4;
y6 = y;
x6 = x - flat - radius;
x1 = x6 + radius * Math.sqrt(3) / 2;
x5 = x1;
x2 = x;
x4 = x;
x3 = x + radius * Math.sqrt(3) / 2;
// I/O Pins
xin1 = x6 + radius * 0.96592582628; // cos( PI/12 )
yin1 = y - radius * 0.2588190451; // sin( PI/12 )
xin2 = xin1;
yin2 = y + radius * 0.2588190451; // sin( PI/12 )
xout = x3;
yout = y3;
}
public double getXInput1() {
return xin1;
}
public double getYInput1() {
return yin1;
}
public double getXInput2() {
return xin2;
}
public double getYInput2() {
return yin2;
}
public double getXOutput() {
return xout;
}
public double getYOutput() {
return yout;
}
public void draw() {
// draw 1-2
context.moveTo(x1, y1);
context.lineTo(x2, y2);
context.stroke();
// draw 2-3
context.moveTo(x2, y2);
context.arc(x4, y4, radius, 3 * Math.PI / 2, Math.PI * 2 - Math.PI / 6);
context.stroke();
// draw 4-3
context.moveTo(x3, y3);
context.arc(x2, y2, radius, Math.PI / 6, Math.PI / 2);
context.stroke();
// Draw 4-5
context.moveTo(x4, y4);
context.lineTo(x5, y5);
context.stroke();
// Draw 1-5
context.moveTo(x1, y1);
context.arc(x6, y6, radius, -Math.PI / 6, Math.PI / 6);
context.stroke();
}
}
TextLabel.java
package dft.client;
import com.google.gwt.canvas.dom.client.Context2d;
public class TextLabel {
Context2d context;
String text;
double x, y;
String font = "bold 22px sans-serif";
public TextLabel( Context2d c, String t, double xx, double yy ) {
context = c;
text = t;
x = xx;
y = yy;
}
public void setFont( String f ) {
font = f;
}
public void draw() {
context.setFont( font );
context.fillText( text, x, y);
}
}