Question

Java Painter Class This is the class that will contain main. Main will create a new...

Java

Painter Class

This is the class that will contain main. Main will create a new Painter object - and this is the only thing it will do. Most of the work is done in Painter’s constructor.

The Painter class should extend JFrame in its constructor.  Recall that you will want to set its size and the default close operation. You will also want to create an overall holder JPanel to add the various components to. It is this JPanel that will be set as the content pane of the JFrame. Next create 2 plain JPanels, one to hold the shape selector buttons and one to hold the color selector buttons. You do not need to extend JPanel to create these JPanel objects since you don't need to change (override) the default painting behavior of JPanel. You only need to create new JPanels and add buttons to them. Each of the shape selector buttons should be a JButton with some specific text ("line" or "circle"). Each of the color selector buttons should be a JButton with no text, but with a specific backgroundColor (i.e. set the backgroundColor of the JButton). Once you have created all 5 buttons, add them to their respective holder panels.  You will want to use GridLayouts for both your JPanels.  The following gets you started on this:

JPanel holder = new JPanel();
holder.setLayout(new BorderLayout());

// Create the paints

JPanel leftPanel = new JPanel();
leftPanel.setLayout(new GridLayout(3, 1)); // 3 by 1

// add red paint button
JButton redPaint = new JButton();
redPaint.setBackground(Color.RED);
redPaint.setOpaque(true);
redPaint.setBorderPainted(false);
leftPanel.add(redPaint);  // Added in next open cell in the grid

// similar for green and blue

// add the panels to the overall panel, holder
// note that holder's layout should be set to BorderLayout
p.add(leftPanel, BorderLayout.WEST);

// use similar code to add topPanel buttons to the NORTH region
// omit the center panel for now
// after finishing the PaintingPanel class (described later) add a
// new object of this class as the CENTER panel

// And later you will add the chat panel to the SOUTH

// Lastly, connect the holder to the JFrame
setContentPane(holder);

// And make it visible to layout all the components on the screen
setVisible(true)

Test your program by running your Painter class after completing this part of the assignment.  It should “look” like the completed program (without the chat panel) – but won’t do anything until you modify Painter as described later and complete the following classes.

PaintingPrimitive Class

The painter program has to be able to handle drawing lines and circles. So, you will need a Line class and a Circle class.  However, before you code a line class and a circle class, you should think about possible extensions to this drawing program.

One can image have many more primitives (e.g. polygons, squares, free-form, etc). Because of this, you should design the software to be easily extended to handle new primitives. So, we should create an abstract primitive class that sits above all the concrete primitives. It should contain all the information that would be duplicated in each primitive, such as the color.

So now go ahead and make a class called PaintingPrimitive. It needs to be an abstract class. It should contain a single instance variable to hold the Color information. It needs to have a single constructor that initializes this color information based on what is passed to it. And it needs to have a method that allows the primitive to be drawn on a graphics object. We are going to implement this draw method in a unique way (described below).

To implement the draw method, we need to think about what goes on when a primitive (like a Line) is drawn. First the color needs to be set to the color of the primitive. Second the actual geometry of the primitive needs to be drawn. Since the color setting is the same for every primitive (called invariant code) this will be done in the PaintingPrimitive class. The geometry of the drawing is dependent on the particular primitive (called variant code).  In addition we will allow a user to drag the mouse to locate and size the object.  So, the best way to code this is to use the Template Design Pattern.  This is the additional code to add to PaintingPrimitive:

//This is an example of the Template Design Pattern

public final void draw(Graphics g) {
    g.setColor(this.color);
    drawGeometry(g);
}

protected abstract void drawGeometry(Graphics g);

The draw method is called the Template Method because it contains a template of the steps involved in drawing (1. color setting, 2. drawing geometry). The drawGeometry(g) method is a Hook to requiring subclasses to provide their own versions of the geometry drawing. Note that this Hook exists in the abstract PaintingPrimitive class as an abstract method. This implies that any class that subclasses PaintingPrimitive will have to provide their own drawGeometry(g) method that does the correct thing for the particular type of geometry in question. Note that the Hook method is protected. This means that client code can only call them through the Template Method. Also note that the Template Method is final. That means that subclasses are not allowed to override this method, bypassing the template steps. Subclasses are only allowed to provide concrete implementations for the Hooks provided by the Template Method. Implement your code using this design pattern.

Line and Circle Classes

The painter program has to be able to handle drawing lines and circles. So, you will need a Line class and a Circle class. These classes should store the basic information necessary to represent lines (starting and ending Points) and circles (center Point and a point named radiusPoint).  Use the java.awt.Point class to create two dimensional Point objects storing your points.  Additionally, these primitives should be able draw themselves on a graphics object. And since the lines/circles can be drawn in different colors, you will also be keeping the color information with the primitive.  

These will have constructors that take in all the relevant information for the shape in question.  The constructors should have the proper super call to pass the color information upwards to PaintingPrimitive.

Circle and Line will have drawGeometry and size methods that do the actual drawing on the Graphics object.  For example, Circle will have this code:

public void drawGeometry(Graphics g) {
            int radius = (int) Math.abs(center.distance(radiusPoint));
            g.drawOval(center.x - radius, center.y - radius, radius*2, radius*2);           
}

Note that we needed to do some conversions to draw the oval correctly since our center point is to be at the center of the circle, while the oval's first two x,y parameters are the upper left corner of a box containing the oval.

Line’s drawGeometry will use the g.drawLine method instead of drawOval.

PaintingPanel Class

Next you are to create a class called PaintingPanel that extends JPanel (since we need to change how it draws itself) and will be the center canvas you will paint on.  It needs to store an ArrayList of things to draw. However, there are multiple types of primitives it can draw: Lines and Circles for now. So, when you code PaintingPanel you need to work in terms of an ArrayList of generic PaintingPrimitives. Go ahead and add this ArrayList as well as an addPrimitive method that allows the user to add a new primitive to the panel. It needs to have a default constructor setting the panel’s background color to WHITE.

You will also have to override the paintComponent method.

public void paintComponent(Graphics g)

The first line of code should be a call chaining to the super.paintComponent(g) method to initially paint the panel -- this will make sure, among other things, that the background gets repainted. You will then draw the contents of all of the objects stored in your ArrayList.  You must recreate the entire contents of the window in this method (e.g. in case the window was minimized and then brought back).  Also note that you are not to pull the Point information out of PaintingPrimitive and do the actual drawing in this class – it should pass the Graphics object to each PaintingPrimitive in turn to have it draw its contents on the given Graphics.

public void addPrimitive(PaintingPrimitive obj) {
            this.primitives.add(obj);
}

public void paintComponent(Graphics g) {
            super.paintComponent(g);
            for(PaintingPrimitive obj : primitives) {  // I named my ArrayList primitives -- could also use a standard for loop if you wish
                        obj.draw(g);
            }
}

Finishing the Painter Class

Note: your main method can easily get lost in all of the methods in Painter – yet it’s the starting point for the entire program.  Make it easier to find by making this the last method in the class.

Now it is time to put all the GUI pieces together. We have a JPanel holding the shape selectors. We have a JPanel holding the color selectors. And we can create a PaintingPanel as our third JPanel. Then set the center pane of the overall JPanel to be this last JPanel.

Now we have our GUI built. You should be able to run the code and see it appear on the screen. However, there is no behavior yet. So now it is time to add the handlers (listeners) for the buttons and painting panel. Add an actionPerformed listener for each of the 5 buttons. Then add Listener interfaces to the painting panel. You can do this in a number of way, but I’m going to suggest making the Painter class be the ActionListener, MouseListener, and MouseMotionListener (i.e. it will need to implement 3 interfaces) and using “this” as the listener as I think this will be easiest to code, but the choice is up to you.

The only thing left to do is to fill in the code for the event handlers. The 5 buttons control which color is picked and which primitive is picked. All that is necessary are a two instance variables to store this information and code in the handler to set them.  Note that if you went with my suggestion for using the Painter class as the listener, then all 5 buttons will go to the same actionPerformed handler.  Then, you should provide an action command for each button and use that to control a large if/else statement in your handler. For example:

redPaint.setActionCommand("red");
and then you can use the getActionCommand() method of the ActionEvent in the actionPerformed method.

The center JPanel’s mouse events are a bit harder, but not much. A mousePressed event occurs when the user presses the mouse button down and a mouseReleased event occurs when the user releases the mouse button (these are the only event delegates you will add code to). The easiest approach is to have the painter draw the line (or circle) after the mouse has been released. Thus, in the released section you need to create the Line or Circle and add it to the PaintingPanel. Note that in order to create these primitives you also need to remember the starting location where the mouse was originally pressed. So in the pressed section you need to record that information in a Painter class instance variable.

The above type of painting is all that is required for this assignment.

0 0
Add a comment Improve this question Transcribed image text
Answer #1

Program Files:

Circle.java

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;

public class Circle extends PaintingPrimitive {

protected Color colours;
protected Point topLeft;
protected Point bottomRight;

public Circle(Point topLeft, Point bottomRight, Color colours) {
super(colours);
this.topLeft = topLeft;
this.bottomRight = bottomRight;

}

public void drawGeometry(Graphics g) {
int radius = (int) ((Math.abs(topLeft.distance(bottomRight))));

  
if ((topLeft.y > bottomRight.y) && (topLeft.x < bottomRight.x)) {
g.drawOval(topLeft.x, bottomRight.y, radius, radius);
} else if ((topLeft.y < bottomRight.y) && (topLeft.x >bottomRight.x)) {
g.drawOval(bottomRight.x, topLeft.y, radius, radius);
} else if (topLeft.y < bottomRight.y) {
g.drawOval(topLeft.x, topLeft.y, radius, radius);
} else if (topLeft.y > bottomRight.y) {
g.drawOval(bottomRight.x, bottomRight.y, radius, radius);
}
}
}

Line.java

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;

public class Line extends PaintingPrimitive{

protected Color colours;
protected Point topLeft;
protected Point bottomRight;

public Line(Point topLeft, Point bottomRight, Color colours) {
super(colours);
this.topLeft = topLeft;
this.bottomRight = bottomRight;

}

public void drawGeometry(Graphics g) {
//int radius = (int) ((Math.abs(topLeft.distance(bottomRight))) / 2);

g.drawLine(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
}
}

Painter.java

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Painter implements ActionListener {

private boolean circleSelected = false;
private boolean lineSelected = false;
private boolean redSelected = false;
private boolean greenSelected = false;
private boolean blueSelected = false;
private Point mousePoint1 = null;
private Point mousePoint2 = null;
private Color colours = null;

public Painter() {

// MAIN JFRAME
JFrame f = new JFrame();
f.setSize(new Dimension(500, 500));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// ENCOMPASSING PANEL
JPanel p = new JPanel();
p.setBackground(Color.WHITE);
p.setLayout(new BorderLayout());

// LEFT
JPanel leftPanel = new JPanel();
leftPanel.setLayout(new GridLayout(3, 1));

// RED
JButton redPaint = new JButton();
redPaint.setBackground(Color.RED);
leftPanel.add(redPaint);

// GREEN
JButton greenPaint = new JButton();
greenPaint.setBackground(Color.GREEN);
leftPanel.add(greenPaint);

// BLUE
JButton bluePaint = new JButton();
bluePaint.setBackground(Color.BLUE);
leftPanel.add(bluePaint);

p.add(leftPanel, BorderLayout.WEST);

// NORTH
JPanel topPanel = new JPanel();
topPanel.setLayout(new GridLayout(1, 2));

// LINE
JButton lineButton = new JButton();
lineButton.setText("Line");
topPanel.add(lineButton);

// CIRCLE
JButton circleButton = new JButton();
circleButton.setText("Circle");
topPanel.add(circleButton);

p.add(topPanel, BorderLayout.NORTH);

final PaintingPanel pp = new PaintingPanel();
p.add(pp, BorderLayout.CENTER);

// ACTION BUTTONS
circleButton.setActionCommand("CIRCLE");
circleButton.addActionListener(this);
lineButton.setActionCommand("LINE");
lineButton.addActionListener(this);
redPaint.setActionCommand("RED");
redPaint.addActionListener(this);
greenPaint.setActionCommand("GREEN");
greenPaint.addActionListener(this);
bluePaint.setActionCommand("BLUE");
bluePaint.addActionListener(this);

// ACTION MOUSE

pp.addMouseListener(new MouseListener() {

@Override
public void mouseClicked(MouseEvent e) {
if (mousePoint1 != null) {
mousePoint2 = e.getPoint();

if (redSelected) {
colours = Color.RED;
} else if (greenSelected) {
colours = Color.GREEN;
} else if (blueSelected) {
colours = Color.BLUE;
}
if (circleSelected) {
pp.addPrimitive(new Circle(mousePoint1, mousePoint2, colours));
} else if (lineSelected) {
pp.addPrimitive(new Line(mousePoint1, mousePoint2, colours));
}
mousePoint1 = null;
mousePoint2 = null;

} else {

mousePoint1 = e.getPoint();
}
  
pp.repaint();
}

@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub

}

@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub

}

@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub

}

@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub

}

});

f.setContentPane(p);
f.setVisible(true);
}

public static void main(String[] args) {

new Painter();

}

public void actionPerformed(ActionEvent arg0) {

if (arg0.getActionCommand().equals("CIRCLE")) {
circleSelected = true;
lineSelected = false;
} else if (arg0.getActionCommand().equals("LINE")) {
lineSelected = true;
circleSelected = false;
} else if (arg0.getActionCommand().equals("RED")) {
redSelected = true;
greenSelected = false;
blueSelected = false;
} else if (arg0.getActionCommand().equals("GREEN")) {
redSelected = false;
greenSelected = true;
blueSelected = false;
} else if (arg0.getActionCommand().equals("BLUE")) {
redSelected = false;
greenSelected = false;
blueSelected = true;
}

}

}

PaintingPanel.java

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;

import javax.swing.JPanel;

@SuppressWarnings("serial")
public class PaintingPanel extends JPanel {

protected ArrayList<PaintingPrimitive> ppal;

public PaintingPanel() {

setBackground(Color.WHITE);
  
ppal = new ArrayList<PaintingPrimitive>(10);

}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);

for (PaintingPrimitive obj : ppal) {
obj.draw(g);
}
}

public void addPrimitive(PaintingPrimitive obj) {
this.ppal.add(obj);
}

}

PaintingPrimitive.java

import java.awt.Color;
import java.awt.Graphics;

public abstract class PaintingPrimitive {

protected Color colours;

public PaintingPrimitive(Color colours){
this.colours = colours;
}

public final void draw(Graphics g) {
g.setColor(this.colours);
drawGeometry(g);
}

protected abstract void drawGeometry(Graphics g);

}

Hope this helps!

Please let me know if any changes needed.

Thank you!

Add a comment
Know the answer?
Add Answer to:
Java Painter Class This is the class that will contain main. Main will create a new...
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for? Ask your own homework help question. Our experts will answer your question WITHIN MINUTES for Free.
Similar Homework Help Questions
  • In Java Swing, in my ButtonHandler class, I need to have 2 different showDialog messages show...

    In Java Swing, in my ButtonHandler class, I need to have 2 different showDialog messages show when my acceptbutton1 is pressed. One message is if the mouse HAS been dragged. One is if the mouse HAS NOT been dragged. /// I tried to make the Points class or the Mouse Dragged function return a boolean of true, so that I could construct an IF/THEN statement for the showDialog messages, but my boolean value was never accepted by ButtonHandler. *************************ButtonHandler class************************************...

  • create a java class with the name Brick class: For this part of the assignment, you...

    create a java class with the name Brick class: For this part of the assignment, you will create a class that allows you to specify a colored brick that is capable of drawing itself given a specified Graphics object. Note that this is a regular Java class and does not extend the JApplet class. Your class should a constructor with the following signature: Identifier: Brick(int xPosition, int yPosition, int width, int height, Color color) Parameters: xPosition – an int representing...

  • Java program GCompound Practice Exercise CS141 Assignment Write a class that represents a digital snowman. Your...

    Java program GCompound Practice Exercise CS141 Assignment Write a class that represents a digital snowman. Your class should follow these guidelines: 1. Store the following private class variables bodyColor of type Color b. int x, int y for the upper left corner Graphics g. a. C. 2. Create two different constructor methods a. A (int x, int y, Graphics myG) parameter constructor that makes the snowman a light gray color by default and makes x and y the upper left...

  • Need help writing Java code for this question. CircleFrame class is provided below. what happen after...

    Need help writing Java code for this question. CircleFrame class is provided below. what happen after u add the code and follow the requirement? It would be nice to be able to directly tell the model to go into wait mode in the same way that the model's notify method is called. (i.e. notify is called directly on the model, whereas wait is called indirectly through the suspended attribute.) Try altering the the actionPerformed method of the SliderListener innner class...

  • JAVA problem: Upgrade and extend the previous programs Draw.java and DrawCanvas.java used in the class to...

    JAVA problem: Upgrade and extend the previous programs Draw.java and DrawCanvas.java used in the class to maintain a list of shapes drawn as follows: Replace and upgrade all the AWT components used in the programs to the corresponding Swing components, including Frame, Button, Label, Choice, and Panel. Add a JList to the left of the canvas to record and display the list of shapes that have been drawn on the canvas. Each entry in the list should contain the name...

  • Please use Java to solve this quesition. Thx. Lab14 10:30 Write a program similar to the...

    Please use Java to solve this quesition. Thx. Lab14 10:30 Write a program similar to the following figure, which allow user to add name and draw the added names in the center part of the frame. ArrayList and GUI drawing will be used 1) Create your customized Jframe 2) Fields that you need: IButton, JTextField, DrawPanel Lab 15 of Summer 17 3) Create components and panel Tom Hanks 4) Add components to the panel Frank Jim 5) Draw your panel...

  • I am getting this Error can you please fix my Java code. import java.awt.Dialog; import java.awt.Label;...

    I am getting this Error can you please fix my Java code. import java.awt.Dialog; import java.awt.Label; import java.awt.TextArea; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class Fall_2017 {    public TextArea courseInput;    public Label textAreaLabel;    public JButton addData;    public Dialog confirmDialog;    HashMap<Integer, ArrayList<String>> students;    public Fall_2017(){    courseInput = new TextArea(20, 40);    textAreaLabel = new Label("Student's data:");    addData = new JButton("Add...

  • MasterMind in Java Activity MasterMind project Create a new Java Application project named MasterMind allowing Netbeans...

    MasterMind in Java Activity MasterMind project Create a new Java Application project named MasterMind allowing Netbeans IDE to create the main class called MasterMind.java MasterMind class Method main() should: Call static method System.out.println() and result in displaying “Welcome to MasterMind!” Call static method JOptionPane.showMessageDialog(arg1, arg2) and result in displaying a message dialog displaying “Let’s Play MasterMind!” Instantiate an instance of class Game() constants Create package Constants class Create class Constants Create constants by declaring them as “public static final”: public...

  • I have currently a functional Java progam with a gui. Its a simple table of contacts...

    I have currently a functional Java progam with a gui. Its a simple table of contacts with 3 buttons: add, remove, and edit. Right now the buttons are in the program but they do not work yet. I need the buttons to actually be able to add, remove, or edit things on the table. Thanks so much. Here is the working code so far: //PersonTableModel.java import java.util.List; import javax.swing.table.AbstractTableModel; public class PersonTableModel extends AbstractTableModel {     private static final int...

  • I mainly need help with the “Mouse Events” & “Command Buttons” sections Sqrt xA2 Cir CircleButton...

    I mainly need help with the “Mouse Events” & “Command Buttons” sections Sqrt xA2 Cir CircleButton Clas:s The graphic circular buttons are created by drawing a filled Circle on a StackPane. So, the pictured GUI uses 9 different StackPanes tor displaying the 9 qraphic buttons. Of course, these CircleButton objects can then be placed on a single GridPane lo achieve the 3x3 layoul (see SimpleCalc class below). Creale a class narned CircleBullon thal exlends the StackPane class. The class should...

ADVERTISEMENT
Free Homework Help App
Download From Google Play
Scan Your Homework
to Get Instant Free Answers
Need Online Homework Help?
Ask a Question
Get Answers For Free
Most questions answered within 3 hours.
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT