patternjavaModerate
Bare bones painter app in Java
Viewed 0 times
bareappjavapainterbones
Problem
See the next iteration: Bare bones painter app in Java - follow-up.
I have this tiny program for drawing:
PaintCanvas.java:
```
package net.coderodde.javapaint;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
/**
* This class implements a GUI component for drawing.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Jun 8, 2016)
*/
public class PaintCanvas extends Canvas {
/**
* The actual image being drawn to.
*/
private final BufferedImage image;
/**
* The graphics context of the above.
*/
private final Graphics2D imageGraphics;
public PaintCanvas(final int width, final int height) {
super();
super.setBounds(0, 0, width, height);
this.image = new BufferedImage(width,
height,
BufferedImage.TYPE_INT_RGB);
this.imageGraphics = this.image.createGraphics();
this.imageGraphics.setColor(Color.WHITE);
this.imageGraphics.fillRect(0, 0, width, height);
this.imageGraphics.setColor(Color.BLACK);
final PaintCanvasMouseListener listener =
new PaintCanvasMouseListener();
this.addMouseListener(listener);
this.addMouseMotionListener(listener);
}
@Override
public void paint(final Graphics g) {
update(g);
}
@Override
public void update(final Graphics g) {
g.drawImage(this.image, 0, 0, null);
}
private class PaintCanvasMouseListener
extends MouseAdapter implements MouseMotionListener {
@Override
public void mouseClicked(final MouseEvent event) {
processEvent(event);
}
@Override
public void mouseDragged(final MouseEvent event) {
proce
I have this tiny program for drawing:
PaintCanvas.java:
```
package net.coderodde.javapaint;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
/**
* This class implements a GUI component for drawing.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Jun 8, 2016)
*/
public class PaintCanvas extends Canvas {
/**
* The actual image being drawn to.
*/
private final BufferedImage image;
/**
* The graphics context of the above.
*/
private final Graphics2D imageGraphics;
public PaintCanvas(final int width, final int height) {
super();
super.setBounds(0, 0, width, height);
this.image = new BufferedImage(width,
height,
BufferedImage.TYPE_INT_RGB);
this.imageGraphics = this.image.createGraphics();
this.imageGraphics.setColor(Color.WHITE);
this.imageGraphics.fillRect(0, 0, width, height);
this.imageGraphics.setColor(Color.BLACK);
final PaintCanvasMouseListener listener =
new PaintCanvasMouseListener();
this.addMouseListener(listener);
this.addMouseMotionListener(listener);
}
@Override
public void paint(final Graphics g) {
update(g);
}
@Override
public void update(final Graphics g) {
g.drawImage(this.image, 0, 0, null);
}
private class PaintCanvasMouseListener
extends MouseAdapter implements MouseMotionListener {
@Override
public void mouseClicked(final MouseEvent event) {
processEvent(event);
}
@Override
public void mouseDragged(final MouseEvent event) {
proce
Solution
A few notes:
-
Is there a reason you aren't using JavaFX? See this answer as
to why you should be using it.
-
Since I mostly rewrote your code, I'll do the best I can to explain all the components of implementing an app in JavaFX:
-
There are a few layers within a JavaFX app; the application, the stage, the scene, and the canvas. I'll let you do more reading on your own about all of those if you wish to learn more, but these are the basic components for creating a GUI.
-
Within the canvas, we add the event handlers to handle all the different mouse events. These are pretty self-explanatory, since you have them in your app as well.
-
Now we have to handle the actual painting on the canvas. Again, you have a similar approach in your code, so I don't have to cover this in depth.
-
Small user-experience quip: don't start the program in the middle of the screen. Often comes across as adware-like.
Final Code:
-
Is there a reason you aren't using JavaFX? See this answer as
to why you should be using it.
-
Since I mostly rewrote your code, I'll do the best I can to explain all the components of implementing an app in JavaFX:
-
There are a few layers within a JavaFX app; the application, the stage, the scene, and the canvas. I'll let you do more reading on your own about all of those if you wish to learn more, but these are the basic components for creating a GUI.
-
Within the canvas, we add the event handlers to handle all the different mouse events. These are pretty self-explanatory, since you have them in your app as well.
-
Now we have to handle the actual painting on the canvas. Again, you have a similar approach in your code, so I don't have to cover this in depth.
-
Small user-experience quip: don't start the program in the middle of the screen. Often comes across as adware-like.
Final Code:
package javafx_drawoncanvas;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class JavaFX_DrawOnCanvas extends Application {
@Override
public void start(Stage primaryStage) {
Canvas canvas = new Canvas(400, 400);
final GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
initDraw(graphicsContext);
canvas.addEventHandler(MouseEvent.MOUSE_PRESSED,
new EventHandler(){
@Override
public void handle(MouseEvent event) {
graphicsContext.beginPath();
graphicsContext.moveTo(event.getX(), event.getY());
graphicsContext.stroke();
}
});
canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED,
new EventHandler(){
@Override
public void handle(MouseEvent event) {
graphicsContext.lineTo(event.getX(), event.getY());
graphicsContext.stroke();
}
});
canvas.addEventHandler(MouseEvent.MOUSE_RELEASED,
new EventHandler(){
@Override
public void handle(MouseEvent event) {
}
});
StackPane root = new StackPane();
root.getChildren().add(canvas);
Scene scene = new Scene(root, 400, 400);
primaryStage.setTitle("Paint");
primaryStage.setScene(scene);
primaryStage.show();
}
private void initDraw(GraphicsContext gc){
double canvasWidth = gc.getCanvas().getWidth();
double canvasHeight = gc.getCanvas().getHeight();
gc.setFill(Color.LIGHTGRAY);
gc.setStroke(Color.BLACK);
gc.setLineWidth(5);
gc.fill();
gc.strokeRect(
0, //x of the upper left corner
0, //y of the upper left corner
canvasWidth, //width of the rectangle
canvasHeight); //height of the rectangle
gc.setFill(Color.RED);
gc.setStroke(Color.BLUE);
gc.setLineWidth(1);
}
public static void main(String... args) {
launch(args);
}
}Code Snippets
package javafx_drawoncanvas;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class JavaFX_DrawOnCanvas extends Application {
@Override
public void start(Stage primaryStage) {
Canvas canvas = new Canvas(400, 400);
final GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
initDraw(graphicsContext);
canvas.addEventHandler(MouseEvent.MOUSE_PRESSED,
new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent event) {
graphicsContext.beginPath();
graphicsContext.moveTo(event.getX(), event.getY());
graphicsContext.stroke();
}
});
canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED,
new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent event) {
graphicsContext.lineTo(event.getX(), event.getY());
graphicsContext.stroke();
}
});
canvas.addEventHandler(MouseEvent.MOUSE_RELEASED,
new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent event) {
}
});
StackPane root = new StackPane();
root.getChildren().add(canvas);
Scene scene = new Scene(root, 400, 400);
primaryStage.setTitle("Paint");
primaryStage.setScene(scene);
primaryStage.show();
}
private void initDraw(GraphicsContext gc){
double canvasWidth = gc.getCanvas().getWidth();
double canvasHeight = gc.getCanvas().getHeight();
gc.setFill(Color.LIGHTGRAY);
gc.setStroke(Color.BLACK);
gc.setLineWidth(5);
gc.fill();
gc.strokeRect(
0, //x of the upper left corner
0, //y of the upper left corner
canvasWidth, //width of the rectangle
canvasHeight); //height of the rectangle
gc.setFill(Color.RED);
gc.setStroke(Color.BLUE);
gc.setLineWidth(1);
}
public static void main(String... args) {
launch(args);
}
}Context
StackExchange Code Review Q#131422, answer score: 10
Revisions (0)
No revisions yet.