I wrote a program to play Maxwell's Demon. It should have a window with 2 sides and a few
dots running around bouncing off the walls. There's a wall in the middle. When you click a
button, a gap opens up in the wall (until you unclick). This should allow a person to try
to get more balls on one side than the other. You can display the count on each side.
This is the main class, I have two other classes one is Dot ( where I make my dots move, and
tell how fast), and the other one is BLueDot(where i create the blue dots).
So what I want is that to display the counts of the balls on each sides? Or How many we
got (balls) on each side of the walls?
Main Program
package dotChaser;
//DotChaser.java
//This program does some simple animation where a dot move around
//the blue dots.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DotChaser extends JFrame implements ActionListener, KeyListener
{
javax.swing.Timer time; // generates ticks that drive the animation
protected double deltaT = 0.020; // how much time for each tick
BlueDot[] blues; // holds the blue dots
int blueCounter = 0; // number of blue dots
//Label howMany = new Label();
JTextField tf;// The text field for the key listener
boolean open; // open= true part. pass through, open = false part. dont pass through
public static void main(String[] args)
{
DotChaser d = new DotChaser();
}
// constructor
public DotChaser()
{
Dot.theDotChaser = this;
//time managment
time = new javax.swing.Timer((int)(1000*deltaT), this);
time.start();
blues= new BlueDot[200] ;
tf = new JTextField("---------------");
add(tf);
tf.addKeyListener(this);
for(int i = 0; i<20; i++)
{blues[blueCounter++] = new BlueDot();
//count++;
//howMany.setText(ballReport());
setLayout( new FlowLayout());
setTitle("Dot Chaser!");
setSize(new Dimension(600,600));
setVisible(true);}
}
// the work its doing
public void actionPerformed(ActionEvent e)
{
if (e.getSource()==time){doTime();}
repaint();
}
// key listener mouse motion
public void keyTyped( KeyEvent k ) { }
public void keyPressed( KeyEvent k )
{
System.out.println("you pressed key="+k.getKeyChar());
open=true;
}
public void keyReleased( KeyEvent k )
{
System.out.println("you released key="+k.getKeyChar());
open=false;
}
// the clock ticked, so tell all the dots to move a little
public void doTime()
{
for (int i= 0; i<blueCounter; i++)
{
blues[i].move(deltaT);
}
}
// make another blue dot (and add it to the blues array)
public void doMoreDots()
{blues[blueCounter++] = new BlueDot();}
// paint all the dots
public void paint(Graphics g)
{
super.paint(g);
for (int i= 0; i<blueCounter; i++)
{
blues[i].drawMe(g);
}
{
// draw the wall
g.setColor( Color.pink );
g.fillRect( 250, 40, 90, 200 );
g.fillRect( 250, 400, 90, 300 );
}
// close wall when false
if ( open == false)
{
g.fillRect(250, 200, 90, 200);
g.fillRect(250, 400, 90, 300);
}
}
}
As I am getting you need to count the total number of dots each side.
The total number of dots you can get from the Array where you are keeping.Add a counter in the below method which will keep the number of dots total.
static int count=0;
public void doMoreDots()
{
blues[blueCounter++] = new BlueDot();
count++;
}
Now ,you need to find out the count for each side,here I will suggest that use another 2 separate counter in that class where you can track moving dots.
Hope it will help you.
Related
I am trying to draw 8 red squares in a specific pattern in java.
And I am expecting an output like this:
Alteration.java
And this is what I have tried so far:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Alteration {
private int xGrid;
private int yGrid;
public static void main(String[] args) {
Alteration a = new Alteration();
a.display();
}
public void display() {
JFrame frame = new JFrame("Alteration");
Background bg = new Background();
frame.setSize(400, 200);
frame.getContentPane().add(bg);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
for (int i = 0; i < 2; i++) {
for (int s = 0; s < 4; s++) {
bg.repaint();
xGrid += 50;
yGrid += 50;
}
yGrid = 0;
}
}
class Background extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.RED);
g.fillRect(xGrid, yGrid, 50, 50);
}
}
}
However, when I compile the code and run it, I only see one red square at the position of (400, 0)
That was not what I expected to output and I dont know why. I've done plenty of research and I still cannot find the correct answer to my problem, can anyone help?
EDIT: I added a code in the paintComponent method.
public void paintComponent(Graphics g) {
g.setColor(Color.RED);
g.fillRect(xGrid, yGrid, 50, 50);
System.out.println(xGrid+" "+yGrid);
}
Output (in the command prompt): 400 0
The double for loop runs 8 loops in total.
so bg.repaint() is called 8 times.
However the command prompt prints only 1 line.
I'm confused by this, why does the command prompt only print 1 line despite the fact that the paintComponent method was called 8 times?
I have a graphic which consists of a horizontal line of circles of different sizes at regular intervals. Here is the picture:
I am trying to recreate this graphic using recursion as opposed to the if statements used in my code but after trying, am unsure about how to do this. Would love some help, here is my code:
package weekFour;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.*;
#SuppressWarnings("serial")
public class Circle extends JPanel {
private int circX = 10;
private static int windowW = 1700;
private static int windowH = 1000;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //smoothes out edges
Color c5 = new Color(50, 50, 50);
Color c4 = new Color(100, 100, 100);
Color c3 = new Color(150, 150, 150);
Color c2 = new Color(200, 200, 200);
Color c1= new Color(250, 250, 250);
for (int i = 0; i < 1; i++) {
g2.setColor(c1);
g2.fillOval(522 + 75*i, 138, 666, 666);
g2.setColor(c1);
g2.drawOval(522 + 75*i, 138, 666, 666);
}
for (int i = 0; i < 3; i++) {
g2.setColor(c2);
g2.fillOval(244 + 522*i, 365, 180, 180);
g2.setColor(c2);
g2.drawOval(244 + 522*i, 365, 180, 180);
}
for (int i = 0; i < 10; i++) {
g2.setColor(c3);
g2.fillOval(130 + 174*i, 428, 60, 60);
g2.setColor(c3);
g2.drawOval(130 + 174*i, 428, 60, 60);
}
for (int i = 0; i < 25; i++) {
g2.setColor(c4);
g2.fillOval(60 + 87*i, 444, 25, 25);
g2.setColor(c4);
g2.drawOval(60 + 87*i, 444, 25, 25);
}
for (int i = 0; i < 120; i++) {
g2.setColor(c5);
g2.fillOval(circX + 29*i, 450, 12, 12);
g2.setColor(c5);
g2.drawOval(circX + 29*i, 450, 12, 12);
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("MyTaskToo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Circle());
frame.setSize(windowW, windowH);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Thanks for your time.
This is how I went about this problem, although we had to do it with green circles as opposed to grey circles but it's not that different.
N.B: Sorry for the appealing comments for sometimes trivial things but we get marks for commenting and it is better to be safe than sorry. Maybe they change you some insight into the thought process.
Here is the main method that starts the programme and sets out the window information.
public class Q2Main {
public static void main(String[] args) {
// here we are just setting out the window end putting the circles drawin in Q2Circles into this window.
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(1000, 500);
window.getContentPane().add(new Q2Circles(5));
window.setVisible(true);
}}
This is where the magic happens:
public class Q2Circles extends JPanel {
// this allows the user to specify how many loops of recursion they want the programme to complete before finishing
int recursionsToDo;
public Q2Circles(int recursionMax){
super();
recursionsToDo = recursionMax;
}
/*
this method is automatically called when we run the constructor as it inherits from the JFram superclass. here
we are setting out the size of the circle by getting the size of the window to make it proportional to the rest
of the screen and circles.
we then pass these values into the drawCircle method to draw the circle
*/
public void paintComponent(Graphics g){
Rectangle rectangle = this.getBounds();
int diameter = rectangle.width/3;
int centerPoint = rectangle.width/2;
drawCircle(g, 1, centerPoint, diameter);
}
/*
This method is where the magic of the programme really takes place. first of all we make sure we haven't completed
the necessary recursions. we the set the color by dividing it by the amount of times we have recursed, this will
have the affect of getting darker the more times the method recurses. we then sset the color. finaly we fill the
oval (draw the circle). because we want to move depending on the times it has recursed and size of the previous
we do it based on the size of the elements from the previous call to this method. Getting the right numbers
though was just alot of trial and error.
we then increment the recursion counter so that we know how many times we have recursed and that can then be
used at different points where needed. e.g for setting the color.
each recursive call used the dimension of the other recursive calls to make the whole picture. Although the
first recursive call creates the circles on the right of the screen. the second call draws the circle on the
left of the screen and the last one does the circles in the middle, they all use eachothers values to make it
complete. without one recursive step, more is missing than just what is created by that recursive call on its own.
in all honesty though, there is alot of duplication, like the large middlecircle.
*/
public void drawCircle(Graphics g, int amountOfRecursions, int center, int diameter){
if (amountOfRecursions <= recursionsToDo){
int recursionsCount = amountOfRecursions;
int greenColor = Math.round(225 / (amountOfRecursions));
g.setColor(new Color(0, greenColor, 0));
g.fillOval(center - (diameter/2), 200 - (diameter/2), diameter, diameter);
recursionsCount++;
drawCircle(g, recursionsCount, Math.round(center + diameter), diameter/3);
drawCircle(g, recursionsCount, Math.round(center - diameter), diameter/3);
drawCircle(g, recursionsCount, Math.round(center), diameter/3);
}
}}
I'm kind of new to Java and OO programming, here is the code of moving black and white balls problem. First let me explain the program that I want in the output: there are n balls(for example 6 balls) on the window, one black and one white, in each move we only are allowed to move just one ball and this movement should be shown on the screen, and at the end all the white balls should be on one side and all the black balls should be on the other side. Here is an example of six balls:
I have written the program and it seems working good and no flaws in the algorithm, but my problem is that I can't show animation of the movement of the balls, in each movement one ball should swap its place with its neighbor ball, but all I get is the final arrangements of the balls. Please someone help me with the animation part. I would be really thankful for that.
code:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.*;
public class DrawPanel extends JPanel implements ActionListener
{
Timer myTimer = new Timer(2000, this);
public static final int NUMBER_OF_CIRCLES = 10; //number of circles which are to moved
static int[] circles = new int[NUMBER_OF_CIRCLES];
public void paintComponent(Graphics g)
{
int x = 0; //start point of circles;
int length = 40; //diagonal of the circles
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Ellipse2D circle;
//painting n circles based on the array
for(int index = 0; index<10; index++)
{
if(circles[index] == 0){ //if the element of the arrayy is 0 then draw a void circle
circle = new Ellipse2D.Double(x, 120, length, length);
g2.draw(circle);
}
else if(circles[index] == 1){ //if the element of the array is 1 them draw a filled circle
circle = new Ellipse2D.Double(x, 120, length, length);
g2.fill(circle);
}
x += 45; //increas start pont of the next circle 45 pixles
}
myTimer.start();
}
public void actionPerformed(ActionEvent e)
{
int tmp; //template for swaping elements
int condition; //condition of the forS
arrayFill(circles); //fills the array based on the writen method, one 1 and one 0 like: 0 1 0 1 0 1 0 1
//here is the part which works good, it changes palces of an elemen at time.
//at the end of this part the array would be like: 1 1 1 1 0 0 0 0
if(NUMBER_OF_CIRCLES % 2 == 0)
condition = circles.length/2 -1;
else
condition = circles.length/2;
for(int i = circles.length-1, k = 1; i>condition; i--, k++)
{
for(int j = i - k; j<i ;j++)
{
tmp = circles[j];
circles[j] = circles[j+1];
circles[j+1] = tmp;
//if we call arrayPrint method it will print the array but I don't know why repaint is not working here
//arrayPrint(circles);
repaint();
}
}
}
//fills the array, one 1 and one 0. Example: 0 1 0 1 0 1 0 1 0 1
public static void arrayFill(int[] array)
{
for(int i = 0; i<array.length; i++)
{
if( i%2 == 0)
array[i] = 0;
else
array[i] = 1;
}
}
}//end of class
And the main Class:
import javax.swing.JFrame;
public class BlackAndWhiteBallsMoving {
public static void main(String[] args)
{
DrawPanel myPanel = new DrawPanel();
JFrame myFrame = new JFrame();
myFrame.add(myPanel);
myFrame.setSize(600, 500);
myFrame.setTitle("Black And White Balls Moving");
myFrame.setVisible(true);
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}//end of class
The events triggered by the Timer are performed on the same event thread as the repaints. Calling repaint does not actively perform a paint event, rather it queues one for later. When you call your repaints from within the timer event, they will only get executed once the timer event is completed.
What you need to do is refactor your loop so that only a single swap is performed each time the timer triggers. I've done this for you as an example:
public class DrawPanel extends JPanel implements ActionListener {
public static final int NUMBER_OF_CIRCLES = 10;
Timer myTimer = new Timer(500, this);
int[] circles = new int[NUMBER_OF_CIRCLES];
public DrawPanel() {
arrayFill(circles);
if(NUMBER_OF_CIRCLES % 2 == 0) {
condition = circles.length/2 -1;
} else {
condition = circles.length/2;
}
i = circles.length - 1;
k = 1;
myTimer.start();
}
int i, j, k;
int condition;
boolean outer = true;
#Override
public void actionPerformed(ActionEvent e) {
if(outer) {
if(i > condition) {
j = i - k; // set j
outer = false; // and move to the inner loop swap
} else {
myTimer.stop(); // the outer loop is done so stop the timer
}
}
if(!outer) {
int tmp = circles[j];
circles[j] = circles[j+1];
circles[j+1] = tmp;
repaint();
j++;
if(j >= i) {
i--;
k++;
outer = true; // move to the outer condition
} // next time the timer triggers
}
}
#Override
protected void paintComponent(Graphics g) {
int x = 0;
int length = 40;
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Ellipse2D circle;
for(int index = 0; index<10; index++) {
if(circles[index] == 0){
circle = new Ellipse2D.Double(x, 120, length, length);
g2.draw(circle);
} else if(circles[index] == 1){
circle = new Ellipse2D.Double(x, 120, length, length);
g2.fill(circle);
}
x += 45;
}
//myTimer.start();
}
public static void arrayFill(int[] array) {
for(int i = 0; i<array.length; i++) {
if( i%2 == 0) {
array[i] = 0;
} else {
array[i] = 1;
}
}
}
}
(I'm sure it could be factored another way.)
Also:
I added #Override annotations which you should use. Doing so will warn you when you make certain mistakes. (Like misspelling a method name or incorrectly declaring its signature.)
I moved circles to an instance variable because I don't see a reason it should be static. It is part of the state of the DrawPanel instance.
I created a constructor which initializes variables such as circles.
paintComponent is a protected method and it should remain so unless there is a reason to promote it to public.
(I removed your comments and changed the bracing style just to condense the code for my answer.)
As a side note, you should read the tutorial Initial Threads. You are not creating your GUI on the Swing event thread. Basically you need to wrap your code in main inside a call to invokeLater:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// create and show your GUI
}
});
}
The basic problem is in your actionPerformed method. Your two for loops are rearranging the array to its final arrangement very quickly. Each loop iteration will take a matter of nanoseconds to milliseconds to complete (it depends on how the repaint() method works). The entire process is finished in less than 50 milliseconds or so. That's too fast for your eyes to keep up.
Basically, the repaint() method is working, but it's working too fast for human eyes to keep up.
If you break up the for loops into something that does one step of the algorithm each time it's called, you can trigger that from a timer and see the animation at a human-detectable speed.
add a paint thread. it should always call repaint() like,
new Thread(){ // this can be started on main or constructor of object
public void run(){
while(true){
repaint();
try {
Thread.sleep(50);
} catch(Exception e){ }
}
}
}.start();
and then, on action performed, mark moving objects like movingObjects, keep a animate_x = 0 and keep a boolean variable like existAnimation
then on paintComponent, increase animate_x
animate_x = animate_x + 1;
if (animate_x >= MAX_WIDTH_OF_ANIMATION){
existAnimation = false;
}
and use this existAnimation, animate_x and movingObjects
like,
public void paintComponent(Graphics g)
{
int x = 0; //start point of circles;
int length = 40; //diagonal of the circles
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Ellipse2D circle;
//painting n circles based on the array
for(int index = 0; index<10; index++)
{
int paint_x = x;
if (movingObjects.has(circles[index])){
paint_x += animate_x;
}
if(circles[index] == 0){ //if the element of the arrayy is 0 then draw a void circle
circle = new Ellipse2D.Double(paint_x, 120, length, length);
g2.draw(circle);
}
else if(circles[index] == 1){ //if the element of the array is 1 them draw a filled circle
circle = new Ellipse2D.Double(paint_x, 120, length, length);
g2.fill(circle);
}
x += 45; //increas start pont of the next circle 45 pixles
}
myTimer.start();
}
So basically I have my main code (TuringSimLS.java) and my animation code (Animation.java)
Animation.java creates a number of boxes (dependent on the length of an array in my TuringSimLS.java. The length of this array does not change). Now there is a variable in my TuringSimLS.java which has a variable pointer (this one changes). This pointer decides which box in my animation is in the middle. For example if there are 7 boxes, and the pointer is 6, the box in the middle will have one box to it's right and five to it's left (making it the 6th of boxes). When the pointer changes all the boxes move until the required box is in the middle. The problem is that my method (which changes the value of pointer) finishes running and then my animation starts. So no animation ends up happening (as the pointer's value returns to the value it initially was in the beginning). I need my animation to happen as soon as the variable pointer's value changes.
Part of my main code (TuringSimLS.java)
public static int[] POINTER = new int[1]; // My global variable. How i tell my Animation.java
// What the current value of pointer is
static String[] processTape(String[][] Quints, String[] Tape, int TapeInitial) {
int pointer = TapeInitial;
POINTER[0] = pointer;
...
...
Animation.main(Quints, Tape, TapeInitial); // <- animation started here
while (!currentDir.equals("H")) { // <- IMPORTANT WHILE LOOP as mentioned below
for (String[] Quint : Quints) {
if (Quint[0].equals(currentState) && Quint[1].equals(Tape[pointer])) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(TuringSimLS.class.getName()).log(Level.SEVERE, null, ex);
}
Tape[pointer] = Quint[3];
...
...
if (currentDir.equals("R")) {pointer += 1;} // pointer changes here
if (currentDir.equals("L")) {pointer -= 1;}
symbolFound = true;
startFound = true;
POINTER[0] = pointer;
//Here is where i want the animation to start as in
//moving of the already drawn boxes
//System.out.println(POINTER[0]);
break;
}
}
}
return Tape;
}
Here is my Animition.java:
package turingsimls;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*; // Imports ActionEvent, ActionListener
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Animation extends JPanel implements ActionListener
{
Timer tm = new Timer(5, this);
int x = 0;
int xtri = 300;
int ytri = 30;
public static int[] C = new int[1];
public static int[] Number = new int[1];
public static int[] POINTER2 = new int[1];
public void paintComponent(Graphics g) {
super.paintComponent(g); //9
g.setColor(Color.WHITE);
for (int i = 0; i < Number[0]; i++)
g.fillRect((280 + (40 + 20)*i) + C[0], 50, 40, 30);
int xpoly[] = {xtri , xtri + 10, xtri - 10 };
int ypoly[] = {ytri, ytri - 10, ytri - 10};
g.drawPolygon(xpoly, ypoly, xpoly.length);
tm.start();
}
public void actionPerformed (ActionEvent e) {
//Here C changes according to the pointer
//Which in turn changes the XPos of the rectangles
if (!(C[0] == -60 * TuringSimLS.POINTER[0])){
if ((C[0] < -60 * TuringSimLS.POINTER[0]))
C[0] += 10;
if ((C[0] > -60 * TuringSimLS.POINTER[0]))
C[0] -= 10;
}
System.out.println(C[0]);
System.out.println(TuringSimLS.POINTER[0]);
repaint();
}
public static void main(String[][] Quints, String[] Tape, int TapeInitial) {
Animation t = new Animation(); //2
JFrame jf = new JFrame();
jf.setTitle("Animation");
jf.setSize(600, 400);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(t);
Number[0] = Tape.length - 1;
C[0] = -60 * TapeInitial;
}
}
processTape() starts the animation and produces the first rectangles correctly. The problem is the entire "Important while loop" runs before actionPerformed() runs for the second time. So the animation doesnt process the changes of pointer.
This is just an exercise in mechanics. I am attempting to create three custom panels that control their own progress bar. It’s part of a time management program I am writing for myself to learn more about Java. The larger program uses dates input by the user to create the framework for the min/max of the progress bar. Both this program and the larger one exhibit the same behavior with multiple bars racing the clock.
The issue I am having is that if I have just one bar everything seems to work just fine, but when I have more than one everything seems to go bust. So I wrote this little program to test some things out. It’s very simple, takes three custom panels, gives them a label and uses a timer event to change the label and the position of the progress bar. My question is If the math lines up (System output shows the calculation) and I’m counting events every second (1000 milliseconds) why is everything beating the count down.
Please forgive my lack of form with my code. I’m more concerned with the logic than the form.
(Most of the below is cut from my larger program, so if you see extraneous bits they really do have a home)
Thank you in advance.
import javax.swing.*;
import javax.swing.Timer;
import java.awt.*;
import java.awt.Color;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
public class plaything extends JFrame implements ActionListener
{
myPanel[] mp = new myPanel[3];
JLabel[] jl = new JLabel[3];
short[] tim = new short[3];
short x = 0;
short t = 0; //used to stagger the clocks
short dateSaver; //holds temp dates
public plaything()
{
setSize(400, 350);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(3, 1) );
for(short x = 0; x < 3; x++)
{
mp[x] = new myPanel();
//sets all three bars to different 'times'
dateSaver = (short)(10 + t) ;
tim[x] = dateSaver;
mp[x].setMax( dateSaver );
jl[x] = new JLabel("Expires: " + dateSaver);
this.add(mp[x]);
mp[x].add( jl[x] );
t += 15; // 15 seconds
}
Timer time = new Timer(1000, this);
time.start();
}
public void actionPerformed(ActionEvent e)
{
if ( x < 60 )
{
x++;
}
else
{
x = 1;
}
for(myPanel m : mp)
{
m.tock();
}
for(short x = 0; x < 3; x++ )
{
mp[x].tock();
jl[x].setText( "" + --tim[x] );
}
}
private class myPanel extends JPanel
{
//Fields
private boolean finished = false;
//(x,y) Coords
private short x = 15;
private short y = 50;
//Size and shape
private short width = 200;
private short height = 10;
private short arcSize = 10;
//Bar essentials
private double max; //highest range of bar
private double fill = width; //sets filled in portion
private double tick; //calculates movement per event
private Color urgent = Color.BLUE; // Changes the color depending on the Urgency
//Constructors
public myPanel()
{
this.setBackground( Color.WHITE );
repaint();
}
//Mutators ( tick manipulation )
public void setMax( double maxIn )
{
this.max = maxIn;
System.out.println("Max: " + this.max );
this.tick = (double)width / this.max;
System.out.println("tick: " + this.tick );
}
//Methods
//Tick Manipulation
public void tock()
{
//Ends when zero
if( fill < 1 )
{
fill = width;
finished = true;
tick = 0;
urgent = Color.BLUE;
repaint();
}
else
{
fill -= tick ;
System.out.println("fill is " + fill );
repaint();
}
}
//Paint method
public void paint( Graphics g)
{
super.paint(g);
Graphics2D g2 = (Graphics2D)g;
g2.setColor( urgent );
g2.draw(new RoundRectangle2D.Double(x,y + 40, width, height, arcSize, arcSize) );
g2.fill(new RoundRectangle2D.Double(x,y + 40, fill , height, arcSize, arcSize) );
}
}
public static void main(String[] args)
{
plaything pt = new plaything();
pt.setVisible(true);
}
}
My real only concern is where is my logic flawed concerning the progression of the bars and the labels. I hope to find how to make both reach zero together. (two days of research and work on just the bars alone)
Again thank you for your time.
You're calling tock() twice every iteration of your Timer:
for(myPanel m : mp)
{
m.tock(); // ONCE
}
for(short x = 0; x < 3; x++ )
{
mp[x].tock(); // TWICE
jl[x].setText( "" + --tim[x] );
}
You should remove one call, or the other.