Why this code doesn't work as it should work?, Could you help me to correct it, I'm new in Java, I've been practically all day making some Java exercises and I'm about to give up with this exercise, it's almost ready but still needs some corrections, basically, the objective of the program is that when the user places the pointer inside each circumference and when the user moves the mouse wheel, the internal circles of colors change in size according to the parameters that are specified in the main class and can never exceed the size of the circumference, the exercise is a bit more complicated because, In addition, circumferences and internal circles of colors should change in size and shape if the size of the window is changed. Only the second Class can be modified because the main class is already given.
I would appreciate it if you could help me, by the way, I am sorry if I made some grammatical errors, English is not my native language
package Hw03_Balloon;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.JFrame;
public class BalloonTest extends JFrame {
private Balloon ct_red, ct_green, ct_blue;
public BalloonTest() {
setTitle("Balloon Test");
setSize(450, 250);
setupWidgets();
setupEvents();
setVisible(true);
}
private void setupEvents() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private void setupWidgets() {
ct_red =new Balloon(100, 0, 100, Color.RED, 1);
ct_green =new Balloon(20, 0, 100, Color.BLUE, 5);
ct_blue =new Balloon(20, 0, 100, Color.ORANGE, 10);
setLayout(new GridLayout(1,3));
add(ct_red);
add(ct_green);
add(ct_blue);
}
public static void main(String[] args) {
new BalloonTest();
}
}
And this is the second class I used
package Hw03_Balloon;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.JComponent;
public class Balloon extends JComponent{
private int value;
private int min;
private int max;
private Color col;
private int speed;
public int r1;
public Balloon(int value, int min, int max, Color col, int speed) {
this.value=value;
this.min=min;
this.max=max;
this.col=col;
this.speed=speed;
}
public void paint(Graphics g) {
int w =getWidth();
int h =getHeight();
int x=w/2;
int y=h/2;
int r1=(int) ((double)value/100*24*w/29);
int r2=(int) ((double) value/100*40*h/71);
System.out.println(r1);
x = x-(r1/2);
y = y-(r2/2);
g.setColor(col);
g.fillOval(x, y, r1, r2);
g.setColor(Color.BLACK);
x=w/2;
y=h/2;
r1=24*w/29;
r2=40*h/71;
x = x-(r1/2);
y = y-(r2/2);
g.drawOval(x, y, r1, r2);
this.r1=r1;
setupEvents();
}
private void setupEvents() {
addMouseWheelListener(new MouseWheelListener() {
public void mouseWheelMoved(MouseWheelEvent ev) {
if(value+ev.getWheelRotation()>=0 && value+ev.getWheelRotation()<=r1) {
value -= speed*ev.getWheelRotation();
if (value<=0) value=0+1;
if (value>=r1) value=r1-1;
repaint();
}
}
});
}
}
In Ballon#setupEvents
you create and add a mouse wheel listener to the component, right? In a component you can multiple listeners (in your case, mouse wheel) which are going to be fired when mouse wheel is moved. You call this method (Ballon#setupEvents
) inside JComponent#paint()
method. Therefore, every time paint()
method is called, a new mouse wheel listener is added to the component. The result is that your component has multiple listeners. That's why you get this strange behavior.
Solution: Have only one mouse wheel listener added to the component. Also, do not @Override
paint()
method. @Override
JComponent#paintComponent(Graphics g)
method.
About circles having bigger bounds than the black one:
I searched it a bit, and i can say you over-complicate it. As far as i can understand from these two lines:
int r1=(int) ((double) value/100 * 24*w/29);
int r2=(int) ((double) value/100 * 40*h/71);
Your variable value
is expressed into percentage. And here comes the "over-complicated" part. You just have to adjust this percentage by speed*mousewheelrotation
on each mouse wheel event. Simple as that.
P.S: I wish i could explain more what you did wrong, but i had hard time to find your logic, and i do not think it is necessary to make things complex.
Balloon.class:
public class Balloon extends JComponent{
private int value;
private int min;
private int max;
private Color col;
private int speed;
public int r1;
public Balloon(int value, int min, int max, Color col, int speed) {
this.value=value;
this.min=min;
this.max=max;
this.col=col;
this.speed=speed;
setupEvents(); //Call only 1 time in constructor
this.r1=24*(getWidth()/2)/29; //Declare it one time
}
@Override
public void paintComponent(Graphics g) {
int w =getWidth();
int h =getHeight();
int x=w/2;
int y=h/2;
int r1=(int) ((double)value/100*24*w/29);
int r2=(int) ((double) value/100*40*h/71);
System.out.println(r1);
x = x-(r1/2);
y = y-(r2/2);
g.setColor(col);
g.fillOval(x, y, r1, r2);
g.setColor(Color.BLACK);
x=w/2;
y=h/2;
r1=24*w/29;
r2=40*h/71;
x = x-(r1/2);
y = y-(r2/2);
g.drawOval(x, y, r1, r2);
}
private void setupEvents() {
addMouseWheelListener(new MouseWheelListener() {
public void mouseWheelMoved(MouseWheelEvent ev) {
value -= speed*ev.getWheelRotation();
if (value<=0)
value=speed; //Minimum
if (value>=100)
value=100; //Maximum
repaint();
}
});
}
}