Graphics keep resetting in JFrame - java

I recently started with Java and now I got stuck with a simple project. I want to draw a line and that works, but when i draw another line the first line disappears. I have no idea how to get it so I can keep drawing lines.
This is my code:
package com.example.paint;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class ClickEvent extends MouseAdapter {
private Paint paint;
boolean click = false;
boolean clear = false;
int startX;
int startY;
int endX;
int endY;
int firstTime = 1;
public ClickEvent(Paint paint, Handler handler, Line line) {
this.paint = paint;
}
public void mousePressed(MouseEvent e) {
int mx = e.getX();
int my = e.getY();
if (mouseOver(mx, my, 750, 560, 83, 40)) {
clear = true;
}
if (mouseOver(mx, my, 0, 0, 40, 40)) {
paint.color = "Black";
}
if (mouseOver(mx, my, 0, 40, 40, 40)) {
paint.color = "Blue";
}
if (mouseOver(mx, my, 0, 80, 40, 40)) {
paint.color = "Green";
}
if (mouseOver(mx, my, 0, 120, 40, 40)) {
paint.color = "Red";
}
if (!mouseOver(mx, my, 0, 0, 40, 160) && !mouseOver(mx, my, 750, 560, 83, 40)) {
clear = false;
startX = mx;
startY = my;
click = true;
}
}
public void mouseReleased(MouseEvent e) {
int mx = e.getX();
int my = e.getY();
if (!mouseOver(mx, my, 0, 0, 40, 160) && !mouseOver(mx, my, 750, 560, 83, 40)) {
endX = mx;
endY = my;
click = false;
}
}
private boolean mouseOver(int mx, int my, int x, int y, int width, int height) {
if (mx > x && mx < x + width) {
if (my > y && my < y + height) {
return true;
} else
return false;
} else
return false;
}
public void tick() {
}
public void render(Graphics g) {
Font font = new Font("Arial", 1, 30);
Font font1 = new Font("Arial", 1, 13);
g.setColor(Color.black);
g.fillRect(0, 0, 40, 40);
g.setColor(Color.blue);
g.fillRect(0, 40, 40, 40);
g.setColor(Color.green);
g.fillRect(0, 80, 40, 40);
g.setColor(Color.red);
g.fillRect(0, 120, 40, 40);
g.setColor(Color.black);
g.drawRect(750, 560, 83, 40);
g.setFont(font);
g.drawString("Clear", 755, 590);
g.setFont(font1);
if (paint.color == "Red") {
g.setColor(Color.red);
g.drawString("Color: " + paint.color, 745, 15);
} else if (paint.color == "Blue") {
g.setColor(Color.blue);
g.drawString("Color: " + paint.color, 745, 15);
} else if (paint.color == "Green") {
g.setColor(Color.green);
g.drawString("Color: " + paint.color, 745, 15);
} else if (paint.color == "Black") {
g.setColor(Color.black);
g.drawString("Color: " + paint.color, 745, 15);
} else {
g.setColor(Color.black);
g.drawString("Color: ", 745, 15);
}
if (!clear) {
if ("Red".equals(paint.color) && !click) {
g.setColor(Color.red);
g.drawLine(startX, startY, endX, endY);
} else if ("Green".equals(paint.color) && !click) {
g.setColor(Color.green);
g.drawLine(startX, startY, endX, endY);
} else if ("Blue".equals(paint.color) && !click) {
g.setColor(Color.blue);
g.drawLine(startX, startY, endX, endY);
} else if ("Black".equals(paint.color) && !click) {
g.setColor(Color.black);
g.drawLine(startX, startY, endX, endY);
}
}
}
}
Some of the code is part of a basic tutorial, but the rest I tried to do myself. If anyone knows how I can get it to keep drawing lines or if anyone has any other improvements I would really appreciate it.

The problem is that you're only saving one line to draw later, in the form of startX, startY, endX, endY.
Rather you could, at the end of each click, save the line as a new line object. Something like this:
class MyLine {
private final int startX, startY;
private final int endX, endY;
private final Color color;
public MyLine(int startX, int startY, int endX, int endY, Color color) {
this.startX = startX;
this.startY = startY;
this.endX = endX;
this.endY = endY;
this.color = color;
}
public void draw(Graphics g) {
g.setColor(color);
g.drawLine(startX, startY, endX, endY);
}
}
Add a list as a field to your class:
List<MyLine> lineList = new ArrayList<>();
And then, in the mouseReleased method, add a new Line to the list:
if (!mouseOver(mx, my, 0, 0, 40, 160) && !mouseOver(mx, my, 750, 560, 83, 40)) {
endX = mx;
endY = my;
click = false;
lineList.add(new MyLine(startX, starY, endX, endY, paint.color));
}
Additionally, you would have to change Paint, so that it holds the color as a Color object:
class Paint {
public Color color;
...
}
~~~~
paint.color = Color.black;
Which is much easier than saving strings.
Finally, loop over all of your lines to draw them, within your render method:
for(MyLine l : lineList) {
l.draw(g);
}

Related

Creating sliders with arrow buttons

How can I create a slider with two arrow buttons from the side? The arrows/triangle should turn white when clicked. And the slider should move each time the arrow button is clicked.
here's the link to what it should look like
and here's what I've done so far
int x=75;
void setup() {
size(600,400);
}
void draw() {
background(100);
fill (200);
rect (75, 25, 400, 50);
stroke(0);
if(mousePressed) {
if (mouseX >75 && mouseX <= 475)
{x=mouseX;}
}
fill(127,0,0);
rect (x, 20, 9, 60);
fill (255);
fill (200);
rect (10, 25, 50, 50);
{
if (mousePressed == true) {
fill(255);
} else {
fill(0);
}
triangle (50, 60, 50, 40, 15, 50);
}
fill (200);
rect (490, 25, 50, 50);
{
if (mousePressed == true) {
fill(255);
} else {
fill(0);
}
triangle (500, 60, 500, 40, 535, 50);
}
println(x);
}
When I click anywhere on the screen, my problem is that both arrows turn white. I need it to individually function. And the slider is not moving every time I click the arrow buttons
The following approach to this problem uses 4 different classes: ForwardArrow, BackArrow, Slider, and ValueField. Arrow fill color is controlled by the press() method of its respective class.
color BLUE = color(64, 124, 188);
color LTGRAY = color(185, 180, 180);
color YELLOW = color(245, 250, 13);
color RED = color(255, 0, 0);
color BLACK = color(0, 0, 0);
color WHITE = color(255, 255, 255);
color GREEN = color(32, 175, 47);
ForwardArrow _fwdArrw;
BackArrow _backArrw;
ValueField _valueFld;
Slider _slider;
final int _sliderX = 90;
final int _sliderY = 40;
final int _sliderW = 200;
final int _sliderH = 30;
final int _txtSize = 22;
final int _initValue = 40;
final int _maxValue = 200;
final int _minValue = 0;
int value = _initValue;
class ValueField {
float x, y, w, h;
String title;
color fldColor;
color txtColor;
// Constructor
ValueField(int xpos, int ypos, float wt, float ht, String valueStr, color background, color foreground) {
x = xpos;
y = ypos;
w = wt;
h = ht;
title = valueStr;
fldColor = background;
txtColor = foreground;
}
void display(int val) {
// **** Value Field **** //
fill(fldColor); // erase old value
rect(x, y, w, h);
fill(txtColor); // text color
textSize(_txtSize);
textAlign(CENTER);
text(str(val), x, y, w, h);
// **** Slider bar **** //
fill(255);
rect(_sliderX, _sliderY, _sliderW*val/_maxValue, _sliderH);
}
}
class ForwardArrow {
float x, y, w, h;
color arrwColor;
// Constructor
ForwardArrow(int xpos, int ypos, float wt, float ht, color background) {
x = xpos;
y = ypos;
w = wt;
h = ht;
arrwColor = background;
}
void display() {
fill(arrwColor); // arrow color
noStroke();
triangle(x, y, x, y + h, x + w, y + h/2 );
}
void press() {
fill(255); // arrow color
noStroke();
triangle(x, y, x, y + h, x + w, y + h/2 );
}
}
class BackArrow {
float x, y, w, h;
color arrwColor;
// Constructor
BackArrow(int xpos, int ypos, float wt, float ht, color background) {
x = xpos;
y = ypos;
w = wt;
h = ht;
arrwColor = background;
}
void display() {
fill(arrwColor);
noStroke();
triangle(x, y + h/2, x + w, y, x + w, y + h );
}
void press() {
fill(255);
noStroke();
triangle(x, y + h/2, x + w, y, x + w, y + h );
}
}
class Slider {
float x, y, w, h;
color barColor;
color trimColor;
// Constructor
Slider(int xpos, int ypos, float wt, float ht, color background, color foreground) {
x = xpos;
y = ypos;
w = wt;
h = ht;
barColor = background;
trimColor = foreground;
}
void display() {
stroke(0);
strokeWeight(1);
noFill();
rect(x, y, w, h);
}
}
void setup() {
size(500, 250);
background(BLUE);
_slider = new Slider(_sliderX, _sliderY, _sliderW, _sliderH, WHITE, BLACK);
_backArrw = new BackArrow(50, 40, 30, 30, GREEN);
_fwdArrw = new ForwardArrow(300, 40, 30, 30, GREEN);
_valueFld = new ValueField(380, 40, 60, 30, str(_initValue), WHITE, BLACK);
}
void draw() {
background(BLUE);
_valueFld.display(value);
_fwdArrw.display();
_backArrw.display();
_slider.display();
// FwdArrw Long Press
if ((mouseX >= _fwdArrw.x) && (mouseX <= _fwdArrw.x + _fwdArrw.w) && (mouseY >= _fwdArrw.y) && (mouseY <= _fwdArrw.y + _fwdArrw.h)) {
if (mousePressed == true) {
_fwdArrw.press();
value++;
if (value > _maxValue) {
value = _maxValue;
}
_valueFld.display(value);
}
}
// BackArrw Long Press
if ((mouseX >= _backArrw.x) && (mouseX <= _backArrw.x + _backArrw.w) && (mouseY >= _backArrw.y) && (mouseY <= _backArrw.y + _backArrw.h)) {
if (mousePressed == true) {
_backArrw.press();
value--;
if (value < _minValue) {
value = _minValue;
}
_valueFld.display(value);
}
}
}
A revision of your code follows;
int x=75;
void setup() {
size(600, 400);
}
void draw() {
background(100);
fill (200);
rect (75, 25, 400, 50); // slider bar
stroke(0);
fill(127, 0, 0);
rect (x, 20, 9, 60); // slider thumb
fill (200);
rect (10, 25, 50, 50); // back arrow
fill(0);
triangle (50, 60, 50, 40, 15, 50);
if ((mouseX >= 10) && (mouseX <= 10 + 50) && (mouseY >= 25) && (mouseY <= 25 + 50) ) {
if (mousePressed == true) {
fill(255);
triangle (50, 60, 50, 40, 15, 50);
x--;
if (x<75) {
x = 75; // minValue
}
} else {
fill(0);
triangle (50, 60, 50, 40, 15, 50);
}
}
fill (200);
rect (490, 25, 50, 50); //forward arrow
fill(0);
triangle (500, 60, 500, 40, 535, 50);
if ((mouseX >= 490) && (mouseX <= 490 + 50) && (mouseY >= 25) && (mouseY <= 25 + 50) ) {
if (mousePressed == true) {
fill(255);
triangle (500, 60, 500, 40, 535, 50);
x++;
if (x>466) {
x = 466; // maxValue
}
} else {
fill(0);
triangle (500, 60, 500, 40, 535, 50);
}
}
}
You've got part of the logic right for the slider/trackbar so it changes x only within a range. This happens horizontally only at this stage, but you can use the same logic to check horizontal limits as well. Similarly, you can check if the cursor is within the bounds of any rectangle (be it the slider or either of the buttons):
int x=75;
void setup() {
size(600, 400);
}
void draw() {
background(100);
// slider
fill (200);
rect (75, 25, 400, 50);
stroke(0);
if (mousePressed) {
if (mouseX >75 && mouseX <= 475)
{
x=mouseX;
}
}
fill(127, 0, 0);
rect (x, 20, 9, 60);
fill (255);
// left arrow button
fill (200);
rect (10, 25, 50, 50);
fill(0);
if (mousePressed == true) {
if (mouseX > 10 && mouseX <= 10 + 50 && mouseY > 25 && mouseY <= 25 + 50){
fill(255);
}
}
triangle (50, 60, 50, 40, 15, 50);
// right arrow button
fill (200);
rect (490, 25, 50, 50);
fill(0);
if (mousePressed == true) {
if (mouseX > 490 && mouseX <= 490 + 50 && mouseY > 25 && mouseY <= 25 + 50){
fill(255);
}
}
triangle (500, 60, 500, 40, 535, 50);
println(x);
}
Wouldn't it be nice if you could take that logic and instead of copy/pasting the different x,y,width,height parameters for the same 4 statements you could group that functionality in a reusable block of code ?
That what functions are for. You're already using them already (defining setup()/draw(), calling background()/fill()/etc.
The Processing Button example already provides the boolean overRect(int x, int y, int width, int height) function which is perfect for you're trying to achieve: pass in the x,y,width,height or a button and get back boolean value.
Here's your code using the overRect():
int x=75;
void setup() {
size(600, 400);
}
void draw() {
background(100);
// slider
fill (200);
rect (75, 25, 400, 50);
stroke(0);
if (mousePressed) {
if (mouseX >75 && mouseX <= 475)
{
x=mouseX;
}
}
fill(127, 0, 0);
rect (x, 20, 9, 60);
fill (255);
// left arrow button
fill (200);
rect (10, 25, 50, 50);
fill(0);
if (mousePressed && overRect(10, 25, 50, 50)) {
fill(255);
x--;
}
triangle (50, 60, 50, 40, 15, 50);
// right arrow button
fill (200);
rect (490, 25, 50, 50);
fill(0);
if (mousePressed && overRect(490, 25, 50, 50)){
fill(255);
x++;
}
triangle (500, 60, 500, 40, 535, 50);
// ensure x remains within the slide limits
x = constrain(x, 75, 475);
println(x);
}
boolean overRect(int x, int y, int width, int height) {
if (mouseX >= x && mouseX <= x+width &&
mouseY >= y && mouseY <= y+height) {
return true;
} else {
return false;
}
}

Why does Carpaint not move when all other sprites do?

I have a code for moving sprites in an animation - all but one of my sprites moves and I can't figure out why. Can someone explain?
My Sprite class:
abstract class SimpleSprite {
// basic x,y movement,keeps a master list of Sprites
public static final ArrayList<SimpleSprite> sprites = new ArrayList<SimpleSprite>();
float x, y, dx, dy; // position and velocity (pixels/TIMER_MSEC)
public SimpleSprite(float x, float y, float dx, float dy) {
// initial position and velocity
this.x = x;
this.y = y;
this.dx = dx;
this.dy = dy;
sprites.add(this);
}
public void update() { // update position and velocity every n milliSec
// default - just move at constant velocity
x += dx; // velocity in x direction
y += dy; // velocity in y direction
}
abstract public void draw(Graphics2D g2d);
// just draw at current position, no updating.
}
My sprite that doesn't work:
class Carpaint extends SimpleSprite {
public Carpaint(float x, float y, float dx, float dy) {
super(x, y, dx, dy);
}
#Override
public void draw(Graphics2D g2d){
g2d.setColor(Color.pink);
g2d.fillRect(50, 50, 40, 60);
g2d.setColor(Color.black);
g2d.drawRect(50, 50, 40, 60);
g2d.drawRect(60, 60, 20, 40);
g2d.fillRect(45, 50, 5, 15);
g2d.fillRect(90, 50, 5 , 15);
g2d.fillRect(45, 95, 5, 16);
g2d.fillRect(90, 95, 5, 16);
}
}
My main:
public static void main(String[] args) {
// create and display the animation in a JFrame
final JFrame frame = new JFrame("Animation 2 (close window to exit)");
Animation2 animationPanel = new Animation2(600, 500);
frame.add(animationPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
// add some sprites...
new Square(0, 0, 3, 2, 40);
new Ball(500, 0, -3, 3, 20);
new Ball(0, 500, 2, -5, 30);
new Carpaint(100, 100, 20, -6);
}
I expected all sprites to move but the car doesn't (see here: https://i.gyazo.com/0219127277d2543735b3a4727e7c7e72.mp4)
Answer came from #RealSkeptic - I wasn't painting the car with reference to x and y.
New Code:
class Carpaint extends SimpleSprite {
public Carpaint(float x, float y, float dx, float dy) {
super(x, y, dx, dy);
}
#Override
public void draw(Graphics2D g2d){
g2d.setColor(Color.pink);
g2d.fillRect((int) x, (int) y, 40, 60);
g2d.setColor(Color.black);
g2d.drawRect((int) x, (int) y, 40, 60);
g2d.drawRect((int) x + 10, (int) y + 10, 20, 40);
g2d.fillRect((int) x-5, (int) y, 5, 15);
g2d.fillRect((int) x + 40, (int) y, 5 , 15);
g2d.fillRect((int) x - 5, (int) y + 45, 5, 16);
g2d.fillRect((int) x + 40, (int) y + 45, 5, 16);
}
}

Need help adding a class and animations to a simple pet drawing?

float x = 100;
float y = 100;
float p = 150;
float l = 10;
float a = 100;
float b = 100;
float n =20;
int value = 255;
int r = 150;
int t = 100;
int s = 100;
int w = 60;
int h = 60;
int z = 11;
int eyeSize = 10;
int pigNose = 30;
int pigBody = 30;
int pigEars = 35;
int pigTail = 20;
int otherpigTail = 200;
int speed = 1;
void setup () {
size (600, 600);
a = width/2.5;
b = height/2;
}
void draw() {
background(184, 233, 249);
//Draw legs
stroke(0);
fill(249, 137, 244);
rect(x+(2*w), y+h/3.5, z, 2*z);
rect(x+(w), y+h/3, z, 2*z);
rect(x+(1.5*w), y+h/3, z, 2*z);
rect(x+(2.5*w), y+h/3.5, z, 2*z);
////draw body
stroke(0);
fill(249, 137, 244);
ellipse(110+x,y-pigBody, p, p-20);
//draw tail
fill(0);
line(185+x, y-pigTail, x+otherpigTail, y-(2*pigTail));
// Draw payer's head
fill(249, 137, 244);
ellipse(x,y-pigNose,t,t);
// Draw player's eyes
fill(0);
ellipse(x-w/3+1,y-h/2,eyeSize,eyeSize);
ellipse(x+w/3-1,y-h/2,eyeSize,eyeSize);
//Draw nose
stroke(0);
fill(198, 105, 194);
ellipse(x, y, pigNose, pigNose);
//draw ears
stroke(0);
fill(198, 105, 194);
ellipse(x-(w/2),y-h, pigEars, pigEars);
ellipse(x+(w/2),y-h, pigEars, pigEars);
//draw obstacles
fill(value);
ellipse(a, b, s, s);
ellipse(300+a, 200+b, s, s);
ellipse(300-a, 400+b, s, s);
ellipse(300-a, 600+b, s, s);
ellipse(300-a, b, s, s);
ellipse(300+a, 800+b, s, s);
}
I need help turning this code into something similar to this:
/*
This is a very rudimentary virtual pet. It can sit,
lie down, and wag it's tail.
*/
class Pet {
int x, y;
int pose;
int WAG = 1, SLEEP = 2, SIT = 3;
float tailWag, wagSpeed;
Pet(int x, int y) {
this.x = x;
this.y = y;
pose = SIT;
}
// adjust pose and stop tail wagging
void sit() {
pose = SIT;
wagSpeed = 0;
tailWag = 0;
}
// adjust pose and start tail wagging
void wag() {
pose = WAG;
wagSpeed = .1;
}
// adjust pose and stop tail wagging
void sleep() {
pose = SLEEP;
wagSpeed = 0;
tailWag = 0;
}
// draw in selected pose
void draw() {
pushMatrix();
translate(x, y);
if (pose == SIT) {
drawSitting();
}
else if (pose == WAG) {
wagTail();
drawSitting();
}
else {
drawLaying();
}
popMatrix();
}
void drawLaying() {
// needs work :-)
ellipse(0, 0, 150, 60);
}
void wagTail() {
float maxTailWag = .5; // controls how much the tail wags back and forth
tailWag = tailWag + wagSpeed;
// reverse wag direction if the wag limit is reached
if (tailWag > maxTailWag || tailWag < -maxTailWag) {
wagSpeed = -wagSpeed;
}
}
// not pretty but gets the idea across
// origin is the center of the torso
void drawSitting() {
// torso
pushMatrix();
rotate(radians(-30));
ellipse(0, 0, 80, 120);
popMatrix();
ellipse(-20, -70, 60, 60); // head
// nose
pushMatrix();
translate(-55, -55);
rotate(radians(-15));
arc(0, 0, 40, 30, radians(20), radians(310), OPEN);
popMatrix();
// eyes
ellipse(-40, -85, 15, 15); // left eye
ellipse(-25, -80, 15, 15); // right eye
//ear
pushMatrix();
translate(15, -50);
rotate(radians(-20));
ellipse(0, 0, 20, 40);
popMatrix();
//tail
pushMatrix();
translate(40, 30);
rotate(radians(45)+tailWag);
arc(0, -35, 30, 60, radians(-220)-tailWag, radians(80), OPEN);
popMatrix();
// back leg
ellipse(0, 60, 50, 20);
// front leg
pushMatrix();
translate(-50, 30);
rotate(radians(15));
ellipse(0, 0, 30, 60);
popMatrix();
}
}
with classes and whatnot so that I can start working on adding in my own animations for the pet. I'm just not sure where to put everything/how to organize it like that using my drawing.
If I were you, I would start with something simpler. For example, here's a program that uses 4 variables to show a ball bouncing around:
float circleX = 50;
float circleY = 50;
float xSpeed = 1;
float ySpeed = 2;
void draw() {
background(200);
circleX += xSpeed;
if (circleX < 0 || circleX > width) {
xSpeed *= -1;
}
circleY += ySpeed;
if (circleY < 0 || circleY > height) {
ySpeed *= -1;
}
ellipse(circleX, circleY, 20, 20);
}
(source: happycoding.io)
From here, we can encapsulate those 4 variables into a class:
class Circle{
float x;
float y;
float xSpeed;
float ySpeed;
Circle(float x, float y, float xSpeed, float ySpeed){
this.x = x;
this.y = y;
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
}
}
Now that we have a class, we can use an instance of that class to control our ball.
Circle circle = new Circle(50, 50, 1, 2);
void draw() {
background(200);
circle.x += circle.xSpeed;
if (circle.x < 0 || circle.x > width) {
circle.xSpeed *= -1;
}
circle.y += circle.ySpeed;
if (circle.y < 0 || circle.y > height) {
circle.ySpeed *= -1;
}
ellipse(circle.x, circle.y, 20, 20);
}
class Circle{
float x;
float y;
float xSpeed;
float ySpeed;
Circle(float x, float y, float xSpeed, float ySpeed){
this.x = x;
this.y = y;
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
}
}
Your code would follow a similar pattern: create a class, encapsulate your data by moving your variables inside the class, and then create an instance of that class and call its methods to draw your figure. Start with something simpler, and just create a class that draws a single circle. Get that working first, and then add variables to that class to draw two circles (a head and a body), and keep working in small steps like that until you're drawing your whole figure.
I really suggest trying something out and posting an MCVE if you get stuck. Good luck.
Shameless self-promotion: I've written a tutorial on creating classes in Processing available here.

How to make one button change the background color back and forth in processing java?

In my code i am trying to make one button change the background color from black to white to black to white. Here is my code. I included all of the code so you can see. This is not for school or anything just for fun.
int circleX, circleY; // Position of circle button
int circleSize = 93; // Diameter of circle
color circleColor, baseColor;
color circleHighlight;
color currentColor;
boolean circleOver = false;
int start;
int m = 0;
void setup() {
start = millis();
size(640, 360);
circleColor = color(255);
circleHighlight = color(204);
baseColor = color(102);
currentColor = baseColor;
circleX = width/2+circleSize/2+10;
circleY = height/2;
ellipseMode(CENTER);
}
void draw() {
update(mouseX, mouseY);
background(currentColor);
if (circleOver) {
fill(circleHighlight);
} else {
fill(circleColor);
}
stroke(0);
ellipse(circleX, circleY, circleSize, circleSize);
int timer = millis()-start;
fill(0, 102, 153);
textSize(40);
text(timer, 40, 40);
textSize(20);
text("milliseconds", 200,40);
fill(0,102,153);
textSize(40);
text(m,400,40);
textSize(20);
text("hits", 450,40);
}
void update(int x, int y) {
if ( overCircle(circleX, circleY, circleSize) ) {
circleOver = true;
} else {
circleOver = false;
}
}
void mousePressed() {
if (circleOver) {
currentColor = circleColor;
m = m + 1;
}
}
boolean overCircle(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < diameter/2 ) {
return true;
} else {
return false;
}
}
Use a boolean in draw() as a flag, and change it in mousePressed you can say booleanX = !booleanX; this will toogle the value of the boolean.
here:
int circleX, circleY;
// Position of circle button
int circleSize = 93;
// Diameter of circle
color circleColor, baseColor;
color circleHighlight;
color currentColor;
boolean color1 = false;
int start;int m = 0;
void setup() {
start = millis();
size(640, 360);
circleColor = color(255);
circleHighlight = color(204);
baseColor = color(102);
currentColor = baseColor;
circleX = width/2+circleSize/2+10;
circleY = height/2;
ellipseMode(CENTER);
}
void draw() {
if (color1){
currentColor = color(255);
}else{
currentColor = color(85);
}
background(currentColor);
if (overCircle(circleX, circleY, circleSize)) {
fill(circleHighlight);} else {
fill(circleColor);}
stroke(0);
ellipse(circleX, circleY, circleSize, circleSize);
int timer = millis()-start;
fill(0, 102, 153);
textSize(40);
text(timer, 40, 40);
textSize(20);
text("milliseconds", 200,40);
fill(0,102,153);
textSize(40);
text(m,400,40);
textSize(20);
text("hits", 450,40);
}
void mousePressed() {
if (overCircle(circleX, circleY, circleSize)) {
color1 = !color1;
m = m + 1;
}
}
boolean overCircle(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < diameter/2 ) {
return true;
} else {
return false;
}
}

Java mouselistener rectangle issue

I have a programme where there are sticky notes. You click on them to pick them up and click again to place them somewhere. My problem is when there are two or more sticky notes on top of each other they both get picked up I only want the top one to be picked up. How can I fix this here is my code so far:
public class PhoneMsg {
public int x, y, id, hour, minute;
public boolean drag = false;
public String name, lastname, msg, msg2, msg3;
public Rectangle rx = new Rectangle(x + 290, y, 20, 20);
public Rectangle rdrag = new Rectangle(x, y, 310, 20);
public boolean remove;
private Image img;
public PhoneMsg(int x, int y, String name, String lastname, int hour, int minute, int id) {
this.x = x;
this.y = y;
this.name = name;
this.lastname = lastname;
this.hour = hour;
this.minute = minute;
this.id = id;
rdrag = new Rectangle(x, y, 310, 20);
rx = new Rectangle(x + 290, y, 20, 20);
genMsg();
}
public void tick() {
rx = new Rectangle(x + 290, y, 20, 20);
rdrag = new Rectangle(x, y, 310, 20);
if (rx.intersects(Comp.mx, Comp.my, 1, 1)) {
if (Comp.ml) {
remove = true;
for (int i = 0; i < play.ph.pp.toArray().length; i++) {
// play.ph.pp.get(i).canreadtxt = true;
}
}
}
// dragging
if (drag) {
x = Comp.mx - 140;
y = Comp.my - 10;
}
if (msg == null) {
genMsg();
}
}
public void render(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
RenderingHints rh = new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
g2.setRenderingHints(rh);
// display
g.setColor(new Color(19, 165, 34));
g.fillRect(x, y, 310, 150);
g.setColor(new Color(27, 53, 16));
g.drawRect(x, y, 310, 150);
g.setColor(new Color(27, 53, 16));
g.drawRect(x, y, 310, 20);
// Exit part
g.setColor(new Color(27, 53, 16));
g.drawRect(rx.x, rx.y, rx.width, rx.height);
g.setColor(Color.red);
g.setFont(new Font("italic", Font.BOLD, 12));
g.drawString("X", rx.x + 7, rx.y + 15);
// name
g.setColor(Color.black);
g.setFont(new Font("italic", Font.BOLD, 12));
g.drawString("" + name + " " + lastname + "'s Recent Messages", x + 5, y + 15);
// details
String msg11 = String.format("%02d:%02d", hour, minute);
String msg21 = String.format("%02d:%02d", hour, minute);
String msg31 = String.format("%02d:%02d", hour, minute);
if(play.hud.wifi >= 1){
g.setColor(Color.CYAN);
g.setFont(new Font("italic", Font.BOLD, 12));
g.drawString(" " + msg, x + 2, y + 38);
g.setColor(Color.white);
g.setFont(new Font("italic", Font.BOLD, 12));
g.drawString(" " + msg2, x + 2, y + 58);
g.setColor(Color.cyan);
g.setFont(new Font("italic", Font.BOLD, 12));
g.drawString(" " + msg3, x + 2, y + 78);
}else if(play.hud.wifi <= 0){
g.setColor(Color.red);
g.setFont(new Font("italic", Font.PLAIN, 18));
g.drawString("Lost Connection", x +90, y +85);
g.setColor(Color.red);
g.setFont(new Font("italic", Font.PLAIN, 18));
g.drawString("_________________", x +70, y +88);
}
}
}
and this is the part in the mouse listener that lets u pick up the sticky notes:
// dragging msg's
for (int i1 = 0; i1 < play.ph.pm.toArray().length; i1++) {
if (play.ph.pm.get(i1).drag == false && play.holding == false) {
if (play.ph.pm.get(i1).rdrag.contains(Comp.mx, Comp.my)) {
play.ph.pm.get(i1).drag = true;
play.holding = true;
}
} else {
play.ph.pm.get(i1).drag = false;
play.holding = false;
}
}
If you break out of the for loop you can pick up the first sticky note the code gets to when they're overlapping.
if (play.ph.pm.get(i1).rdrag.contains(Comp.mx, Comp.my)) {
play.ph.pm.get(i1).drag = true;
play.holding = true;
break; // Found sticky note, exits loop
}
Or if this conflicts with your else statement, simply create a flag.
// dragging msg's
boolean gotCard = false;
for (int i1 = 0; i1 < play.ph.pm.toArray().length; i1++) {
if (play.ph.pm.get(i1).drag == false && play.holding == false && gotNote == false) { // Added gotNote check
if (play.ph.pm.get(i1).rdrag.contains(Comp.mx, Comp.my)) {
play.ph.pm.get(i1).drag = true;
play.holding = true;
gotNote = true; // Set flag to true
}
} else {
play.ph.pm.get(i1).drag = false;
play.holding = false;
}
}
However you should probably have a z-index implemented to be able to tell which sticky note is on top then sort your array by that z-index.

Categories