Reputation: 23
It's a simple Paint-style program based on the use of arrays and arraylists to save the coordinates, sizes, and colors of different points draw on the screen using a JFrame, paintComponent, and various mouse listeners.
I recently fixed a problem where it would spit out an ArrayOutOfBounds error and point to line 34 with the colors array exceeding its limit of 10000. However I need the program to run and the size and color of each point parallel to each other, so each time the program repaints the points, each retains its own size and color variables. Thank you for your input!
import java.util.ArrayList;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;
public class Proj1Panel extends JPanel{
public int SIZE = 5, c = 0, s = 0;
private ArrayList<Point> pointList;
public int[] sizes;
public Color[] colors;
public Proj1Panel(){
pointList = new ArrayList<Point>();
sizes = new int[10000];
colors = new Color[10000];
addMouseListener (new Proj1Listener());
addMouseMotionListener (new Proj1Listener());
addMouseWheelListener (new Proj1Listener());
setBackground(Color.black);
setPreferredSize(new Dimension(300, 200));
}
public void paintComponent(Graphics page){
super.paintComponent(page);
for(Point spot : pointList){
page.setColor(colors[c]);
page.fillRect(spot.x-sizes[pointList.size()], spot.y-sizes[pointList.size()], sizes[pointList.size()]*2, sizes[pointList.size()]*2);
c = 0;
}
repaint();
page.setColor(Color.RED);
page.fillRect(5, 40, 30, 30);
page.setColor(Color.BLUE);
page.fillRect(5, 75, 30, 30);
page.setColor(Color.GREEN);
page.fillRect(5, 110, 30, 30);
page.setColor(Color.WHITE);
page.fillRect(5, 145, 30, 30);
page.setColor(Color.WHITE);
page.drawString("Count: " + pointList.size() + "/10000", 5, 15);
page.drawString("Size: " + SIZE, 5, 30);
}
private class Proj1Listener implements MouseListener, MouseMotionListener, MouseWheelListener{
public void mousePressed(MouseEvent event){
pointList.add(event.getPoint());
sizes[pointList.size()] = SIZE;
repaint();
}
public void mouseDragged(MouseEvent event){
pointList.add(event.getPoint());
sizes[pointList.size()] = SIZE;
repaint();
}
public void mouseWheelMoved(MouseWheelEvent event){
SIZE -= event.getWheelRotation();
repaint();
}
public void mouseClicked(MouseEvent event){
int x1 = event.getX();
int y1 = event.getY();
if(x1 > 5 && x1 < 35 && y1 > 40 && y1 < 70){
colors[c] = Color.RED;
}
if(x1 > 5 && x1 < 35 && y1 > 75 && y1 < 105){
colors[c] = Color.BLUE;
}
if(x1 > 5 && x1 < 35 && y1 > 110 && y1 < 140){
colors[c] = Color.GREEN;
}
if(x1 > 5 && x1 < 35 && y1 > 145 && y1 < 175){
colors[c] = Color.WHITE;
}
}
public void mouseReleased(MouseEvent event){}
public void mouseEntered(MouseEvent event){}
public void mouseExited(MouseEvent event){}
public void mouseMoved(MouseEvent event){}
}
}
EDIT:
I was able to fix the problem I had with my program. I had to reset a couple variables before I the drawing loop. Here is the working program!
import java.util.ArrayList;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;
public class Proj1Panel extends JPanel{
public int SIZE = 5, c = 0, s = 0;
private ArrayList<Point> pointList;
private int[] sizes;
private Color[] colors;
public String colorIs = "WHITE";
public Proj1Panel(){
pointList = new ArrayList<Point>();
sizes = new int[1000000];
colors = new Color[1000000];
addMouseListener (new Proj1Listener());
addMouseMotionListener (new Proj1Listener());
addMouseWheelListener (new Proj1Listener());
setBackground(Color.black);
setPreferredSize(new Dimension(300, 200));
}
public void paintComponent(Graphics page){
super.paintComponent(page);
page.setColor(Color.WHITE);
c = 0;
s = 0;
for(Point spot : pointList){
page.setColor(colors[c]);
page.fillRect(spot.x-sizes[s], spot.y-sizes[s], sizes[s]*2, sizes[s]*2);
c++;
s++;
}
repaint();
page.setColor(Color.BLACK);
page.fillRect(0, 0, 150, 35);
page.setColor(Color.BLACK);
page.fillRect(0, 35, 40, 180);
page.setColor(Color.RED);
page.fillRect(5, 40, 30, 30);
page.setColor(Color.BLUE);
page.fillRect(5, 75, 30, 30);
page.setColor(Color.GREEN);
page.fillRect(5, 110, 30, 30);
page.setColor(Color.WHITE);
page.fillRect(5, 145, 30, 30);
page.setColor(Color.WHITE);
page.fillRect(5, 180, 30, 30);
page.setColor(Color.BLACK);
page.fillRect(7, 182, 26, 26);
page.setColor(Color.WHITE);
page.drawString("Count: " + pointList.size() + "/1000000", 5, 15);
page.drawString("Size: " + SIZE, 5, 30);
page.drawString("Color: ", 65, 30);
page.drawString(colorIs, 100, 30);
}
private class Proj1Listener implements MouseListener, MouseMotionListener, MouseWheelListener{
public void mousePressed(MouseEvent event){
pointList.add(event.getPoint());
sizes[pointList.size()] = SIZE;
repaint();
}
public void mouseDragged(MouseEvent event){
pointList.add(event.getPoint());
sizes[pointList.size()] = SIZE;
repaint();
}
public void mouseWheelMoved(MouseWheelEvent event){
SIZE -= event.getWheelRotation();
repaint();
}
public void mouseClicked(MouseEvent event){
int x1 = event.getX();
int y1 = event.getY();
if(x1 > 5 && x1 < 35 && y1 > 40 && y1 < 70){
colors[c] = Color.RED;
colorIs = "RED";
}
if(x1 > 5 && x1 < 35 && y1 > 75 && y1 < 105){
colors[c] = Color.BLUE;
colorIs = "BLUE";
}
if(x1 > 5 && x1 < 35 && y1 > 110 && y1 < 140){
colors[c] = Color.GREEN;
colorIs = "GREEN";
}
if(x1 > 5 && x1 < 35 && y1 > 145 && y1 < 175){
colors[c] = Color.WHITE;
colorIs = "WHITE";
}
if(x1 > 5 && x1 < 35 && y1 > 180 && y1 < 210){
colors[c] = Color.black;
colorIs = "BLACK";
}
}
public void mouseReleased(MouseEvent event){}
public void mouseEntered(MouseEvent event){}
public void mouseExited(MouseEvent event){}
public void mouseMoved(MouseEvent event){}
}
}
Upvotes: 2
Views: 279
Reputation: 285403
You never reset the c variable, used as an index to the color array, to 0 in the paintComponent method. Instead it is set to 0 once in the beginning of the program. Thus it will monotonically increase until the array overflows. Consider resetting it to 0 at the beginning of paintComponent.
Also, what kind of Point class are you using? It holds some array, that we are not seeing. Here:
spot.x-sizes[pointList.size()]
Edit
I apologize as I misread your code, and I also didn't explain my answer well. You still should increment the c
variable, but you should re-set it to 0 at the beginning of paintcomponent. For example:
public void paintComponent(Graphics page) {
super.paintComponent(page);
c = 0; // each time paintComponent starts, c should be 0
for (Point spot : pointList) {
page.setColor(colors[c]);
page.fillRect(spot.x - sizes[pointList.size()], spot.y
- sizes[pointList.size()], sizes[pointList.size()] * 2,
sizes[pointList.size()] * 2);
c++; // but within the for loop, it should increment.
}
// .... etc
Alternatively, don't use a for-each loop, but rather a basic for loop, and this way you wouldn't even need a c
variable.
Upvotes: 2
Reputation: 324118
Create a custom object to containing the information you need to do the painting. That is your custom object can contain the Color and the Rectangle that you want to paint.
See Custom Painting Approaches for an example of how this can be done, then change your code to use the custom Object. You would use the DrawOnComponent
example.
my professor expects each point in the pointList to be drawn on the frame with its own corrisponding size and color, pointing back to the two parallel arrays of sizes and colors.
I just read that above comment, so my suggestion doesn't help. However, it still would not hurt to look at the example to see that each time you add a "point" top the ArrayList, you need to also set the Color and Size at the same time. Even though my code uses a Rectangle, the same logic is required for your code as well.
Also, why would you have one data structure as an ArrayList and two other structures as an Array. (Tell the prof) that is a terrible requirement. The ArrayList can grow to any size, but the Arrays are hard code to a magic number of 1000.
Upvotes: 1