I want to make an application in order to draw forms (rectangle, line, square, arrow) like in paint using Java SWT Canvas. I'm using mouse events (Up, Down and move) to get the canvas Y and X position. And i have a button for each form types that get canvas mouse position and draw the selected form using the mouse events. My problem is, when i draw the first form (Circle, square, line) everything works, but when draw the second, the first erase. How can I make the first form stay on drawn after redraw the canvas?
Variables:
private static boolean drag = false;
private Canvas compCanvas;
private Button btnSend, btnAdd,btnFreeHand,btnArrow,btnCircle,btnSquare,btnLine;
private Composite mainPanel;
compCanvas = new Canvas(mainPanel, SWT.NONE);
mouseEvents():
private void mouseEvents(){
compCanvas.addListener(SWT.MouseDown, new Listener(){
public void handleEvent(Event e){
System.out.println("Mouse event on canvas DOWN: X VALUE:"+e.x+"Y VALUE:"+e.y);
startY = e.y;
startX = e.x;
drag = true;
}
});
compCanvas.addListener(SWT.MouseUp, new Listener(){
public void handleEvent(Event e){
System.out.println("Mouse event on canvas UP: X VALUE:"+e.x+"Y VALUE:"+e.y);
endY = e.y;
endX = e.x;
drag = false;
//compCanvas.redraw();
}
});
compCanvas.addListener(SWT.MouseMove, new Listener(){
public void handleEvent(Event e){
System.out.println("Mouse event on canvas MOVE: X VALUE:"+e.x+"Y VALUE:"+e.y);
if(drag){
endY = e.y;
endX = e.x;
compCanvas.redraw();
}
}
});
};
btnSquare.selectionListener() and Declaration:
btnSquare = new Button(compSendAdd, SWT.NONE);
btnSquare.setLayoutData(new RowData(25, 25));
btnSquare.setImage(squareIcon);
btnSquare.addSelectionListener(new SelectionListener(){
private void btnSquare(){
mouseEvents();
//LightweightSystem lws = new LightweightSystem(compCanvas);
compCanvas.addListener(SWT.Paint, new Listener(){
public void handleEvent(Event e){
if(drag){
GC gc = e.gc;
//gc.setAlpha(128);
int minX = Math.min(startX,endX);
int minY = Math.min(startY,endY);
int maxX = Math.max(startX, endX);
int maxY = Math.max(startY, endY);
int width = maxX - minX;
int height = maxY - minY;
gc.fillRectangle(minX, minY,width,height);
}
}
});
}
public void widgetSelected(SelectionEvent event) {
btnSquare();
}
public void widgetDefaultSelected(SelectionEvent event) {
btnSquare();
}
});
By default controls are filled with current background color each time the SWT.Paint listener is called. You need to turn this off.
Do this by specifying the SWT.NO_BACKGROUND style on the Canvas
compCanvas = new Canvas(mainPanel, SWT.NO_BACKGROUND);
You will also need to fill the background the first time the canvas is drawn.
Create class shape with x, y, width, height fields
class Shape {
public int x; // coordiates
public int y;
public int width;
public int heigth;
String type; // "rect" for example
public Shape(int x, int y, int width, int height, String type) {
this.x = x;
this.y = y;
this.width = width;
this.heigth = height;
this.type = type;
}
}
After mouse up store your shape in list according to which button is selected
List<Shape> shapes = new ArrayList<Shape>();
shapes.add(new Shape(x, y, width, height, getType()));
In PainListener You MUST redraw all shapes from your list
for(Shape s: shapes) {
//draw shape s
}
Related
I'm writing a program that displays a circle every time you click the Jpanel. I have it all set up and I want to be able to use the drawCircle method I created in my circle class to draw the circles in the paintComponent method. I'm storing all of the circles created in a linked list. Then I interate through each Circle in the list and try to use the method in my Circle class called drawCircle().
For some reason, if I try to use c1.drawCircle() in a for loop in the My panel class it only draws the last circle that was created. But if I just use g.fillOval(with the correct parameters grabbing the values from the Circle class) in the for loop it works properly and displays all the circles. Why is it doing this and how do I go about using the method in the Circle class properly
I'm unsure what to try right now.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.LinkedList;
public class MouseTest {
private int borderWidth = 20;
private JFrame frame;
private boolean tracking;
private boolean start;
private boolean clearBol;
private int xstart;
private int ystart;
private int xend;
private int yend;
private LinkedList<Circle> circles;
public MouseTest() {
tracking = false;
start = false;
circles = new LinkedList<Circle>();
frame = new JFrame();
frame.setBounds(250, 98, 600, 480);
frame.setTitle("Window number three");
Container cp = frame.getContentPane();
JButton clear = new JButton("Clear");
JToggleButton circleButton = new JToggleButton()("Circles");
JToggleButton drawButton = new JToggleButton("Draw");
ButtonGroup circleOrDraw = new ButtonGroup();
MyPanel pane = new MyPanel();
clear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
clearBol = true;
frame.repaint();
}
});
JPanel top = new JPanel();
top.setLayout(new FlowLayout());
top.add(clear);
circleOrDraw.add(circleButton);
circleOrDraw.add(drawButton);
top.add(circleOrDraw);
cp.add(top, BorderLayout.NORTH);
cp.add(pane, BorderLayout.CENTER);
pane.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
xstart = e.getX();
ystart = e.getY();
start = false;
}
public void mouseReleased(MouseEvent e) {
xend = e.getX();
yend = e.getY();
if (xend < xstart) {
int tmp = xstart;
xstart = xend;
xend = tmp;
}
if (yend < ystart) {
int tmp = ystart;
ystart = yend;
yend = tmp;
}
start = true;
frame.repaint();
}
});
pane.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
if (tracking) {
int x = e.getX();
int y = e.getY();
msg("(" + x + ", " + y + ")");
}
}
});
frame.setVisible(true);
} // constructor
public static void main(String[] arg) {
MouseTest first = new MouseTest();
} // main
public void msg(String s) {
System.out.println(s);
}
public void trackMouse() {
tracking = !tracking;
} // trackMouse
public class Circle extends JPanel {
Graphics g;
int x;
int y;
int r;
Color color;
public Circle(Graphics g, int x, int y, int r) {
this.g = g;
this.x = x;
this.y = y;
this.r = r;
int red = (int) (256 * Math.random());
int green = (int) (256 * Math.random());
int blue = (int) (256 * Math.random());
this.color = new Color(red, green, blue);
}
public void drawCircle() {
int x2 = x - (r / 2);
int y2 = y - (this.r / 2);
g.setColor(color);
g.fillOval(x2, y2, this.r, this.r);
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Color getColor() {
return color;
}
public int getR() {
return r;
}
}
public class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
if (start) {
circles.add(new Circle(g, xend, yend,
(int) ((250 * Math.random() + 4))));
//Area where I'm having issues
for (Circle c1 : circles) {
msg("" + c1.getX());
// this method that I created in the circle class will only draw the first circle
//c1.drawCircle();
int r = c1.getR();
int x = c1.getX();
int y = c1.getY();
g.setColor(c1.getColor());
g.fillOval((c1.getX() - (r / 2)), (c1.getY() - (r / 2)),
r, r); // this will display all the circles
}
int size = circles.size();
msg(size + " Size");
msg("" + circles.getLast().getX());
}
if (clearBol) {
super.paintComponent(g);
circles.clear();
clearBol= false;
}
Thank you!
Most of the structure of your class needs to be changed
Your MyPanel should have a better name to give its functionality, maybe something like DrawingPanel.
The DrawingPanel is then responsible for managing the Circles to be painted. So typically you would just use an ArrayList to hold the Circle information.
Then you would add a method to the class, like addCircle(...) to add the Circle information to the ArrayList and then invoke repaint().
Then in your paintComponent(...) method the first thing you do is invoke super.paintComponent(...) to clear the panel. Then you iterate through the ArrayList and paint all the Circles. There will be no need for the Boolean values to check the state of the class. The ArrayList will either have circles or it won't.
You would also need a method like clearCircles(). This would simply remove all the Circles from the ArrayList and invoke repaint() on itself.
Your Circle class should NOT extend JPanel. It should just be a class that contains the information need to paint the circle: x/y location, size of circle and color of circle.
Now your frame is responsible of displaying your DrawingPanel and the buttons.
When you click the "Clear" button you simply invoke the clearCircles() method of the DrawingPanel.
For your MouseListener you simply invoke the addCircle(...) method of your DrawingPanel once you have all the information needed to create a Circle instance.
For a complete working example that incorporates all these suggestions check out the DrawOnComponent example found in Custom Painting Approaches
I'm relatively new to Java, but I've made a simple paint program that allows the user to draw, change the color and size of the pen, and clear the drawing area.
The user selects a color from the JColorChooser object 'c' and this is handed off to the Color variable 'selected' through c.getColor(). I want to be able to change the transparency of the selected color, but I don't know if there is a way to convert from Color to RGB so that I can use the setColor(r, g, b, a) method. My code is below. I really appreciate any help!
Color selected;
public class ColorTool extends JPanel {
public ColorTool() {
super(new BorderLayout());
b = new JLabel("Pen Color", JLabel.CENTER);
b.setForeground(Color.black);
c = new JColorChooser(b.getForeground());
c.getSelectionModel().addChangeListener(new ColorListener());
add(c, BorderLayout.PAGE_END);
}
}
public DrawPanel() {
setDoubleBuffered(false);
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
for (int i = 0; i <= 100; i++) {
if (PS == i) {
oldX = (int)(e.getX() - Math.ceil(PS/2));
oldY = (int)(e.getY() - Math.ceil(PS/2));
if (graphics != null) {
graphics.setColor(selected);
graphics.fillOval(oldX, oldY, PS, PS);
}
repaint();
oldX = e.getX();
oldY = e.getY();
}
}
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
BasicStroke size = new BasicStroke(PS,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
currentX = e.getX();
currentY = e.getY();
if (graphics != null) {
graphics.setColor(selected);
graphics.setStroke(size);
graphics.drawLine(oldX, oldY, currentX, currentY);
}
repaint();
oldX = currentX;
oldY = currentY;
}
});
}
public class ColorListener implements ChangeListener {
public void stateChanged(ChangeEvent e) {
selected = c.getColor();
}
}
You can access that by calling the method getComponents on the instance of Color.
From the documentation:
public float[] getComponents(float[] compArray)
Returns a float array containing the color and alpha components of the Color, in the ColorSpace of the Color. If compArray is null, an array with length equal to the number of components in the associated ColorSpace plus one is created for the return value. Otherwise, compArray must have at least this length and it is filled in with the components and returned.
Parameters: compArray - an array that this method fills with the color and alpha components of this Color in its ColorSpace and returns
Returns:
the color and alpha components in a float array.
I am tasked with how to paint an arrayList of shapes in java.
I feel i have most of it right, there are two methods i am confused about however
the method in ShapeChooserPanel called public void setPoints(int x, int y)
Since Xs and Ys are arrays, how would i set the x and y values?
And the other is one is the final method in ShapeChooserPanel I cannot find out how to print the Shapes in the array, It should paint the current shape at the place the mouse was clicked.
My code is below
Main class:
import javax.swing.JFrame;
public class Lab2 {
public static void main (String[] args) {
JFrame myFrame = new JFrame("Lab 2");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.add(new ShapeChooserPanel());
myFrame.pack();
myFrame.setVisible(true);
}
}
ShapeChooserPanel class
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.ArrayList;
public class ShapeChooserPanel extends JPanel {
private int currentX;
private int currentY;
private Color currentColor;
private int currentShape;
private JButton clearBtn;
private JRadioButton circle, square, triangle, box;
private DrawingPanel drawingPanel;
private JPanel controlsPanel;
//constants representing shape choice
private final int CIRCLE = 0;
private final int SQUARE = 1;
private final int TRIANGLE = 2;
private final int BOX = 3;
//constant delta used for setting distance between points
private final int DELTA = 25;
private int[] Xs;
private int[] Ys;
//store all the shapes to be painted UNCOMMENT when you have Shape.java defined
ArrayList<Shape> shapes;
public ShapeChooserPanel(){
//provide some default values paints a circle at (10,10) in blue
currentX = 10;
currentY = 10;
Xs = new int[4];//we will use all 4 points for the square, but only the first 3 for the triangle
Ys = new int[4];
setPoints(currentX,currentY);
currentShape = CIRCLE;
currentColor = Color.red;
shapes = new ArrayList<Shape>();
//instantiate the controls panel and set its layout to display everything in a single column
controlsPanel = new JPanel();
controlsPanel.setLayout(new BoxLayout(controlsPanel, BoxLayout.Y_AXIS));
//TODO: add clear button *
// TODO: define radio buttons *
clearBtn = new JButton("Clear");
clearBtn.addActionListener(new ClearListener());
circle = new JRadioButton("Red Circle");
circle.addActionListener(new ShapeListener());
square = new JRadioButton("Cyan Square");
square.addActionListener(new ShapeListener());
triangle = new JRadioButton("Green Triangle");
triangle.addActionListener(new ShapeListener());
box = new JRadioButton("Blue Box");
box.addActionListener(new ShapeListener());
ButtonGroup group = new ButtonGroup();
group.add(clearBtn);
group.add(circle);
group.add(square);
group.add(triangle);
group.add(box);
controlsPanel.add(clearBtn);
controlsPanel.add(circle);
controlsPanel.add(square);
controlsPanel.add(triangle);
controlsPanel.add(box);
//TODO: add radio buttons to group *
//TODO add listeners to radio buttons *
//TODO: add radio buttons to controls panel *
drawingPanel = new DrawingPanel();
drawingPanel.setBorder(BorderFactory.createLineBorder(Color.black));
//TODO: set a border around the drawing panel *
drawingPanel.setPreferredSize(new Dimension(200,200));
drawingPanel.addMouseListener(new PanelListener());
add(drawingPanel);
add(controlsPanel);
setPreferredSize(new Dimension (300,400));
}//end constructor
public void setPoints(int x, int y) {
//TODO: set Xs and Ys *
Xs[0] = x;
Ys[0] = y;
}
private class ClearListener implements ActionListener{
public void actionPerformed(ActionEvent ae){
shapes.removeAll(shapes);
drawingPanel.repaint();
}
}
private class PanelListener implements MouseListener {
public void mouseClicked(MouseEvent me) {
currentX = me.getX();
currentY = me.getY();
//TODO: find coordinates of this mouse click *
//TODO: add a new shape to the shapes list*
shapes.addAll(shapes);
setPoints(currentX, currentY);
//TODO: call setPoints with current x and y values *
drawingPanel.repaint();
}
public void mouseExited(MouseEvent me){}
public void mouseEntered(MouseEvent me){}
public void mouseReleased(MouseEvent me){}
public void mousePressed(MouseEvent me){}
}
//Class to listen for radio button changes
private class ShapeListener implements ActionListener{
public void actionPerformed(ActionEvent me){
//TODO: determine which radio button was clicked *
if(me.getSource() == circle){
currentShape = CIRCLE;
currentColor = Color.red;
}
if(me.getSource() == square){
currentShape = SQUARE;
currentColor = Color.cyan;
}
if(me.getSource() == triangle){
currentShape = TRIANGLE;
currentColor = Color.green;
}
if(me.getSource() == box){
currentShape = BOX;
currentColor = Color.blue;
}
//TODO: set current shape and color *
drawingPanel.repaint();
}
}
private class DrawingPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
//TODO: paint all the shapes in our list
}
}
}
and my Shape class
import java.awt.Color;
public class Shape {
private int x,y;
private int type;
private Color c;
public Shape(int x, int y, int type, Color c) {
this.x = x;
this.y = y;
this.type = type;
this.c = c;
}
public int x(int x) {
return x;
}
public int y(int y) {
return y;
}
public int type(int type) {
return type;
}
public Color c(Color c) {
return c;
}
}
super.paintComponent(g) invokes the paintComponent method from the superclass of JPanel (the JComponent class) to erase whatever is currently drawn on the panel. This is useful for animation, but not for setting color.
I guess you'll have to set the color of the shapes in your Arraylist<Shape> shapes when you will create them, nonetheless it could be helpfull to see the Shape class. Maybe you could create a function changeColor(Color ColorToBeSet) in this shape class and loop through the shapes ArrayList to call it at the end of your ShapeListener
You could...
Define an "abstract" concept of a shape, which has the basic properties (location and size) and which can paint itself...
public abstract class Shape {
private int x, y;
private int width, height;
private Color c;
public Shape(int x, int y, int width, int height, Color c) {
this.x = x;
this.y = y;
this.c = c;
this.width = width;
this.height = height;
}
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Color getColor() {
return c;
}
public abstract void paint(Graphics2D g2d);
}
Then you can implement the individual shapes...
public class Rectangle extends Shape {
public Rectangle(int x, int y, int width, int height, Color c) {
super(x, y, width, height, c);
}
#Override
public void paint(Graphics2D g2d) {
g2d.setColor(getColor());
g2d.drawRect(getX(), getY(), getWidth(), getHeight());
}
}
public class Oval extends Shape {
public Oval(int x, int y, int width, int height, Color c) {
super(x, y, width, height, c);
}
#Override
public void paint(Graphics2D g2d) {
g2d.setColor(getColor());
g2d.drawOval(getX(), getY(), getWidth(), getHeight());
}
}
Then, you can simply call the paint method of each instance of Shape as required...
public class TestPane extends JPanel {
private List<Shape> shapes;
public TestPane() {
shapes = new ArrayList<>(25);
shapes.add(new Rectangle(10, 10, 20, 20, Color.RED));
shapes.add(new Oval(15, 15, 40, 20, Color.RED));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Shape shape : shapes) {
Graphics2D g2d = (Graphics2D) g.create();
shape.paint(g2d);
g2d.dispose();
}
}
}
Right now I am trying to get it so whenever I click inside of the oval that I have painted, and drag the mouse it will move positions by repainting. However, even though the MouseEvents are being detected correctly, the oval image is not updating. I am confused to why that is. Here is the code that deals with the oval, MouseEvents, and updating:
public class DrawOval extends JPanel {
private int size = 50;
private int locX = 0; //vector points
private int locY = 0;
private boolean isPressed = false;
private Shape oval = new Ellipse2D.Double(locX, locY, size, size * 2);
public DrawOval(int size){
this.size = size;
Dimension dims = new Dimension(size, size);
setPreferredSize(dims);
setMaximumSize(dims);
setMinimumSize(dims);
MouseAdapter m = new MouseAdapter(){
public void mouseReleased(MouseEvent e){
isPressed = false;
update(e);
System.out.println("Mouse is released!");
}
public void mousePressed(MouseEvent e){
isPressed = true;
update(e);
System.out.println("Mouse is pressed!");
}
public void mouseDragged(MouseEvent e){
if(isPressed){
update(e);
System.out.println("Mouse is dragged!");
}
}
public void update(MouseEvent e){
System.out.println("X: " + e.getX() + ", Y: " + e.getY());
if(oval.contains(e.getX(), e.getY())){
setX(e.getX()); setY(e.getY());
repaint();
}
//does not update if the mouses click coordinates are outside of the oval
}
};
addMouseListener(m); //for pressing and releasing
addMouseMotionListener(m); //for dragging
}
public void setX(int _x){
this.locX = _x;
}
public void setY(int _y){
this.locY = _y;
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.BLACK);
g2.fill(oval);
}
}
I cannot figure out why it is not updating correctly. I had it partially working before, but it would update all the time, even if where the user clicked was not within the oval.
I think doing setX and setY you forget to update x and y in your oval. You have at least three options:
1) recreate Ellipse2D.Double every time you change this.locX and this.locY.
2) expect that your oval is created with x=0, y=0 once and for all, check mouse event switching to relative coordinates (if(oval.contains(e.getX() - locX, e.getY() - locY)){...}) and draw your oval using AffineTransform by g2.transform(...).
3) Declare oval as Ellipse2D.Double oval = new Ellipse2D.Double(...); and then you can change its x and y directly cause they're public:
oval.x = this.locX;
oval.y = this.locY;
So basically I'm writing a program where the user clicks and drags the mouse to a size he/she wants, and lets go, filling in a rectangle based on the choice from the JComboBox.
What I have implemented is MouseListener and MouseMotionListener to track the location of the mouse, and draw a rectangle based on where the user first clicked, to where it was let go.
When the user clicks and drags (but does not let go), there is a drawRect() but not a fillRect() (as in, the rectangle does not fill - only when the user releases the mouse does the rectangle fill with the color).
This class creates a Rect object that has another part in the constructor, which is the color that is selected (which is determined in the ColorListener class below).
This is where I included my instance variables, and everything is instantiated in the constructor below:
private ArrayList<Rect> rectList;
private Color currentColor;
private Canvas canvas;
private JPanel controlPanel;
private JButton undo, erase;
private JComboBox comboBox;
private int xStart, yStart, xEnd, yEnd;
private Graphics page;
private Point pt = null;
private PointListener pointListener;
private ColorListener colorListener;
public WholePanel()
{
// here we use black to draw a rectangle
currentColor = Color.black;
pointListener = new PointListener();
addMouseListener(pointListener);
addMouseMotionListener(pointListener);
String[] listOfColors = {"black", "red", "blue", "green", "orange"};
comboBox = new JComboBox(listOfColors);
comboBox.setSelectedIndex(0);
rectList = new ArrayList<Rect>();
controlPanel = new JPanel(new GridLayout(1,3));
undo = new JButton("Undo");
erase = new JButton("Erase");
controlPanel.add(comboBox);
controlPanel.add(undo);
controlPanel.add(erase);
undo.addActionListener(new ButtonListener());
erase.addActionListener(new ButtonListener());
canvas = new Canvas();
JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, controlPanel, canvas);
setLayout(new BorderLayout());
add(sp);
}
The Rect class can create a Rect object used later.
public class Rect
{
private int x1, y1, width1, height1;
private Color color1;
public Rect(int x, int y, int width, int height, Color color)
{
x1 = x;
y1 = y;
width1 = width;
height1 = height;
color1 = color;
}
public void draw(Graphics page)
{
page.setColor(color1);
page.drawRect(x1,y1,width1,height1);
}
}
The Canvas class creates the space that allows for drawing of an object.
private class Canvas extends JPanel
{
public void paintComponent(Graphics page)
{
super.paintComponent(page);
setBackground(Color.white);
if (pt != null)
{
Rect rect = new Rect(xStart, yStart, xEnd-xStart, yEnd-yStart, currentColor);
rect.draw(page);
}
}
}
The PointListener class finds all the points that are there, as in where the user clicks, to where the user drags, and also to where the user releases.
private class PointListener implements MouseListener, MouseMotionListener
{
public void mousePressed(MouseEvent event)
{
pt = event.getPoint();
xStart = pt.x;
yStart = pt.y;
}
public void mouseReleased(MouseEvent event)
{
pt = event.getPoint();
if (pt != null)
{
xEnd = pt.x;
yEnd = pt.y;
page.fillRect(xStart, yStart, xEnd-xStart, yEnd-yStart);
}
}
public void mouseClicked(MouseEvent event) {}
public void mouseEntered(MouseEvent event) {}
public void mouseExited(MouseEvent event) {}
public void mouseDragged(MouseEvent event)
{
pt = event.getPoint();
if (pt != null)
{
xEnd = pt.x;
yEnd = pt.y;
Rect rect = new Rect(xStart, yStart, xEnd-xStart, yEnd-yStart, currentColor);
rect.draw(page);
}
repaint();
}
public void mouseMoved(MouseEvent event) {}
}
ColorListener finds the type of object that is selected in the JComboBox determined in the main() method, and sets the currentColor to it (it is put back as the color in the Rect constructor above).
private class ColorListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if (event.getSource().equals("black"))
{
currentColor = Color.black;
comboBox.setSelectedIndex(0);
}
else if (event.getSource().equals("red"))
{
currentColor = Color.red;
comboBox.setSelectedIndex(1);
}
else if (event.getSource().equals("blue"))
{
currentColor = Color.blue;
comboBox.setSelectedIndex(2);
}
else if (event.getSource().equals("green"))
{
currentColor = Color.green;
comboBox.setSelectedIndex(3);
}
else if (event.getSource().equals("orange"))
{
currentColor = Color.orange;
comboBox.setSelectedIndex(4);
}
}
}
So what I am having trouble with is being able to draw it. I don't see any flaws in logic in the program so far above, and nothing is being able to be drawn onto the Canvas (don't worry about the JButtons Undo and Erase, as they are easy to work with with an ArrayList and remove() and clear() and things like that).
Your program should have no Graphics field that is a class field (your page class field). I'm surprised your not seeing a NullPointException with the way you're attempting to use it above in say your Mouse Listener class:
public void mouseReleased(MouseEvent event)
{
pt = event.getPoint();
if (pt != null)
{
xEnd = pt.x;
yEnd = pt.y;
// !!!! don't do this !!!!
page.fillRect(xStart, yStart, xEnd-xStart, yEnd-yStart);
}
}
Instead the Graphics object should only be obtained from the JVM, should only exist within the paintComponent method and should only be used within the same paintComponent method (exceptions being any methods called from with paintComponent that are passed this object and of course a Graphics object obtained from a BufferedImage). The MouseListener/MouseMotionListener should fill in your x-start, y-start, x-end, and y-end variables during mouseDragged, and then on mouseRelease these variables should be used to create a new Rect object that is placed in the rectList, and then repaint called.
Then paintComponent should iterate through rectList, filling each Rect object it finds there.