OpenGL generic error 1282, issue drawing GL_QUADS [duplicate] - java

This question already has answers here:
glTranslatef not working within glBegin .. glEnd
(2 answers)
Closed 7 years ago.
I'm attempting to draw a red square with LGJWL (native OpenGL bindings for Java) in Java. I receive a 1282 error from OpenGL and my square does not appear.
Below is (what I believe to be) the basic implementation for what I'm trying to do.
// begin drawing quads
glBegin(GL11.GL_QUADS);
// set color
glColor4d(255, 0, 0, 255);
// draw rectangle vertices
glVertex2i(0, 0);
glVertex2i(100, 0);
glVertex2i(100, 100);
glVertex2i(0, 100);
glEnd();
Following is what I'm trying to do in practice.
public class WindowComponent extends Component {
/** Window color */
private Color color = new Color();
/**
* Sets the window's color
* #param r red
* #param b blue
* #param g green
* #param a alpha
*/
public void setColor(int r, int g, int b, int a) {
color.set(r, g, b, a);
}
/**
* #see Component#renderComponent()
*/
#Override
protected void renderComponent() {
// begin drawing quads
begin(GL11.GL_QUADS);
// set color
GL11.glColor4ub(color.getRedByte(), color.getGreenByte(), color.getBlueByte(), color.getAlphaByte());
// draw rectangle vertices
GL11.glVertex2i(0, 0);
GL11.glVertex2i(getWidth(), 0);
GL11.glVertex2i(getWidth(), getHeight());
GL11.glVertex2i(0, getHeight());
end();
}
}
is an extension of...
public abstract class Component {
/** Dimension of component */
private Dimension size = new Dimension();
/** Position of component */
private Vector2f position = new Vector2f();
/**
* Gets width
* #return width
*/
public int getWidth() {
return size.getWidth();
}
/**
* Gets height
* #return height
*/
public int getHeight() {
return size.getHeight();
}
/**
* Gets size
* #return size
*/
public Dimension getSize() {
return size;
}
/**
* Gets X position
* #return X position
*/
public float getX() {
return position.getX();
}
/**
* Gets Y position
* #return Y position
*/
public float getY() {
return position.getY();
}
/**
* Gets position vector
* #return position vector
*/
public Vector2f getPosition() {
return position;
}
/**
* Sets width
* #param width width
*/
public void setWidth(int width) {
size.setWidth(width);
}
/**
* Sets height
* #param height height
*/
public void setHeight(int height) {
size.setHeight(height);
}
/**
* Sets size
* #param width width
* #param height height
*/
public void setSize(int width, int height) {
size.setSize(width, height);
}
/**
* Sets X position
* #param x X position
*/
public void setX(float x) {
position.setX(x);
}
/**
* Sets Y position
* #param y Y position
*/
public void setY(float y) {
position.setY(y);
}
/**
* Sets position
* #param x X position
* #param y Y position
*/
public void setPosition(float x, float y) {
position.set(x, y);
}
/**
* Begins drawing and does parent translations
* #param mode drawing mode
*/
protected void begin(int mode) {
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glBegin(mode);
GL11.glTranslatef(getX(), getY(), 0);
}
/**
* Ends drawing and does parent translations
*/
protected void end() {
GL11.glTranslatef(-getX(), -getY(), 0);
GL11.glEnd();
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
/**
* Applies pre-rendering checks then renders the component
*/
public void render() {
renderComponent();
}
/**
* Component rendering code here
*/
protected abstract void renderComponent();
}
and I'm initializing this all with...
WindowComponent window = new WindowComponent();
window.setSize(100, 100);
window.setPosition(100, 100);
window.setColor(255, 0, 0, 255);
window.render();

In begin:
GL11.glBegin(mode);
GL11.glTranslatef(getX(), getY(), 0);
You cannot call glTranslate in between glBegin and glEnd; move it to before.

Related

How to bounce text in a window without JFrame?

I am trying to bounce my text in a window, inserted from a text file without modifying the inputs from the text. I have the code to create and bounce the text, but some of it is lost when trying to bounce on the wall. The code consists of 3 classes.
This creates the text:
public class MyShape extends ClosedShape {
//The width and height of the text (major and minor axis)
private int width, height;
private String bouncingText;
private double textFont;
/**
* Creates an oval.
* #param x The display component's x position.
* #param y The display component's y position.
* #param vx The display component's x velocity.
* #param vy The display component's y velocity.
* #param width The width of the text (in pixels).
* #param height The height of the text (in pixels).
* #param colour The line colour or fill colour.
* #param isFilled True if the oval is filled with colour, false if opaque.
*/
public MyShape (int insertionTime, int x, int y, int vx, int vy, String bouncingText, int width, int height, Color colour, boolean isFilled, double textFont) {
super (insertionTime, x, y, vx, vy, colour, isFilled);
this.width = width;
this.height = height;
this.bouncingText = bouncingText;
this.textFont = textFont;
}
/**
* Method to convert a text to a string.
*/
public String toString () {
String result = "This is a text shape\n";
result += super.toString ();
result += "Its width is " + this.width + " and its height is " + this.height + "\n";
return result;
}
/**
* #param width Resets the width.
*/
public void setWidth (int width) {
this.width = width;
}
/**
* #param height Resets the height.
*/
public void setHeight (int height) {
this.height = height;
}
public void setBouncingText (String bouncingText) {
this.bouncingText = bouncingText;
}
public void setTextFont (double textFont) {
this.textFont = textFont;
}
/**
* #return The width of the text.
*/
public int getWidth() {
return width;
}
/**
* #return The height of the text.
*/
public int getHeight() {
return height;
}
public String getBouncingText() {
return bouncingText;
}
public double getTextFont() {
return textFont;
}
public void pulsing() {
if (textFont > 20) {
textFont = 10;
}else {
textFont = 50;
}
}
/**
* Draw the text.
* #param g The graphics object of the drawable component.
*/
public void draw (GraphicsContext g) {
Font bouncingTextFont = new Font ("TimesNew", textFont);
g.setFill (colour);
g.setStroke( colour );
if (isFilled) {
g.fillText(bouncingText, xPos, yPos );
g.setFont(bouncingTextFont);
}
else {
g.strokeText(bouncingText, xPos, yPos );
g.setFont(bouncingTextFont);
}
}
}
This is the bouncing code:
import java.util.ArrayList;
import javafx.animation.Animation;
import javafx.animation.AnimationTimer;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.scene.shape.ArcType;
import javafx.stage.Stage;
import javafx.util.Duration;
public class BouncingShapesWindow {
private static final int ANIMATION_DELAY = 10;
private static final String FRAME_TITLE = "Shape Booooiiinggg Frame";
private GraphicsContext gc;
private Queue shapesToAdd;
private ArrayList<ClosedShape> activeShapes;
private int currentTime = 0;
private boolean flag=true;
private String filename;
public BouncingShapesWindow(GraphicsContext gc,String filename) {
this.gc=gc;
activeShapes=new ArrayList<ClosedShape>();
this.initShapes(filename);
this.insertShapes ();
drawShapes();
actionPerformed();
}
private void drawShapes () {
for (ClosedShape s : activeShapes)
{
s.draw(gc);
}
}
private void initShapes (String filename) {
shapesToAdd = ReadShapeFile.readFile(filename);
}
private void insertShapes() {
//no more shapes to add, we are done
if (shapesToAdd.isEmpty ()) {
return;
}
//add shapes if needed
ClosedShape current = (ClosedShape) shapesToAdd.peek ();
while (!shapesToAdd.isEmpty () && (current.getInsertionTime() <= currentTime*ANIMATION_DELAY)) {
activeShapes.add(current);
shapesToAdd.dequeue();
if (!shapesToAdd.isEmpty ()) {
current = (ClosedShape) shapesToAdd.peek();
}
}
}
public void actionPerformed()
{
Timeline timeline = new Timeline(new KeyFrame(Duration.millis(5), ae -> onTime()));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}
private void onTime() {
currentTime++;
double h =gc.getCanvas().getHeight();
double w = gc.getCanvas().getWidth();
gc.clearRect(0, 0, w, h);
moveShapes();
insertShapes ();
drawShapes();
}
public void moveShapes()
{
double dimsY = gc.getCanvas().getHeight() ;
double dimsX = gc.getCanvas().getWidth() ;
for (ClosedShape s : activeShapes)
{
s.move();
// Move us back in and bounce if we went outside the drawing area.
if (s.outOfBoundsX(dimsX))
{
s.putInBoundsX(dimsX);
s.bounceX();
}
if (s.outOfBoundsY(dimsY))
{
s.putInBoundsY(dimsY);
s.bounceY();
}
}
}
}
and this is the super class:
import javafx.scene.paint.Color;
import javafx.scene.canvas.GraphicsContext;
/**
* A ClosedShape is any shape that can be drawn without
* taking a pencil off a piece of paper.
* It's representation on computer has a line colour
* and a position on the drawable screen component.
* It can be filled in with colour or opaque.
* This class is a super class for all shapes.
*/
public class ClosedShape {
/**
* The x position of the Shape.
*/
protected int xPos;
/**
* The y position of the Shape.
*/
protected int yPos = 20;
/**
* The x position of the Shape.
*/
protected int xVec;
/**
* The y position of the Shape.
*/
protected int yVec;
/**
* The line colour of the shape, or the filled in
* colour if the Shape has fill.
*/
protected Color colour;
/**
* Determines if the Shape has a fill colour or not.
*/
protected boolean isFilled;
/**
* Encodes the insertion time into the scene
*/
private int insertionTime;
/**
* Creates a closed shape object.
* #param x The x position.
* #param y the y position.
* #param colour The line or fill colour.
* #param isFilled True if the shape is filled, false if not.
*/
protected ClosedShape (int insertionTime, int x, int y, int vx, int vy, Color colour, boolean isFilled) {
this.xPos = x;
this.yPos = y;
this.xVec = vx;
this.yVec = vy;
this.colour = colour;
this.isFilled = isFilled;
this.insertionTime = insertionTime;
}
/**
* The method returns a string suitable for printing.
* #return string to print out shape.
*/
public String toString () {
String result = "";
result += "Its position is " + xPos + " " + yPos + "\n";
result += "Its velocity is " + xVec + " " + yVec + "\n";
result += "Its colour is " + colour + "\n";
if (isFilled)
result += "It is filled" + "\n";
else
result += "It is not filled" + "\n";
result += "It should be inserted at " + insertionTime + "\n";
return result;
}
/**
* Resets the x position.
*/
public void setX (int x) {
this.xPos = x;
}
/**
* Resets the y position.
*/
public void setY (int y) {
this.yPos = y;
}
/**
* Resets the x vector
*/
public void setVecX (int x) {
this.xVec = x;
}//end setVecX
/**
* Resets the y position.
*/
public void setVecY (int y) {
this.yVec = y;
}//end setVecY
/**
* Resets the colour.
*/
public void setColour (Color colour) {
this.colour = colour;
}
/**
* Sets the shape to filled.
*/
public void setFilled () {
isFilled = true;
}
/**
* Sets the shape to unfilled.
*/
public void unsetFilled () {
isFilled = false;
}
/**
* Sets the insertion time.
*/
public void setInsertionTime (int time) {
insertionTime = time;
}
/**
* #return The x position value.
*/
public int getX() {
return xPos;
}
/**
* #return The y position value.
*/
public int getY() {
return yPos;
}
/**
* #return The colour.
*/
public Color getColour() {
return colour;
}
/**
* #return True if the shape is filled, false if not.
*/
public boolean isFilled() {
return isFilled;
}
/**
* #return the insertion time.
*/
public int getInsertionTime () {
return insertionTime;
}
/**
* Puts the shape back in bounds in X
*/
public void putInBoundsX (double winX) {
if (xPos < 0) xPos = 0;
if (xPos + this.getWidth() > winX) {
xPos = (int) (winX - Math.ceil (this.getWidth ()));
}
}//end inBoundsX;
/**
* Puts the shape back in bounds
*/
public void putInBoundsY (double winY) {
if (yPos < 0) yPos = 0;
if (yPos + this.getHeight() > winY) {
yPos = (int) (winY - Math.ceil (this.getHeight ()));
}
}//end inBoundsY;
/**
* Bounces the shape off a vertical wall
*/
public void bounceX () {
xVec = -xVec;
}
/**
* Bounces the shape off a horizontal wall
*/
public void bounceY () {
yVec = -yVec;
}
/**
* Returns true if the shapes have gone out of bounds in X
*/
public boolean outOfBoundsX (double winX) {
return (xPos + this.getWidth()> winX) || (xPos < 0);
}
/**
* Returns true if the shapes have gone out of bounds in Y
*/
public boolean outOfBoundsY (double winY) {
return (yPos + this.getHeight() > winY) || (yPos < 0);
}
/**
* Takes in a direction and a velocity and moves the shape
* in that direction on unit
*/
public void move () {
xPos += xVec;
yPos += yVec;
}
/**
* Draws the object to the current component.
* #param g The graphics object associated with the drawing component.
*/
public void draw (GraphicsContext g) {
System.out.println ("You forgot to override this method! (draw)");
System.out.println ("Don't modify this method.");
}
/**
* Get the width of the current component
*/
public int getWidth () {
System.out.println ("You forgot to override this method! (getWidth)");
System.out.println ("Don't modify this method.");
return 1;
}
/**
* Get the width of the current component
*/
public int getHeight () {
System.out.println ("You forgot to override a method! (getHeight)");
System.out.println ("Don't modify this method.");
return 1;
}
public int getSide () {
System.out.println ("You forgot to override this method! (getSide)");
System.out.println ("Don't modify this method.");
return 1;
}
}
I tried reversing it, but nothing works. Using other shapes like circle or rect is OK, but with text it bounces under the head of the window and if I change the font size it loses its boundaries. I tried searching for solutions and it seems that everything uses JFrame and JPanel. I hope the code I provided leads to a useful solution.

Opengl nvidia gpu multisampling

I have a 3d program that was working fine before I updated my nvidia gf 620m graphics drivers to version 22.21.13.8494 .Now whenever I run the program I get a black screen . I tried to find the source of the problem and it seems to be with the multisampling FBO in my program as the problem only occurs when its enabled.
My FBO class.
public class Fbo {
public static final int NONE = 0;
public static final int DEPTH_TEXTURE = 1;
public static final int DEPTH_RENDER_BUFFER = 2;
private final int width;
private final int height;
private int frameBuffer;
private boolean multisampleMultiTargets = false;
private int colourTexture;
private int depthTexture;
private int depthBuffer;
private int colourBuffer;
private int colourBuffer2;
/**
* Creates an FBO of a specified width and height, with the desired type of
* depth buffer attachment.
*
* #param width
* - the width of the FBO.
* #param height
* - the height of the FBO.
* #param depthBufferType
* - an int indicating the type of depth buffer attachment that
* this FBO should use.
*/
public Fbo(int width, int height, int depthBufferType) {
this.width = width;
this.height = height;
initialiseFrameBuffer(depthBufferType);
}
public Fbo(int width, int height) {
this.width = width;
this.height = height;
this.multisampleMultiTargets = true;
initialiseFrameBuffer(DEPTH_RENDER_BUFFER);
}
/**
* Deletes the frame buffer and its attachments when the game closes.
*/
public void cleanUp() {
GL30.glDeleteFramebuffers(frameBuffer);
GL11.glDeleteTextures(colourTexture);
GL11.glDeleteTextures(depthTexture);
GL30.glDeleteRenderbuffers(depthBuffer);
GL30.glDeleteRenderbuffers(colourBuffer);
GL30.glDeleteRenderbuffers(colourBuffer2);
}
/**
* Binds the frame buffer, setting it as the current render target. Anything
* rendered after this will be rendered to this FBO, and not to the screen.
*/
public void bindFrameBuffer() {
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, frameBuffer);
GL11.glViewport(0, 0, width, height);
}
/**
* Unbinds the frame buffer, setting the default frame buffer as the current
* render target. Anything rendered after this will be rendered to the
* screen, and not this FBO.
*/
public void unbindFrameBuffer() {
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
GL11.glViewport(0, 0, Display.getWidth(), Display.getHeight());
}
/**
* Binds the current FBO to be read from (not used in tutorial 43).
*/
public void bindToRead() {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, frameBuffer);
GL11.glReadBuffer(GL30.GL_COLOR_ATTACHMENT0);
}
/**
* #return The ID of the texture containing the colour buffer of the FBO.
*/
public int getColourTexture() {
return colourTexture;
}
/**
* #return The texture containing the FBOs depth buffer.
*/
public int getDepthTexture() {
return depthTexture;
}
/**
* Creates the FBO along with a colour buffer texture attachment, and
* possibly a depth buffer.
*
* #param type
* - the type of depth buffer attachment to be attached to the
* FBO.
*/
public void resolveToFbo(int readBuffer,Fbo outputFbo){
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER,outputFbo.frameBuffer);
GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER,this.frameBuffer);
GL11.glReadBuffer(readBuffer);
GL30.glBlitFramebuffer(0,0,width,height,0,0,outputFbo.width,outputFbo.height,GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT,GL11.GL_LINEAR);
this.unbindFrameBuffer();
}
public void resolveToScreen(){
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER,0);
GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER,this.frameBuffer);
GL11.glDrawBuffer(GL11.GL_BACK);
GL30.glBlitFramebuffer(0,0,width,height,0,0,Display.getWidth(),Display.getHeight(),GL11.GL_COLOR_BUFFER_BIT ,GL11.GL_LINEAR);
this.unbindFrameBuffer();
}
private void initialiseFrameBuffer(int type) {
createFrameBuffer();
if(multisampleMultiTargets){
colourBuffer = createMultisampledColourbuffer(GL30.GL_COLOR_ATTACHMENT0);
colourBuffer2 = createMultisampledColourbuffer(GL30.GL_COLOR_ATTACHMENT1);
}else{
createTextureAttachment();
}
if (type == DEPTH_RENDER_BUFFER) {
createDepthBufferAttachment();
} else if (type == DEPTH_TEXTURE) {
createDepthTextureAttachment();
}
unbindFrameBuffer();
}
/**
* Creates a new frame buffer object and sets the buffer to which drawing
* will occur - colour attachment 0. This is the attachment where the colour
* buffer texture is.
*
*/
private void createFrameBuffer() {
frameBuffer = GL30.glGenFramebuffers();
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBuffer);
determineDrawBuffer();
}
private void determineDrawBuffer(){
IntBuffer drawBuffers = BufferUtils.createIntBuffer(2);
drawBuffers.put(GL30.GL_COLOR_ATTACHMENT0);
if(this.multisampleMultiTargets){
drawBuffers.put(GL30.GL_COLOR_ATTACHMENT1);
}
drawBuffers.flip();
GL20.glDrawBuffers(drawBuffers);
}
/**
* Creates a texture and sets it as the colour buffer attachment for this
* FBO.
*/
private void createTextureAttachment() {
colourTexture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, colourTexture);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE,
(ByteBuffer) null);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL11.GL_TEXTURE_2D, colourTexture,
0);
}
/**
* Adds a depth buffer to the FBO in the form of a texture, which can later
* be sampled.
*/
private void createDepthTextureAttachment() {
depthTexture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, depthTexture);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL14.GL_DEPTH_COMPONENT24, width, height, 0, GL11.GL_DEPTH_COMPONENT,
GL11.GL_FLOAT, (ByteBuffer) null);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL11.GL_TEXTURE_2D, depthTexture, 0);
}
private int createMultisampledColourbuffer(int Attachment){
int colourBuffer = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, colourBuffer);
GL30.glRenderbufferStorageMultisample(GL30.GL_RENDERBUFFER,4, GL11.GL_RGBA8, width, height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER,Attachment, GL30.GL_RENDERBUFFER,
colourBuffer);
return colourBuffer;
}
/**
* Adds a depth buffer to the FBO in the form of a render buffer. This can't
* be used for sampling in the shaders.
*/
private void createDepthBufferAttachment() {
depthBuffer = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthBuffer);
if(!multisampleMultiTargets){
GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL14.GL_DEPTH_COMPONENT24, width, height);
}else{
GL30.glRenderbufferStorageMultisample(GL30.GL_RENDERBUFFER,4, GL14.GL_DEPTH_COMPONENT24, width, height);
}
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL30.GL_RENDERBUFFER,
depthBuffer);
}
}

Canvas shows content only by minimizing and resizing the window

im using the Canvas class to make a screensaver as a schoolproject.
But the window generated by Canvas doesnt show my objects on it (current time)
until i minimize it an resize it again. After that all things works fine.
so what is wrong?
thank you for coming answers!
with kind regards
leon
those are the classes, i peronally think that the problem is in the class Start or BufferedCanvas
import java.awt.*;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class Start
{
int fensterX = 900;
int fensterY = 700;
Farbengenerator fg = new Farbengenerator();
BufferedCanvas c =newBufferedCanvas("Bild",fensterX,fensterY);
Zeit z = new Zeit();
SchriftParameter sp = new SchriftParameter();
public void zeichneText(){
double x = 100;
double y = 100;
double fy =0.01;
double fx =0.02;
int red=0;
int green=0;
int blue=0;
double colourGrowRate=0.05;
String uhr;
c.setFont(sp.setzteSchrift());
c.setForegroundColour(Color.BLACK);
c.setBackgroundColour(Color.WHITE);
for(int i=0;i<100;i++){
c.drawString("Starting...",(int)x,(int)y);
c.updateAndShow();
try{Thread.sleep(50);}
catch(Exception e){};
c.updateAndShow();
}
CreateButton d = new CreateButton();
d.run();
while(true) {
c.erase();
uhr = z.erstelleZeit();
c.drawString(uhr,(int)x,(int)y);
if((int)x >fensterX-93 || (int)x <5){
fx = fx * (-1);
red=fg.gibROT();
green=fg.gibGRUEN();
blue=fg.gibBLAU();
Color colour = new Color(red,green,blue);
c.setForegroundColour(colour);
}
if((int)y > fensterY-1 || (int)y < 46){
fy = fy * (-1);
red=fg.gibROT();
green=fg.gibGRUEN();
blue=fg.gibBLAU();
Color colour = new Color(red,green,blue);
c.setForegroundColour(colour);
}
if((int)colourGrowRate>=1){
fg.generiereFarbe();
colourGrowRate = 0.05;
}
colourGrowRate=colourGrowRate+colourGrowRate;
x = x + fx;
y = y + fy;
c.updateAndShow();
}
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferStrategy;
public class BufferedCanvas
{
private JFrame frame;
private CanvasPane canvas;
private Graphics2D graphic;
private Color backgroundColour;
private Image canvasImage;
BufferStrategy buff;
/**
* Create a BufferedCanvas with default height,
width and background colour
* (300, 300, white).
* #param title title to appear in Canvas Frame
*/
public BufferedCanvas(String title)
{
this(title, 300, 300, Color.white);
}
/**
* Create a BufferedCanvas with default background colour (white).
* #param title title to appear in Canvas Frame
* #param width the desired width for the canvas
* #param height the desired height for the canvas
*/
public BufferedCanvas(String title, int width, int height)
{
this(title, width, height, Color.white);
}
/**
* Create a BufferedCanvas.
* #param title title to appear in Canvas Frame
* #param width the desired width for the canvas
* #param height the desired height for the canvas
* #param bgClour the desired background colour of the canvas
*/
public BufferedCanvas(String title, int width, int height, Color bgColour)
{
frame = new JFrame();
canvas = new CanvasPane();
frame.setContentPane(canvas);
frame.setTitle(title);
canvas.setPreferredSize(new Dimension(width, height));
backgroundColour = bgColour;
frame.pack();
frame.createBufferStrategy(2);
buff = frame.getBufferStrategy();
graphic = (Graphics2D)buff.getDrawGraphics();
setVisible(true);
}
/**
* Set the canvas visibility and brings canvas to the front of screen
* when made visible. This method can also be used to bring an already
* visible canvas to the front of other windows.
* #param visible boolean value representing the desired visibility of
* the canvas (true or false)
*/
public void setVisible(boolean visible)
{
if(graphic == null) {
// first time: instantiate the offscreen image and fill it with
// the background colour
Dimension size = canvas.getSize();
canvasImage = canvas.createImage(size.width, size.height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.setColor(backgroundColour);
graphic.fillRect(0, 0, size.width, size.height);
graphic.setColor(Color.black);
}
frame.setVisible(true);
}
/**
* Update the canvas and show the new image.
*/
public void updateAndShow(){
buff.show();
}
/**
* Provide information on visibility of the Canvas.
* #return true if canvas is visible, false otherwise
*/
public boolean isVisible()
{
return frame.isVisible();
}
/**
* Draw a given shape onto the canvas.
* #param shape the shape object to be drawn on the canvas
*/
public void draw(Shape shape)
{
graphic.draw(shape);
//canvas.repaint();
}
/**
* Fill the internal dimensions of a given shape with the current
* foreground colour of the canvas.
* #param shape the shape object to be filled
*/
public void fill(Shape shape)
{
graphic.fill(shape);
//canvas.repaint();
}
/**
* Erase the whole canvas.
*/
public void erase()
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
Dimension size = canvas.getSize();
graphic.fill(new Rectangle(0, 0, size.width, size.height));
graphic.setColor(original);
//canvas.repaint();
}
/**
* Erase a given shape's interior on the screen.
* #param shape the shape object to be erased
*/
public void erase(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
graphic.fill(shape); // erase by filling background colour
graphic.setColor(original);
//canvas.repaint();
}
/**
* Erases a given shape's outline on the screen.
* #param shape the shape object to be erased
*/
public void eraseOutline(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
graphic.draw(shape); // erase by drawing background colour
graphic.setColor(original);
//canvas.repaint();
}
/**
* Draws an image onto the canvas.
* #param image the Image object to be displayed
* #param x x co-ordinate for Image placement
* #param y y co-ordinate for Image placement
* #return returns boolean value representing whether the image was
* completely loaded
*/
public boolean drawImage(Image image, int x, int y)
{
boolean result = graphic.drawImage(image, x, y, null);
//canvas.repaint();
return result;
}
/**
* Draws a String on the Canvas.
* #param text the String to be displayed
* #param x x co-ordinate for text placement
* #param y y co-ordinate for text placement
*/
public void drawString(String text, int x, int y)
{
graphic.drawString(text, x, y);
//canvas.repaint();
}
/**
* Erases a String on the Canvas.
* #param text the String to be displayed
* #param x x co-ordinate for text placement
* #param y y co-ordinate for text placement
*/
public void eraseString(String text, int x, int y)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
graphic.drawString(text, x, y);
graphic.setColor(original);
//canvas.repaint();
}
/**
* Draws a line on the Canvas.
* #param x1 x co-ordinate of start of line
* #param y1 y co-ordinate of start of line
* #param x2 x co-ordinate of end of line
* #param y2 y co-ordinate of end of line
*/
public void drawLine(int x1, int y1, int x2, int y2)
{
graphic.drawLine(x1, y1, x2, y2);
//canvas.repaint();
}
/**
* Draws a dot/pixel on the Canvas.
* #param x x co-ordinate of dot
* #param y y co-ordinate of dot
*/
public void drawDot(int x, int y)
{
graphic.drawLine(x, y, x, y);
//canvas.repaint();
}
/**
* Sets the foreground colour of the Canvas.
* #param newColour the new colour for the foreground of the Canvas
*/
public void setForegroundColour(Color newColour)
{
graphic.setColor(newColour);
}
/**
* Returns the current colour of the foreground.
* #return the colour of the foreground of the Canvas
*/
public Color getForegroundColour()
{
return graphic.getColor();
}
/**
* Sets the background colour of the Canvas.
* #param newColour the new colour for the background of the Canvas
*/
public void setBackgroundColour(Color newColour)
{
backgroundColour = newColour;
graphic.setBackground(newColour);
}
/**
* Returns the current colour of the background
* #return the colour of the background of the Canvas
*/
public Color getBackgroundColour()
{
return backgroundColour;
}
/**
* changes the current Font used on the Canvas
* #param newFont new font to be used for String output
*/
public void setFont(Font newFont)
{
graphic.setFont(newFont);
}
/**
* Returns the current font of the canvas.
* #return the font currently in use
**/
public Font getFont()
{
return graphic.getFont();
}
/**
* Sets the size of the canvas.
* #param width new width
* #param height new height
*/
public void setSize(int width, int height)
{
canvas.setPreferredSize(new Dimension(width, height));
Image oldImage = canvasImage;
canvasImage = canvas.createImage(width, height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.drawImage(oldImage, 0, 0, null);
frame.pack();
}
/**
* Returns the size of the canvas.
* #return The current dimension of the canvas
*/
public Dimension getSize()
{
return canvas.getSize();
}
/**
* Waits for a specified number of milliseconds before finishing.
* This provides an easy way to specify a small delay which can be
* used when producing animations.
* #param milliseconds the number
*/
public void wait(int milliseconds)
{
try
{
Thread.sleep(milliseconds);
}
catch (Exception e)
{
// ignoring exception at the moment
}
}
/************************************************************************
* Nested class CanvasPane - the actual canvas component contained in the
* Canvas frame. This is essentially a JPanel with added capability to
* refresh the image drawn on it.
*/
private class CanvasPane extends JPanel
{
public void paint(Graphics g)
{
g.drawImage(canvasImage, 0, 0, null);
}
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
public class CreateButton extends JFrame implements ActionListener{
public void run() {
createAndShowGUI();
}
public CreateButton() {
// set layout for the frame
this.getContentPane().setLayout(new FlowLayout());
JButton button1 = new JButton();
button1.setText("closeApp");
//set actionlisteners for the buttons
button1.addActionListener(this);
// define a custom short action command for the button
button1.setActionCommand("closeApp");
// add buttons to frame
add(button1);
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new CreateButton();
//Display the window.
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent ae) {
String action = ae.getActionCommand();
if (action.equals("closeApp")) {
System.exit(1);
}
}
}
import java.awt.*;
public class SchriftParameter
{
public Font setzteSchrift(){
Font f = new Font("Fixed",1,24);
return (f);
}
}
public class Farbengenerator
{
int r=0;
int g=0;
int b=0;
public void generiereFarbe(){
if (r<255&&g==0&&b==0){
r++;
}
else if (r==255&&g<255&&b==0){
g++;
}
else if (r>0&&g==255&&b==0){
r= r-1;
}
else if (r==0&&g==255&&b<255){
b++;
}
else if (r==0&&g>0&&b==255){
g=g-1;
}
else if (r<255&&g==0&&b==255){
r++;
}
else if (r==255&&g==0&&b>0){
b=b-1;
}
}
public int gibROT () {
return(r);
}
public int gibGRUEN () {
return(g);
}
public int gibBLAU () {
return(b);
}
}
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class Zeit
{
public String erstelleZeit(){
DateFormat df = new SimpleDateFormat("HH:mm:ss");
Date d = new Date();
String uhr = df.format(d);
return (uhr);
}
}

Programmatically detecting whether a point is on a circular arc?

I have created an arc. I want to do certain things on different arcs when an arc is clicked. How do I know if an arc is touched or not? Can someone please provide some code for onTouch method to do such a calculation. Also please explain it a little bit.
package com.example.android.customviews;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
/**
* Limit Indicator is used to show any kind of limits such as Balance and Actual
* Amount of wallet present in an account. In order to use this in the XML
* Layout, please include the following: <br />
* <br />
*
* xmlns:custom="http://schemas.android.com/apk/res/com.example.android.customviews"
*
* <br /> <br />
*
* Following custom attributes are provided: <br />
* <br />
*
* custom:borderColor <br />
* custom:borderRadius <br />
* custom:outerCircleRadius <br />
* custom:text <br />
* custom:textSize <br />
* custom:innerCircleColor <br />
*
* #author Syed Ahmed Hussain
*/
public class LimitIndicator extends ViewGroup {
// ============================================================================================
// Variables Declaration
private int mInnerCircleColor;
private int mBorderColor;
private int mTextColor;
private float mTextSize;
private String mTitleText = "";
private float mHalfOfBorderWidth = 0.0f;
private float mOuterCircleRadius = 2.0f;
private float mBorderWidth = 30.0f;
private Paint mDialPaint, mTextPaint, mBorderPaint, mInnerCirclePaint;
private float mCenterX = 100.0f;
private float mCenterY = 100.0f;
private int mTotalProgressInDegrees;
private int mTotalProgress = -1;
// Start Angle should be 90 degrees to create a clockwise illusion.
private int mStartAngle = 270;
// This should be the one which provides us a percentage wise drawing
private int mSweepAngle = 1;
private RectF mBorderBounds = null;
// ============================================================================================
// Constructors
public LimitIndicator(Context pContext) {
super(pContext);
Log.d("LimitIndicator", "LimitIndicator(Context pContext) called");
initialize();
}
public LimitIndicator(Context pContext, AttributeSet pAttrs) {
super(pContext, pAttrs);
Log.d("LimitIndicator", "LimitIndicator(Context pContext, AttributeSet pAttrs) called");
TypedArray typedArray = pContext.obtainStyledAttributes(pAttrs, R.styleable.LimitIndicator, 0, 0);
try {
mOuterCircleRadius = typedArray.getDimension(R.styleable.LimitIndicator_outerCircleRadius, mOuterCircleRadius);
mTextColor = typedArray.getColor(R.styleable.LimitIndicator_textColor, Color.WHITE);
mTitleText = typedArray.getString(R.styleable.LimitIndicator_text);
mTextSize = typedArray.getDimension(R.styleable.LimitIndicator_textSize, 25);
mTotalProgress = typedArray.getInteger(R.styleable.LimitIndicator_numerator, mTotalProgress);
mBorderColor = typedArray.getColor(R.styleable.LimitIndicator_borderColor, Color.BLACK);
mBorderWidth = typedArray.getDimension(R.styleable.LimitIndicator_borderRadius, mBorderWidth);
mInnerCircleColor = typedArray.getColor(R.styleable.LimitIndicator_innerCircleColor, Color.GREEN);
} finally {
typedArray.recycle();
}
initialize();
}
// ============================================================================================
// Initialization
/**
* Initialize all elements
*/
private void initialize() {
// Set up the paint for the dial
mDialPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mDialPaint.setStyle(Paint.Style.FILL);
mDialPaint.setColor(Color.GRAY);
// Set up the paint for the label text
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setTypeface(Typeface.SANS_SERIF);
mTextPaint.setTextAlign(Align.CENTER);
mTextPaint.setColor(mTextColor);
mTextPaint.setTextSize(mTextSize);
// Set up the paint for the border
mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setStrokeWidth(mBorderWidth);
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setAntiAlias(true);
mBorderPaint.setDither(true);
mInnerCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mInnerCirclePaint.setStyle(Paint.Style.FILL);
mInnerCirclePaint.setColor(mInnerCircleColor);
// mBorderPaint.setStrokeJoin(Paint.Join.ROUND);
// mBorderPaint.setStrokeCap(Paint.Cap.ROUND);
mBorderBounds = new RectF(getLeft(), getTop(), getRight(), getBottom());
}
// ============================================================================================
// Drawing on surface
#Override
protected void onDraw(Canvas pCanvas) {
super.onDraw(pCanvas);
Log.d("LimitIndicator", "OnDraw called");
Log.d("Measured Spec Width", mCenterX + "");
Log.d("Measured Spec Height", mCenterY + "");
pCanvas.drawCircle(mCenterX, mCenterY, mOuterCircleRadius, mDialPaint);
pCanvas.drawCircle(mCenterX, mCenterY, (float) (mOuterCircleRadius - mBorderWidth + 1) , mInnerCirclePaint);
pCanvas.drawText(mTitleText, mCenterX, mCenterY + 5, mTextPaint);
pCanvas.drawArc(mBorderBounds, mStartAngle, mSweepAngle, false, mBorderPaint);
if (mSweepAngle < mTotalProgressInDegrees) {
mSweepAngle+=3;
mBorderPaint.setStrokeWidth(mBorderWidth++);
invalidate();
}
}
#Override
protected void onLayout(boolean pChanged, int pLeft, int pTop, int pRight, int pBottom) {
Log.d("LimitIndicator", "OnLayout called");
for (int i = 0; i < getChildCount(); i++) {
getChildAt(i).layout(0, 0, pRight, pBottom);
}
}
#Override
protected void onSizeChanged(int pW, int pH, int pOldw, int pOldh) {
super.onSizeChanged(pW, pH, pOldw, pOldh);
Log.d("LimitIndicator", "OnSizeChanged called");
float xPad = (getPaddingLeft() + getPaddingRight());
float yPad = (getPaddingTop() + getPaddingBottom());
// To draw Circle in the middle
mCenterX = (float) ((pW - xPad) * 0.5);
mCenterY = (float) ((pH - yPad) * 0.5);
// This (mBorderBounds.bottom needs to be fixed. Width &
// Height should be equal in order
// to create a perfect circle. Otherwise an
// Oval will be created! :P
// Bounds for creating an arc
mHalfOfBorderWidth = (float) (mBorderWidth * 0.5);
mBorderBounds.right = mCenterX + mOuterCircleRadius - mHalfOfBorderWidth;
mBorderBounds.left = mCenterX - mOuterCircleRadius + mHalfOfBorderWidth;
mBorderBounds.top = mCenterY - mOuterCircleRadius + mHalfOfBorderWidth;
mBorderBounds.bottom = mCenterY + mOuterCircleRadius - mHalfOfBorderWidth;
}
// =========================================================================================================
/**
* Start the progress/animation. Use this method to start the animated view.
*/
public void startProgress() {
if (mTotalProgress >= 0) {
float progressInDegrees = mTotalProgress;
mTotalProgressInDegrees = (int) (progressInDegrees/100 * 360);
invalidate();
}
}
#Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent pEvent) {
return super.dispatchPopulateAccessibilityEvent(pEvent);
}
// =========================================================================================================
// Getters && Setters!
/**
* #return the dialRadius
*/
public float getDialRadius() {
return mOuterCircleRadius;
}
/**
* #param pDialRadius
* the dialRadius to set
*/
public void setDialRadius(float pDialRadius) {
mOuterCircleRadius = pDialRadius;
}
/**
* #return the textSize
*/
public float getTextSize() {
return mTextSize;
}
/**
* #param pTextSize the textSize to set
*/
public void setTextSize(float pTextSize) {
mTextSize = pTextSize;
}
/**
* #return the textColor
*/
public int getTextColor() {
return mTextColor;
}
/**
* #param pTextColor the textColor to set
*/
public void setTextColor(int pTextColor) {
mTextColor = pTextColor;
}
/**
* #return the borderColor
*/
public int getBorderColor() {
return mBorderColor;
}
/**
* #param pBorderColor the borderColor to set
*/
public void setBorderColor(int pBorderColor) {
mBorderColor = pBorderColor;
}
/**
* #return the innerCircleColor
*/
public int getInnerCircleColor() {
return mInnerCircleColor;
}
/**
* #param pInnerCircleColor the innerCircleColor to set
*/
public void setInnerCircleColor(int pInnerCircleColor) {
mInnerCircleColor = pInnerCircleColor;
}
/**
* #return the titleText
*/
public String getTitleText() {
return mTitleText;
}
/**
* #param pTitleText the titleText to set
*/
public void setTitleText(String pTitleText) {
mTitleText = pTitleText;
}
/**
* #return the outerCircleRadius
*/
public float getOuterCircleRadius() {
return mOuterCircleRadius;
}
/**
* #param pOuterCircleRadius the outerCircleRadius to set
*/
public void setOuterCircleRadius(float pOuterCircleRadius) {
mOuterCircleRadius = pOuterCircleRadius;
}
/**
* #return the borderWidth
*/
public float getBorderWidth() {
return mBorderWidth;
}
/**
* #param pBorderWidth the borderWidth to set
*/
public void setBorderWidth(float pBorderWidth) {
mBorderWidth = pBorderWidth;
}
/**
* #return the totalProgress
*/
public int getTotalProgress() {
return mTotalProgress;
}
/**
* #param pTotalProgress the totalProgress to set
*/
public void setTotalProgress(int pTotalProgress) {
mTotalProgress = pTotalProgress;
}
}
EDIT
#Override
public boolean onTouchEvent(MotionEvent pEvent) {
double x = pEvent.getX();
double y = pEvent.getY();
double x1 = x - mCenterX;
double y1 = y - mCenterY;
double distance = Math.sqrt(x1*x1 + y1*y1);
RectF topBoundingRect = new RectF(mCenterX - mOuterCircleRadius, mCenterY - mOuterCircleRadius, mCenterX + mOuterCircleRadius, mCenterY);
if (Math.abs(distance - mOuterCircleRadius) <= MAX_TOUCH_TOLERANCE && topBoundingRect.contains((float) x, (float) y)) {
// the user is touching the arc. Which arc is tapped? How do I know that?
}
return true;
}
I won't post code for this, since I'm not completely comfortable working with Java UIs, but the math behind what you're describing shouldn't be too hard.
To make sure that I understand what you're doing: you have a circular arc defined by some center point (x0, y0), a radius r, a start angle θ0, and an end angle θ1. You then want to take a test point (x, y) and determine whether the user clicked on the circle.
This problem is a lot easier to solve if we translate everything back to the origin, since trigonometry is always easier relative to the origin. So let's let
x' = x - x0
y' = y - y0
Now that you have x' and y', we can determine how far away it is from the center of the circle by computing
dist = √(x'2 + y'2)
If this value isn't close to the radius r, then there's no way that the point clicked is anywhere near the arc. Since the arc mathematically is infinitely small, you probably want to set up some "tolerance" for when the user clicks on the arc. You could, for example, define some constant TOLERANCE and then assume the user is clicking on the circumference of the circle if
|dist - r| ≤ TOLERANCE
Now, this assumes that the arc is just the border of the circle. If you are drawing a filled-in circular arc, you can instead just check whether
dist ≤ r + TOLERANCE
This checks whether the point is inside the circle at all.
Now, at this point you can check whether the point is in/inside the circle at all. The next question is whether they clicked on a part of the circle that's part of the arc. To do this, you can compute the angle θ at which the the point is relative to the center of the circle by using Math.atan2 and computing Math.atan2(y', x'). This gives you back an angle θ (in radians). You can then check whether θ0 ≤ θ ≤ θ1, which will then tell you if they clicked on the part of the circle you care about.
In short:
Compute x' and y' from x, y, x0, and y0.
Compute dist from x' and y'.
Determine whether they hit the circle / circumference by using the above math.
Use Math.atan2 to get the angle θ
See if θ is in the range you want.
Hope this helps!

Why is the class CanvasPane not included in the Java API?

** Why is the class CanvasPane not included in the Java API?.
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
/**
* Class Canvas - a class to allow for simple graphical
* drawing on a canvas.
*
* #author Michael Kolling (mik)
* #author Bruce Quig
*
* #version 2008.03.30
*/
public class Canvas
{
private JFrame frame;
private CanvasPane canvas;
private Graphics2D graphic;
private Color backgroundColor;
private Image canvasImage;
/**
* Create a Canvas with default height, width and background color
* (300, 300, white)
* #param title title to appear in Canvas Frame
*/
public Canvas(String title)
{
this(title, 300, 300, Color.white);
}
/**
* Create a Canvas with default background color (white).
* #param title title to appear in Canvas Frame
* #param width the desired width for the canvas
* #param height the desired height for the canvas
*/
public Canvas(String title, int width, int height)
{
this(title, width, height, Color.white);
}
/**
* Create a Canvas.
* #param title title to appear in Canvas Frame
* #param width the desired width for the canvas
* #param height the desired height for the canvas
* #param bgClour the desired background color of the canvas
*/
public Canvas(String title, int width, int height, Color bgColor)
{
frame = new JFrame();
canvas = new CanvasPane();
frame.setContentPane(canvas);
frame.setTitle(title);
canvas.setPreferredSize(new Dimension(width, height));
backgroundColor = bgColor;
frame.pack();
}
/**
* Set the canvas visibility and brings canvas to the front of screen
* when made visible. This method can also be used to bring an already
* visible canvas to the front of other windows.
* #param visible boolean value representing the desired visibility of
* the canvas (true or false)
*/
public void setVisible(boolean visible)
{
if(graphic == null) {
// first time: instantiate the offscreen image and fill it with
// the background color
Dimension size = canvas.getSize();
canvasImage = canvas.createImage(size.width, size.height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.setColor(backgroundColor);
graphic.fillRect(0, 0, size.width, size.height);
graphic.setColor(Color.black);
}
frame.setVisible(true);
}
/**
* Provide information on visibility of the Canvas.
* #return true if canvas is visible, false otherwise
*/
public boolean isVisible()
{
return frame.isVisible();
}
/**
* Draw the outline of a given shape onto the canvas.
* #param shape the shape object to be drawn on the canvas
*/
public void draw(Shape shape)
{
graphic.draw(shape);
canvas.repaint();
}
/**
* Fill the internal dimensions of a given shape with the current
* foreground color of the canvas.
* #param shape the shape object to be filled
*/
public void fill(Shape shape)
{
graphic.fill(shape);
canvas.repaint();
}
/**
* Fill the internal dimensions of the given circle with the current
* foreground color of the canvas.
*/
public void fillCircle(int xPos, int yPos, int diameter)
{
Ellipse2D.Double circle = new Ellipse2D.Double(xPos, yPos, diameter, diameter);
fill(circle);
}
/**
* Fill the internal dimensions of the given rectangle with the current
* foreground color of the canvas. This is a convenience method. A similar
* effect can be achieved with the "fill" method.
*/
public void fillRectangle(int xPos, int yPos, int width, int height)
{
fill(new Rectangle(xPos, yPos, width, height));
}
/**
* Erase the whole canvas.
*/
public void erase()
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
Dimension size = canvas.getSize();
graphic.fill(new Rectangle(0, 0, size.width, size.height));
graphic.setColor(original);
canvas.repaint();
}
/**
* Erase the internal dimensions of the given circle. This is a
* convenience method. A similar effect can be achieved with
* the "erase" method.
*/
public void eraseCircle(int xPos, int yPos, int diameter)
{
Ellipse2D.Double circle = new Ellipse2D.Double(xPos, yPos, diameter, diameter);
erase(circle);
}
/**
* Erase the internal dimensions of the given rectangle. This is a
* convenience method. A similar effect can be achieved with
* the "erase" method.
*/
public void eraseRectangle(int xPos, int yPos, int width, int height)
{
erase(new Rectangle(xPos, yPos, width, height));
}
/**
* Erase a given shape's interior on the screen.
* #param shape the shape object to be erased
*/
public void erase(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
graphic.fill(shape); // erase by filling background color
graphic.setColor(original);
canvas.repaint();
}
/**
* Erases a given shape's outline on the screen.
* #param shape the shape object to be erased
*/
public void eraseOutline(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
graphic.draw(shape); // erase by drawing background color
graphic.setColor(original);
canvas.repaint();
}
/**
* Draws an image onto the canvas.
* #param image the Image object to be displayed
* #param x x co-ordinate for Image placement
* #param y y co-ordinate for Image placement
* #return returns boolean value representing whether the image was
* completely loaded
*/
public boolean drawImage(Image image, int x, int y)
{
boolean result = graphic.drawImage(image, x, y, null);
canvas.repaint();
return result;
}
/**
* Draws a String on the Canvas.
* #param text the String to be displayed
* #param x x co-ordinate for text placement
* #param y y co-ordinate for text placement
*/
public void drawString(String text, int x, int y)
{
graphic.drawString(text, x, y);
canvas.repaint();
}
/**
* Erases a String on the Canvas.
* #param text the String to be displayed
* #param x x co-ordinate for text placement
* #param y y co-ordinate for text placement
*/
public void eraseString(String text, int x, int y)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
graphic.drawString(text, x, y);
graphic.setColor(original);
canvas.repaint();
}
/**
* Draws a line on the Canvas.
* #param x1 x co-ordinate of start of line
* #param y1 y co-ordinate of start of line
* #param x2 x co-ordinate of end of line
* #param y2 y co-ordinate of end of line
*/
public void drawLine(int x1, int y1, int x2, int y2)
{
graphic.drawLine(x1, y1, x2, y2);
canvas.repaint();
}
/**
* Sets the foreground color of the Canvas.
* #param newColor the new color for the foreground of the Canvas
*/
public void setForegroundColor(Color newColor)
{
graphic.setColor(newColor);
}
/**
* Returns the current color of the foreground.
* #return the color of the foreground of the Canvas
*/
public Color getForegroundColor()
{
return graphic.getColor();
}
/**
* Sets the background color of the Canvas.
* #param newColor the new color for the background of the Canvas
*/
public void setBackgroundColor(Color newColor)
{
backgroundColor = newColor;
graphic.setBackground(newColor);
}
/**
* Returns the current color of the background
* #return the color of the background of the Canvas
*/
public Color getBackgroundColor()
{
return backgroundColor;
}
/**
* changes the current Font used on the Canvas
* #param newFont new font to be used for String output
*/
public void setFont(Font newFont)
{
graphic.setFont(newFont);
}
/**
* Returns the current font of the canvas.
* #return the font currently in use
**/
public Font getFont()
{
return graphic.getFont();
}
/**
* Sets the size of the canvas.
* #param width new width
* #param height new height
*/
public void setSize(int width, int height)
{
canvas.setPreferredSize(new Dimension(width, height));
Image oldImage = canvasImage;
canvasImage = canvas.createImage(width, height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.drawImage(oldImage, 0, 0, null);
frame.pack();
}
/**
* Returns the size of the canvas.
* #return The current dimension of the canvas
*/
public Dimension getSize()
{
return canvas.getSize();
}
/**
* Waits for a specified number of milliseconds before finishing.
* This provides an easy way to specify a small delay which can be
* used when producing animations.
* #param milliseconds the number
*/
public void wait(int milliseconds)
{
try
{
Thread.sleep(milliseconds);
}
catch (InterruptedException e)
{
// ignoring exception at the moment
}
}
/************************************************************************
* Inner class CanvasPane - the actual canvas component contained in the
* Canvas frame. This is essentially a JPanel with added capability to
* refresh the image drawn on it.
*/
private class CanvasPane extends JPanel
{
public void paint(Graphics g)
{
g.drawImage(canvasImage, 0, 0, null);
}
}
}
Why it should be? I mean its a BlueJ extension class, AFAIK. Similar questions may come to the mind regarding StringUtils, or NumberUtils. IMHO, these two really qualifies to be there in the original Java API. :)
One huge reason is that it has one of the worst named methods I have ever seen in a Java class:
public void wait(int milliseconds)
Try calling wait(100) on it and watch it work without synchronisation and obviously do something completely different from java.lang.Object.wait(long). This would be a nightmare to do in production.
What on earth is such a method doing in a class named Canvas?

Categories