作为作业的一部分,我将设定一个可以在按下键盘时移动的形状,并且随着移动而改变颜色。我正在尝试通过单击添加重复的形状,这些形状在选定时会移动。但是,由于某种原因,我不能添加多个形状。这是我的代码。警告:MySimplePanel很长,但是注释解释了我的代码的作用。
import java.awt.Graphics2D;
public interface ActionShape {
/**
* Calls the draw method inherited from the shape
* @param g
*/
public void draw(Graphics2D g);
public boolean contains(double x, double y);
public double getWidth();
public double getHeight();
public void setFrame(double x, double y, double w, double h);
}
Driver.java
public class Driver {
public static void main(String args[]) {
MySimplePanel panel = new MySimplePanel(800, 800, Color.gray);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
public static float random(float lower, float upper) {
float rand = (float) Math.random();
float range = upper - lower;
rand = range * rand;
System.out.println((lower + rand));
return (lower + rand);
}
}
myShape.java
public class myShape extends Rectangle2D.Double implements ActionShape{
static final int size = 50;
Ellipse2D oval;
Ellipse2D oval2;
Ellipse2D oval3;
public int red=127;
public int green=127;
public int blue = 0;
public myShape(int x, int y) {
//sets position of square to center
super(x-size/2, y-size/2, size, size);
oval = new Ellipse2D.Double(x-size/2, y - size, size, size);
oval2 = new Ellipse2D.Double(x-size/2, y + size/25, size, size);
oval3 = new Ellipse2D.Double(x - size, y-size/2, size, size);
}
/**
* Move all the shapes comprising this one
* @return
*/
@Override
public void draw(Graphics2D g) {
// TODO Auto-generated method stub
g.setColor(Color.black);
g.draw(this); //draw outline
g.draw(oval);
g.draw(oval2);
g.draw(oval3);
g.setColor(new Color(red,green,blue));//set color of all shapes
g.fill(this); //draw inside
g.fill(oval);
g.fill(oval2);
g.fill(oval3);
}
public void setFrame(double x, double y, double w, double h) {
super.setFrame(x, y, w, h);
oval.setFrame(x, y-size/2, w, h);
oval2.setFrame(x, y+size/2, w, h);
oval3.setFrame(x-size/2, y, w, h);
}
public boolean contains(double x, double y) {
if(super.contains(x, y) || oval.contains(x, y)|| oval2.contains(x, y)|| oval3.contains(x, y)) {
return true;
}else {
return false;
}
}
}
MySimplepanel
public class MySimplePanel extends JPanel implements MouseInputListener, KeyListener{
public static final int MOVE_PER_ARROW_KEY = 5; //variable that determines how many spaces the shape will move.
private int width;
private int height;
private boolean isPressed = false;
private boolean rightPressed = false;
private boolean otherPressed = false;
public myShape shape;
public int maxRed = 255;
public int maxGreen = 255;
public int maxBlue = 255;
public myShape selShape=null;
public int nextShape=0;
//An array of different shapes that all share an interface. This will be used when the right mouse button is pressed
public myShape[] shapes;
/**
* Construct a panel with specified width, height, and background color
* @param width
* @param height
* @param bgColor
*/
public MySimplePanel(int width, int height, Color bgColor) {
this.setPreferredSize(new Dimension(width, height));
this.setBackground(bgColor);
//Start to listen to mouse and keyboard input on this panel
this.addMouseListener(this);
this.addMouseMotionListener(this);
this.addKeyListener(this); //detect keyboard input
this.setFocusable(true); //allows you to select this window (required to be able to type in it, just like Processing)
this.setFocusTraversalKeysEnabled(false); //disables shift and tab
setup();
}
private void setup() {
//sets up the starting coordinates for each shape the shape is going to be on the panel.
//I still need to align the center of the panel with the shape's center.
shape = new myShape(400,400);
shapes = new myShape[100];
//array of shapes
shapes[nextShape] = new myShape(200,200);
repaint();
}
/**
* This method is called whenever you call repaint();
*/
protected void paintComponent(Graphics graphicHelper) {
super.paintComponent(graphicHelper); //basically background() in Processing, erases everything
Graphics2D g = (Graphics2D) graphicHelper; //used for drawing in 2D mode
//width and height of the panel
width= getWidth();
height = getHeight();
//draws the shape.
shape.draw(g);
for(int i=0;i<nextShape;i++) {
shapes[i].draw(g);
g.setColor(Color.red);
g.draw(shapes[i]);
}
//for the very first shape that is drawn
if(isPressed==true) {
shape.draw(g);
g.setColor(Color.red);
g.draw(shape);
System.out.println("Shape pressed");
}
//for the very other shape that is drawn by right-clicking
if(otherPressed==true) {
for(int i=0;i<nextShape;i++) {
selShape.draw(g);
g.setColor(Color.red);
g.draw(selShape);
System.out.println("Other Shape pressed");
}
}
}
@Override
public void mouseClicked(MouseEvent arg0) {
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
}
@Override
public void mousePressed(MouseEvent arg0) {
if(arg0.getButton() == MouseEvent.BUTTON1) {
if(shape.contains(arg0.getX(), arg0.getY())) {
selShape=shape;
isPressed=true;
repaint();
}
}
if(arg0.getButton() == MouseEvent.BUTTON1) {
for(int i=0; i<nextShape; i++) {
if(shapes[i]!=null) {
if(shapes[i].contains(arg0.getX(), arg0.getY())) {
selShape=shapes[i];
otherPressed=true;
repaint();
}
}
}
}
if(arg0.getButton() == MouseEvent.BUTTON3) {
rightPressed=true;
if(rightPressed==true) {
selShape=shapes[nextShape];
nextShape++;
repaint();
}
}
}
@Override
public void mouseReleased(MouseEvent arg0) {
}
@Override
public void mouseDragged(MouseEvent arg0) {
}
@Override
public void mouseMoved(MouseEvent arg0) {
}
@Override
public void keyPressed(KeyEvent arg0) {
/**
* Scales the values of red and green based on the width and height respectively.
* red = 0 when the shape is all the way on the left, red = 255 when the shape is all the way on the right
* green = 0 when the shape is all the way up, green = 255 when the shape is all the way down
*/
selShape.red=(int) ((maxRed)*selShape.x/width);
selShape.green=(int) ((maxGreen)*selShape.y/height);
/**
* These two if statements are meant to keep the shape from moving off screen.
*/
if(selShape.x>width||selShape.x<(width=0)) {
selShape.x=width;
}
if(selShape.y>height||selShape.y<(height=0)) {
selShape.y=height;
}
/**
* Moves the shape in different directions depending on the key pressed. It also changes the values of red and green
*/
if(arg0.getKeyCode() == KeyEvent.VK_DOWN) {
selShape.setFrame(selShape.x, selShape.y + MOVE_PER_ARROW_KEY,
selShape.width, selShape.height);
selShape.green--;
repaint();
}else if(arg0.getKeyCode() == KeyEvent.VK_UP) {
selShape.setFrame(selShape.x, selShape.y - MOVE_PER_ARROW_KEY,
selShape.width, selShape.height);
selShape.green++;
repaint();
}else if(arg0.getKeyCode() == KeyEvent.VK_LEFT) {
selShape.setFrame(selShape.x - MOVE_PER_ARROW_KEY, selShape.y,
selShape.width, selShape.height);
selShape.red--;
repaint();
}else if(arg0.getKeyCode() == KeyEvent.VK_RIGHT) {
selShape.setFrame(selShape.x + MOVE_PER_ARROW_KEY, selShape.y,
selShape.width, selShape.height);
selShape.red++;
repaint();
}
/**
* If the shape reaches a certain spot, it will keep changing color randomly until it leaves that area.
*
* Still trying to get the shape's center to hit that spot.
*
*/
if(selShape.getCenterX()>=50 && selShape.getCenterX()<=150 && selShape.getCenterY()>=50 && selShape.getCenterY()<=150) {
selShape.red=(int)(Math.random()*maxRed)+1;
selShape.green=(int)(Math.random()*maxGreen)+1;
selShape.blue=(int)(Math.random()*maxBlue)+1;
System.out.println("x: "+selShape.x);
System.out.println("y: "+selShape.y);
}
}
@Override
public void keyReleased(KeyEvent arg0) {
}
@Override
public void keyTyped(KeyEvent arg0) {
}
}
myShape.java
public class myShape extends Rectangle2D.Double implements ActionShape {
static final int size = 50;
Ellipse2D oval;
Ellipse2D oval2;
Ellipse2D oval3;
public int red = 127;
public int green = 127;
public int blue = 0;
public myShape(int x, int y) {
// sets position of square to center
super(x - size / 2, y - size / 2, size, size);
oval = new Ellipse2D.Double(x - size / 2, y - size, size, size);
oval2 = new Ellipse2D.Double(x - size / 2, y + size / 25, size, size);
oval3 = new Ellipse2D.Double(x - size, y - size / 2, size, size);
}
/**
* Move all the shapes comprising this one
*
* @return
*/
@Override
public void draw(Graphics2D g) {
// TODO Auto-generated method stub
g.setColor(Color.black);
g.draw(this); // draw outline
g.draw(oval);
g.draw(oval2);
g.draw(oval3);
g.setColor(new Color(red, green, blue));// set color of all shapes
g.fill(this); // draw inside
g.fill(oval);
g.fill(oval2);
g.fill(oval3);
}
public void setFrame(double x, double y, double w, double h) {
super.setFrame(x, y, w, h);
oval.setFrame(x, y - size / 2, w, h);
oval2.setFrame(x, y + size / 2, w, h);
oval3.setFrame(x - size / 2, y, w, h);
}
public boolean contains(double x, double y) {
if (super.contains(x, y) || oval.contains(x, y) || oval2.contains(x, y) || oval3.contains(x, y)) {
return true;
} else {
return false;
}
}