-1

I'm new to coding and right now am just doing it as a hobby. I've created an analog clock and I have a jlabel set up to tell me how many minutes have passed. However, I can't seem to figure out what I'm doing wrong with setText("....") to update the Jlabel. In short, it just isn't updating the label, it's stuck at the original minute.

Stackverflow has been essential for me getting as far as I have with this and I'm a little embarrassed I even have to ask this questions but I can't seem to find a solution.

I apologize if the answer is somewhere and I just haven't found it yet. What I think is probably the relevant bit of code is here...

        //Minute Counter
        JLabel label = new JLabel();
        System.out.println(getMinuteCount(secondAngle));
        label.setText(String.valueOf(getMinuteCount(secondAngle))+" minutes have passed.");
        add(label);

...and...

        public void rotate()
{
    double time = .01;
    minuteAngle = minuteAngle-time;
    hourAngle = hourAngle-time/12;
    secondAngle = secondAngle-time*60;
}

public int getMinuteCount(double secondAngle)
{
    int secondAngleInt = (int) secondAngle;
    if (secondAngleInt==91)
    {
        minuteCount = minuteCount + 1;
    }    

    return minuteCount;
}

However here is my entire code for reference. (Please excuse the unprofessional layout. I'm still learning :) )

Any help would be greatly appreciative. Have a great day!

public class Clock extends JPanel{

double hour = Double.parseDouble(JOptionPane.showInputDialog(null, "What hour is it?", "I need the time.", JOptionPane.PLAIN_MESSAGE));
double minutes = Double.parseDouble(JOptionPane.showInputDialog(null, "How many minutes have passed in this hour?", "I need the time.", JOptionPane.PLAIN_MESSAGE));
double Area = 400;
int minuteCount = 0;
int x0 = 300;
int y0 = 300;
double a = Math.sqrt(4*Area/Math.sqrt(3));
double h = a*Math.sqrt(3)/2;
double minuteAngle = 90-(360*minutes/60);
double hourAngle = 90-(360*hour/12);
double secondAngle = 90;

@Override
public void paint(Graphics g)
{
    super.paint(g);

    if (minuteAngle<0)
    {
        minuteAngle = 360 + minuteAngle;
    }

    if (hourAngle<0)
    {
        hourAngle = 360 + hourAngle;
    }

    if (secondAngle<0)
    {
        secondAngle = 360 + secondAngle;
    }

    //Draws the Second Hand Line
        Graphics2D secondLine = (Graphics2D) g;
        double[] secondEndpoints = getEndPoints(220+h, secondAngle);
        Shape secondl = new Line2D.Double(x0, y0, secondEndpoints[0], secondEndpoints[1]);
        secondLine.setColor(Color.red);
        secondLine.setStroke(new BasicStroke(2));
        secondLine.draw(secondl);

    //Draws the Minaute Hand Line
        Graphics2D minuteLine = (Graphics2D) g;
        double[] minuteEndpoints = getEndPoints(220, minuteAngle);
        Shape minutel = new Line2D.Double(x0, y0, minuteEndpoints[0], minuteEndpoints[1]);
        minuteLine.setColor(Color.black);
        minuteLine.setStroke(new BasicStroke(5));
        minuteLine.draw(minutel);

    //Draws the Minuate Hand Head
        Graphics2D minuteHead = (Graphics2D) g;
        Path2D.Double minutePath = new Path2D.Double();
        double[][] minuteHeadPoints = new double[3][2];
        minuteHeadPoints=getTriPoints(220, minuteAngle);
        minutePath.moveTo(minuteHeadPoints[0][0], minuteHeadPoints[0][1]);
        minutePath.lineTo(minuteHeadPoints[1][0], minuteHeadPoints[1][1]);
        minutePath.lineTo(minuteHeadPoints[2][0], minuteHeadPoints[2][1]);
        minutePath.lineTo(minuteHeadPoints[0][0], minuteHeadPoints[0][1]);
        minuteHead.setColor(Color.black);
        minuteHead.fill(minutePath);

    //Draws the Hour Hand Line
        Graphics2D line = (Graphics2D) g;
        double[] endpoints = getEndPoints(120, hourAngle);
        Shape l = new Line2D.Double(x0, y0, endpoints[0], endpoints[1]);
        line.setColor(Color.black);
        line.setStroke(new BasicStroke(5));
        line.draw(l);

    //Draws the Hour Hand Head
        Graphics2D tri = (Graphics2D) g;
        Path2D.Double path = new Path2D.Double();
        double[][] tripoints = new double[3][2];
        tripoints=getTriPoints(120, hourAngle);
        path.moveTo(tripoints[0][0], tripoints[0][1]);
        path.lineTo(tripoints[1][0], tripoints[1][1]);
        path.lineTo(tripoints[2][0], tripoints[2][1]);
        path.lineTo(tripoints[0][0], tripoints[0][1]);
        tri.setColor(Color.black);
        tri.fill(path);

    //Draws the Clock
        Graphics2D object = (Graphics2D) g;
        object.setColor(Color.black);
        object.fillOval(x0-10,y0-10,20,20);

        Graphics2D clockedge = (Graphics2D) g;
        clockedge.setColor(Color.black);
        clockedge.setStroke(new BasicStroke(2));
        clockedge.drawOval(x0-230,y0-230,460,460);

    //Minute Counter
        JLabel label = new JLabel();
        System.out.println(getMinuteCount(secondAngle));
        label.setText(String.valueOf(getMinuteCount(secondAngle))+" minutes have passed.");
        add(label);
}

public static void main(String[] args)throws InterruptedException
{
    JFrame frame = new JFrame("Some Shapes");
    Clock clock = new Clock();
    frame.add(clock);
    frame.setSize(600, 600);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    int j=0;
    while (true)
    {
        clock.rotate();
        clock.repaint();
        Thread.sleep(1);
    }
}

public double[] getEndPoints(double radius, double angle)
{
    double[] endpoints = new double[2];
    double a = Math.sqrt(4*Area/Math.sqrt(3));
    double h = a*Math.sqrt(3)/2;

    if (angle%360==0)
    {
        endpoints[0]=x0+radius-h;
        endpoints[1]=y0;
    }

    if (0<angle%360 && angle%360<90)
    {
        endpoints[0]=x0+(radius-h)*Math.cos(Math.toRadians(angle));
        endpoints[1]=y0-(radius-h)*Math.sin(Math.toRadians(angle));
    }

    if (angle%360==90)
    {
        endpoints[0]=x0;
        endpoints[1]=y0-radius+h;
    }

    if (90<angle%360 && angle%360<180)
    {
        double phi = 180-angle;
        endpoints[0]=x0-(radius-h)*Math.cos(Math.toRadians(phi));
        endpoints[1]=y0-(radius-h)*Math.sin(Math.toRadians(phi));
    }

    if (angle%360==180)
    {
        endpoints[0]=x0-radius+h;
        endpoints[1]=y0;
    }

    if (180<angle%360 && angle%360<270)
    {
        double phi = angle-180;
        endpoints[0]=x0-(radius-h)*Math.cos(Math.toRadians(phi));
        endpoints[1]=y0+(radius-h)*Math.sin(Math.toRadians(phi));
    }

    if (angle%360==270)
    {
        endpoints[0]=x0;
        endpoints[1]=y0+radius-h;
    }

    if (270<angle%360 && angle%360<360)
    {
        double phi = 360-angle;
        endpoints[0]=x0+(radius-h)*Math.cos(Math.toRadians(phi));
        endpoints[1]=y0+(radius-h)*Math.sin(Math.toRadians(phi));
    }

    return endpoints;
}

public double[][] getTriPoints(double radius, double angle)
{
    double a = Math.sqrt(4*Area/Math.sqrt(3));
    double[][] tripoints = new double[3][2];
    double h = a*Math.sqrt(3)/2;

    if (angle%360==0)
    {
        tripoints[0][0]=x0+radius;
        tripoints[0][1]=y0;
        tripoints[1][0]=x0+radius-h;
        tripoints[1][1]=y0+a/2;
        tripoints[2][0]=x0+radius-h;
        tripoints[2][1]=y0-a/2;
    }

    if (0<angle%360 && angle%360<90)
    {
        tripoints[0][0]=x0+radius*Math.cos(Math.toRadians(angle));
        tripoints[0][1]=y0-radius*Math.sin(Math.toRadians(angle));
        tripoints[1][0]=x0+radius*Math.cos(Math.toRadians(angle))-a*Math.cos(Math.toRadians(30+angle));
        tripoints[1][1]=y0-radius*Math.sin(Math.toRadians(angle))+a*Math.sin(Math.toRadians(30+angle));
        tripoints[2][0]=x0+radius*Math.cos(Math.toRadians(angle))-a*Math.cos(Math.toRadians(angle-30));
        tripoints[2][1]=y0-radius*Math.sin(Math.toRadians(angle))+a*Math.sin(Math.toRadians(angle-30));
    }

    if (angle%360==90)
    {
        tripoints[0][0]=x0;
        tripoints[0][1]=y0-radius;
        tripoints[1][0]=x0+a/2;
        tripoints[1][1]=y0-radius+h;
        tripoints[2][0]=x0-a/2;
        tripoints[2][1]=y0-radius+h;
    }

    if (90<angle%360 && angle%360<180)
    {
        double phi = 180-angle;
        tripoints[0][0]=x0-radius*Math.cos(Math.toRadians(phi));
        tripoints[0][1]=y0-radius*Math.sin(Math.toRadians(phi));
        tripoints[1][0]=x0-radius*Math.cos(Math.toRadians(phi))+a*Math.cos(Math.toRadians(30+phi));
        tripoints[1][1]=y0-radius*Math.sin(Math.toRadians(phi))+a*Math.sin(Math.toRadians(30+phi));
        tripoints[2][0]=x0-radius*Math.cos(Math.toRadians(phi))+a*Math.cos(Math.toRadians(phi-30));
        tripoints[2][1]=y0-radius*Math.sin(Math.toRadians(phi))+a*Math.sin(Math.toRadians(phi-30));
    }

    if (angle%360==180)
    {
        tripoints[0][0]=x0-radius;
        tripoints[0][1]=y0;
        tripoints[1][0]=x0-radius+h;
        tripoints[1][1]=y0-a/2;
        tripoints[2][0]=x0-radius+h;
        tripoints[2][1]=y0+a/2;
    }

    if (180<angle%360 && angle%360<270)
    {
        double phi = angle-180;
        tripoints[0][0]=x0-radius*Math.cos(Math.toRadians(phi));
        tripoints[0][1]=y0+radius*Math.sin(Math.toRadians(phi));
        tripoints[1][0]=x0-radius*Math.cos(Math.toRadians(phi))+a*Math.cos(Math.toRadians(30+phi));
        tripoints[1][1]=y0+radius*Math.sin(Math.toRadians(phi))-a*Math.sin(Math.toRadians(30+phi));
        tripoints[2][0]=x0-radius*Math.cos(Math.toRadians(phi))+a*Math.cos(Math.toRadians(phi-30));
        tripoints[2][1]=y0+radius*Math.sin(Math.toRadians(phi))-a*Math.sin(Math.toRadians(phi-30));
    }

    if (angle%360==270)
    {
        tripoints[0][0]=x0;
        tripoints[0][1]=y0+radius;
        tripoints[1][0]=x0-a/2;
        tripoints[1][1]=y0+radius-h;
        tripoints[2][0]=x0+a/2;
        tripoints[2][1]=y0+radius-h;
    }

    if (270<angle%360 && angle%360<360)
    {
        double phi = 360-angle;
        tripoints[0][0]=x0+radius*Math.cos(Math.toRadians(phi));
        tripoints[0][1]=y0+radius*Math.sin(Math.toRadians(phi));
        tripoints[1][0]=x0+radius*Math.cos(Math.toRadians(phi))-a*Math.cos(Math.toRadians(30+phi));
        tripoints[1][1]=y0+radius*Math.sin(Math.toRadians(phi))-a*Math.sin(Math.toRadians(30+phi));
        tripoints[2][0]=x0+radius*Math.cos(Math.toRadians(phi))-a*Math.cos(Math.toRadians(phi-30));
        tripoints[2][1]=y0+radius*Math.sin(Math.toRadians(phi))-a*Math.sin(Math.toRadians(phi-30));
    }

    return tripoints;
}

public void rotate()
{
    double time = .01;
    minuteAngle = minuteAngle-time;
    hourAngle = hourAngle-time/12;
    secondAngle = secondAngle-time*60;
}

public int getMinuteCount(double secondAngle)
{
    int secondAngleInt = (int) secondAngle;
    if (secondAngleInt==91)
    {
        minuteCount = minuteCount + 1;
    }    

    return minuteCount;
}

}

  • 1
    I see where you set the original text of the label when you create it. I do not see where you use setText to keep updating the text every time a new second passes. – nhouser9 Oct 25 '16 at 21:29
  • So I guess this is where my misunderstanding lies. I thought that when I ask it to repaint Clock that is goes through everything in paint method all over again - i.e. it updates the setText method with the new getMinuteCount...I guess that's not whats going on though haha – Luke Keltner Oct 25 '16 at 21:31
  • First of all you should override paintComponent, not paint. Second of all think about this for a second - you are adding a new label EVERY TIME paint is called. That will be happening like 60 times per second. That seems very bad. Instead add one label and then store a reference to it. Call setText on the reference from within the paintComponent method. – nhouser9 Oct 25 '16 at 21:53

1 Answers1

0
public static void main(String[] args)throws InterruptedException
{
    JFrame frame = new JFrame("Some Shapes");
    Clock clock = new Clock();
    frame.add(clock);
    frame.setSize(600, 600);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    int j=0;
    while (true)
    {
        clock.rotate();
        clock.repaint();
        Thread.sleep(1);
    }
}

You are painting anything from outside the Event Dispatch Thread (EDT).

In Swing the EDT is the only thread who can actually paint on the screen. it is automatically started when you call setVisible(true) on the Frame.

So if you want somthing to change on he screen you must enqueue the change in the EDT. You need to use SwingUtilities:

 while (true)
    {
        clock.rotate();
        SwingUtilities.runLater(()->clock.repaint());
        Thread.sleep(1);
    }
Timothy Truckle
  • 15,071
  • 2
  • 27
  • 51