// Hello, this is your pilot speaking... err, testing, testing, 1, 2, 3...!!!
// We are about to enter a Volcanic Ash Cloud, please stand by whilst I divert
// your attention to one of hope!
// This assignment is a 'basic' paint package in an 'Applet', which again makes
// me hate Java even more! Arrggghhhhhh!!! Where is the logic? Why can't I get
// these damn booleans to work?!? And why the blummin' blazes to people choose
// - yes *choose* - to create programs in such a language?
// I've had more fun typing a 18,000 words whilst being partially blind-folded
// with my nose! Is this progress?
//
// Anyways, let's get this party started, first we needs to do some of that
// importing stuff, so here goes:
import java.io.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.Math;
// Phew! That works without any red lines, and now we need to give our package
// a name, extent it to an Applet and implement both a Mouse Listener and a
// Motion Listener too, as so:
public class SketchPad extends Applet
implements MouseListener, MouseMotionListener, ActionListener, KeyListener
{
// Right, we're in to the program now. Let's declare some variables which
// we'll need to use later on.
// These first variables I tried to declare as booleans, but Java sux almost
// as much as Adobe ActionScript.
// What these do is give us conditions later on.
int Fill,Rect,Oval,RoundRect,Swirl,Str;
// The following variables set up some mathematics stuff for the Swirly
// brush:
int MX,MY;
double T=0;
// Here is something for the KeyTyped routine if you're entering text
// onto the canvas:
int A,Z,TX,TY;
// Now, just in case you want to type something on the package, there'll have
// to be a String type thingymebob in the program somewhere, hence we need
// to declare that right about now:
String S$="";
// Right, now the above will set a condition to draw different shapes,
// which will either be filled or not. The following two are used to set
// the main parameters for the shape size:
int XAxis,YAxis;
// and now we have two sets of RGB values, the first set is for the background
// colour and the second is for the foreground colour, ie, what you pain with:
int R,G,B,R1,G1,B1;
// These two integers will pass the set width and height through them:
int width,height;
// This is to set what part of the screen you may draw from, because of the
// buttons at the top, we have 86 scan-lines used:
int MinX,MinY;
// Okay, let's add some kick-ass buttons:
Button Fill1=new Button("Fill on/off");
Button Rect1=new Button("Rectangle");
Button Oval1=new Button("Oval");
Button RoundRect1=new Button("Rounded rect");
Button Swirl1=new Button("Swirl");
Button Str1=new Button("Text");
// Mint, and now we need to have some input boxes, and we also need to
// label them up, don't we...??? or something :-P
TextField RedFore=new TextField("255",3);
Label label_RedFore=new Label("Red Foreground:");
TextField GreenFore=new TextField("255",3);
Label label_GreenFore=new Label("Green Foreground:");
TextField BlueFore=new TextField("255",3);
Label label_BlueFore=new Label("Blue Foreground:");
TextField RedBack=new TextField("000",3);
Label label_RedBack=new Label("Red Background:");
TextField GreenBack=new TextField("000",3);
Label label_GreenBack=new Label("Green Background:");
TextField BlueBack=new TextField("000",3);
Label label_BlueBack=new Label("Blue Background:");
TextField CW=new TextField("640",4);
Label label_CW=new Label("Canvas Width:");
TextField CH=new TextField("480",4);
Label label_CH=new Label("Canvas Height:");
// Now here is where we declare our back buffer and main canvas:
Image backbuffer;
Graphics backg;
// Okay, we need to initialize the above variables and set things in action:
public void init()
{
// As you can see, we're using the variables above, one is on and
// zero is off, like in a boolean that I couldn't get to work!
Fill=1;Oval=0;Rect=0;RoundRect=0;Swirl=0;Str=1;
// Right, now to set the default RGB values:
R=0;G=0;B=0;R1=255;G1=255;B1=255;
// Now let's set the minimum parameters that can be drawn to:
MinX=0;MinY=86;
// Okays, so now we needs to the the default size of the brush painty
// bit that will be 'drawn' on the canvas:
XAxis=30;YAxis=30;
// Here is where we get the width and height of the canvas:
width=getSize().width;height=getSize().height;
// Now, as we have buttons at the top, we need to add MinY to the
// canvas height:
height=height+MinY;
// Right, so those Swirly variables above need to do something now:
MX=width/2;
MY=height/2;
// So we need to create a back buffer at the same width and height:
backbuffer=createImage(width,height);
// And of course we call the image *from* the back buffer!!!111ONE
backg=backbuffer.getGraphics();
// First, we need to add white to the background of the buttons and
// stuff:
backg.setColor(new Color(255,255,255));
backg.fillRect(MinX,0,width,MinY);
// So, we tell the program to set the background colour, sending it
// to the above sub-routine, drawing a rectangle of the same size
// and using the default background RGB colour:
backg.setColor(new Color(R,G,B));
backg.fillRect(MinX,MinY,width,height);
// Now I see where this is going, we need to set the foreground colour
// here:
backg.setColor(new Color(R1,G1,B1));
// Right, now let's have a look at them buttons!
Fill1.addActionListener(this);
add(Fill1);
Rect1.addActionListener(this);
add(Rect1);
Oval1.addActionListener(this);
add(Oval1);
RoundRect1.addActionListener(this);
add(RoundRect1);
Swirl1.addActionListener(this);
add(Swirl1);
// Okay, this button (Str1) not only has a mouse action, but also
// needs the KeyListener to be added because you type afterwards.
// If you don't add the KeyListener to this button, then you can
// click on it but not type afterwards :-| Took me ages to work out
// and then I thought "What if I..." and blimey! It worked :D
Str1.addActionListener(this);
Str1.addKeyListener(this);
add(Str1);
// Right, now let's add the text fields:
add(label_RedFore);add(RedFore);add(label_GreenFore);add(GreenFore);
add(label_BlueFore);add(BlueFore);add(label_RedBack);add(RedBack);
add(label_GreenBack);add(GreenBack);add(label_BlueBack);add(BlueBack);
add(label_CW);add(CW);add(label_CH);add(CH);
// As this is an 'object' we need to add the mouse listeners to 'this'
addMouseListener(this);
addMouseMotionListener(this);
// Okay, so here's a bit of an anomoly in Java - because you've got a
// MouseListener and MouseMotionListener active, an Applet can't focus
// on the two things at once - because it sux - so we need to remind
// it to set its' focus to different things, like the keyboard. You do
// this with the following before adding the KeyListener:
setFocusable(true);
addKeyListener(this);
}
public void mouseMoved (MouseEvent e)
{
// Okays, so let's show the status of X and Y axis, innit
int x=e.getX();
int y=e.getY();
showStatus("Donkeysoft Sketchpad V1.7, mouse at: "+x+" "+y);
e.consume();
}
public void mouseClicked (MouseEvent e)
{
int x=e.getX();
int y=e.getY();
if (Str==1 && y>MinY)
{
TX=x;
TY=y;
S$="";
repaint();
e.consume();
return;
}
// As above, but this is a mouse click-and-drag rather than a single
// click :-)
if (y<MinY)
{
return;
}
backg.setColor(new Color(R1,G1,B1));
// And now we need to decide what's going to be drawn, so if the
// read integer is 1 then that means do it, like drawing rectangles
// and if Fill is 1 then it does a fill, otherwise you get an outline:
if (RoundRect==1 && Fill==1)
{
backg.fillRoundRect(x-(XAxis/2),y-(YAxis/2),XAxis,YAxis,XAxis/2,YAxis/2);
}
if (RoundRect==1 && Fill==0)
{
backg.drawRoundRect(x-(XAxis/2),y-(YAxis/2),XAxis,YAxis,XAxis/2,YAxis/2);
}
if (Rect==1 && Fill==1)
{
backg.fillRect(x-(XAxis/2),y-(YAxis/2),XAxis,YAxis);
}
if (Rect==1 && Fill==0)
{
backg.drawRect(x-(XAxis/2),y-(YAxis/2),XAxis,YAxis);
}
if (Oval==1 && Fill==1)
{
backg.fillOval(x-(XAxis/2),y-(YAxis/2),XAxis,YAxis);
}
if (Oval==1 && Fill==0)
{
backg.drawOval(x-(XAxis/2),y-(YAxis/2),XAxis,YAxis);
}
// This bit writes something to the status bar:
showStatus("Donkeysoft Sketchpad V1.7, mouse at: "+x+" "+y);
// Now let's clear the area behind the buttons, just in case:
backg.setColor(new Color(255,255,255));
backg.fillRect(MinX,0,width,MinY);
// Now we call a repaint and consume this mouse action or it'll repeat.
repaint();
e.consume();
}
public void mouseDragged (MouseEvent e)
{
// As above, but this is a mouse click-and-drag rather than a single
// click :-)
int x=e.getX();
int y=e.getY();
if (y<MinY)
{
return;
}
backg.setColor(new Color(R1,G1,B1));
if (RoundRect==1 && Fill==1)
{
backg.fillRoundRect(x-(XAxis/2),y-(YAxis/2),XAxis,YAxis,XAxis/2,YAxis/2);
}
if (RoundRect==1 && Fill==0)
{
backg.drawRoundRect(x-(XAxis/2),y-(YAxis/2),XAxis,YAxis,XAxis/2,YAxis/2);
}
if (Rect==1 && Fill==1)
{
backg.fillRect(x-(XAxis/2),y-(YAxis/2),XAxis,YAxis);
}
if (Rect==1 && Fill==0)
{
backg.drawRect(x-(XAxis/2),y-(YAxis/2),XAxis,YAxis);
}
if (Oval==1 && Fill==1)
{
backg.fillOval(x-(XAxis/2),y-(YAxis/2),XAxis,YAxis);
}
if (Oval==1 && Fill==0)
{
backg.drawOval(x-(XAxis/2),y-(YAxis/2),XAxis,YAxis);
}
// Okay, now let's try to add the Swirly brush code:
if (Swirl==1)
{
backg.setColor(new Color(R1,G1,B1));
int DX=x-MX;
int DY=y-MY;
T+=Math.sqrt(DX*DX+DY*DY)/20;
if(T>2*Math.PI)
{
T-=2*Math.PI;
}
backg.drawLine(x,y,x+(int)(15*Math.cos(T)),y+(int)(15*Math.sin(T)));
MX=x;
MY=y;
}
showStatus("Donkeysoft Sketchpad V1.7, mouse at: "+x+" "+y);
// Now let's clear the area behind the buttons, just in case:
backg.setColor(new Color(255,255,255));
backg.fillRect(MinX,0,width,MinY);
repaint();
e.consume();
}
public void keyTyped (KeyEvent e)
{
if (Str!=1)
{
return;
}
// Okay, let's get the keyboard input :-)
char C$=e.getKeyChar();
Z=C$;
A=S$.length();
// We need to check two conditions, one is whether or not there has
// been a keypress, and the other is to check the integer value of
// that keypress to make sure that it's not equal to 8, which is
// the delete key!
if(C$!=KeyEvent.CHAR_UNDEFINED && Z!=8 && Z!=32 && Z!=10)
{
S$=S$+C$;
Z=C$;
backg.setColor(new Color(R1,G1,B1));
backg.drawString(S$,TX,TY);
showStatus("Donkeysoft Sketchpad V1.7, Key value is ("+Z+")");
repaint();
e.consume();
}
// Right, so what do we do if the delete key is pressed?
// Well, here's a good one, let's take the value of the background
// colour and redraw the string first, this makes it invisible,
// and then let's make the string one character less before redrawing
// it onto the screen, thus elimenating the last char, ie, the one
// that has been deleted. Magic!
else
if(Z==8 && A>0)
{
backg.setColor (new Color(R,G,B));
backg.drawString(S$,TX,TY);
S$=S$.substring(0,A-1);
backg.setColor (new Color(R1,G1,B1));
backg.drawString(S$,TX,TY);
showStatus("Donkeysoft Sketchpad V1.7, Key value is ("+Z+")");
repaint();
e.consume();
}
else
// For some reason, I had an anomoly with the space, because
// if you press space after clicking on the text button,
// what happens is that you've pressed the button again and
// it seems to reset the parameters, so we need a work-around
// which physically adds a space to the string S$:
if(Z==32)
{
S$=S$+" ";
Z=C$;
backg.setColor(new Color(R1,G1,B1));
backg.drawString(S$,TX,TY);
showStatus("Donkeysoft Sketchpad V1.7, Key value is ("+Z+")");
repaint();
e.consume();
}
else
// And this is if you hit return, but there is one condition
// which will stop you going off the canvas, list this:
if(Z==10 && (TY-28<=height-MinY))
// Of course, there's an ofset of 28 because we add
// 14 to the Y axis for each carriage return, so in
// other words, 14 is added to TY if it's smaller than
// the bottom of the canvas - do the maths! Okay, it
// doesn't seem to work, but in theory it should.
{
TY=TY+14;
Z=C$;
// Okay, so let's clear S$ or that will be drawn to
// the next line
S$="";
backg.setColor(new Color(R1,G1,B1));
showStatus("Donkeysoft Sketchpad V1.7, Key value is ("+Z+")");
repaint();
e.consume();
}
}
public void keyPressed(java.awt.event.KeyEvent keyEvent)
{
}
public void keyReleased(java.awt.event.KeyEvent keyEvent)
{
}
// Yo! This is where the buttons *should* work, one hopes.
public void actionPerformed(ActionEvent e)
{
// Integers to change here are as follows:
// Fill (for whether it's draw or fill), Oval for a rounded
// brush, Rect for a square brush, RoundRect for square with rounded
// sides, swirl for the swirly brish (to be added) and finally
// Str for text input to canvas
// First, we'll check for fill on or not:
if (e.getSource()==Fill1 && Fill==1)
{
Fill=0;
showStatus("Donkeysoft Sketchpad V1.7, Fill is now OFF");
repaint();
return;
}
if (e.getSource()==Fill1 && Fill==0)
{
Fill=1;
showStatus("Donkeysoft Sketchpad V1.7, Fill is now ON");
repaint();
return;
}
// Now, we'll have a look if the square brush has been selected:
//Rect1, Oval1, RoundRect1, Swirl1, String1
if (e.getSource()==Rect1)
{
Rect=1;Oval=0;RoundRect=0;Swirl=0;Str=0;
showStatus("Donkeysoft Sketchpad V1.7, Rectangle brush selected");
repaint();
return;
}
if (e.getSource()==Oval1)
{
Rect=0;Oval=1;RoundRect=0;Swirl=0;Str=0;
showStatus("Donkeysoft Sketchpad V1.7, Rectangle brush selected");
return;
}
if (e.getSource()==RoundRect1)
{
Rect=0;Oval=0;RoundRect=1;Swirl=0;Str=0;
showStatus("Donkeysoft Sketchpad V1.7, Rounded-edged rectangle brush selected");
return;
}
if (e.getSource()==Swirl1)
{
Rect=0;Oval=0;RoundRect=0;Swirl=1;Str=0;
showStatus("Donkeysoft Sketchpad V1.7, Swirl brush selected");
return;
}
if (e.getSource()==Str1)
{
Rect=0;Oval=0;RoundRect=0;Swirl=0;Str=1;
showStatus("Donkeysoft Sketchpad V1.7, text brush selected");
return;
}
repaint();
}
// Okay, so this is there the back buffer is drawn to and syncronised
public void update (Graphics g)
{
g.drawImage(backbuffer,0,0,this);
if (Str==1 && R1/2>0 && G1/2>0 && B1/2>0)
{
// Right, let's have a different colour for the text marker
// than the text to make it a bit clearer:
g.setColor(new Color (R1/2,G1/2,B1/2));
g.drawLine(TX,TY,TX,TY-10);
g.drawLine(TX,TY,TX+10,TY);
}
else
if (Str==1 && R1/2<=0 || G1/2<=0 || B1<=0)
{
// Right, well we can't do an RGB colour smaller than zero
// so let's set the new colour to zero for each RGB value:
g.setColor(new Color (0,0,0));
g.drawLine(TX,TY,TX,TY-10);
g.drawLine(TX,TY,TX+10,TY);
}
getToolkit().sync();
}
// This then updates (or flips) the back buffer so we can see the last
// action added to the canvas, good, innit?
public void paint (Graphics g)
{
update(g);
}
// All this crap here needed to be added to this program or Java doesn't
// like it and it takes *hours* to work this out, even though it's not
// actually doing anything whatsoever. I'd like to meet the sadistic
// idiots who created all of these useless bits in Java, I'm sure it's
// been created just to annoy people rather than being in any way
// whatsoever helpful.
public void mouseEntered(java.awt.event.MouseEvent mouseEvent)
{
}
public void mouseExited(java.awt.event.MouseEvent mouseEvent)
{
}
public void mousePressed(java.awt.event.MouseEvent mouseEvent)
{
}
public void mouseReleased(java.awt.event.MouseEvent mouseEvent)
{
}
}
// This assignment was created by Shaun Bebbington to learn about them
// Applets :-P (c) 2010 Donkey Soft, version 1.7 - actually freeware
// to be pedantic.