Question

I have a strange problem, I can figure it out.

here is my program running:

enter image description here

the clock on the right shouldn't even be there, it should just be string that displays the time. I create two different objects and add them to a content panel, then add the content panel to the JFrame. I also have a menu bar that I add to the JFrame and it shows up on the right side of the content pane. Here is my main class:

  class DigitalClock3DialsView extends DigitalClockView {
private static int caps[] = { BasicStroke.CAP_BUTT, 
    BasicStroke.CAP_SQUARE, BasicStroke.CAP_ROUND};
private static int joins[] = { BasicStroke.JOIN_MITER, 
    BasicStroke.JOIN_BEVEL, BasicStroke.JOIN_ROUND};
private static Color colors[] = {Color.gray, Color.pink, Color.lightGray};
private static BasicStroke bs1 = new BasicStroke(1.0f);

// three arms of clock
private Line2D lines[] = new Line2D[3];
private int rAmt[] = new int[lines.length];
private int speed[] = new int[lines.length];
private BasicStroke strokes[] = new BasicStroke[lines.length];
private GeneralPath path;
private Point2D[] pts;
private float size;
private Ellipse2D ellipse = new Ellipse2D.Double();
private BufferedImage bimg;

//variables to keep track if minutes or hours increased
private int oldMinute;
private int oldHour;

/**
 * init background
 */
public void init() {

    setBackground(Color.white);
}
/**
 * reset view: the shape of arms, etc
 */
public void reset(int w, int h) 
{

    oldMinute = 0;
    oldHour = 0;

    size = (w > h) ? h/6f : w/6f;
    for (int i = 0; i < lines.length; i++) {
        lines[i] = new Line2D.Float(0,0,size,0);
        strokes[i] = new BasicStroke(size/3, caps[i], joins[i]);
        rAmt[i] = 270;      // vertical
    }
    //speed of the 3 arms
    speed[0] = 6;   
    speed[1] = 6;
    speed[2] = 6;

    path = new GeneralPath();
    path.moveTo(size, -size/2);
    path.lineTo(size+size/2, 0);
    path.lineTo(size, +size/2);

    // YW: do not know how to show the regular clock view
    // with inc of 5 mins on the contour
    // can you help to fix this?

    ellipse.setFrame(w/2-size*2-4.5f,h/2-size*2-4.5f,size*4,size*4);
    double linApproxLen = 0.75 * size * 0.258819;   // sin(15 degree)
    PathIterator pi = ellipse.getPathIterator(null, linApproxLen);
    Point2D[] points = new Point2D[100];
    int num_pts = 0;
    while ( !pi.isDone() ) 
    {
        float[] pt = new float[6];
        switch ( pi.currentSegment(pt) ) {
            case FlatteningPathIterator.SEG_MOVETO:
            case FlatteningPathIterator.SEG_LINETO:
                points[num_pts] = new Point2D.Float(pt[0], pt[1]);
                num_pts++;
        }
        pi.next();
    }

    pts = new Point2D[num_pts];
    System.arraycopy(points, 0, pts, 0, num_pts);

}

private Point2D[] computePoints(double w, double h, int n)
{
    Point2D points[] = new Point2D[n];
    double angleDeltaRad = Math.PI * 2 / n;
    for (int i=0; i<n; i++)
    {
        double angleRad = i * angleDeltaRad;
        double ca = Math.cos(angleRad);
        double sa = Math.sin(angleRad);
        double x = sa * w/2;
        double y = ca * h/2;
        points[i] = new Point2D.Double(x,y);
    }
    return points;
}




public void paint(Graphics g) 
{   
    System.out.printf("seconds: %s, minutes: %d \n", second, minute);


    Dimension d = getSize();


    updateSecond(d.width, d.height);

    if(oldMinute < minute || (oldMinute==59 && minute==0))
    {
        oldMinute = minute;
        updateMinute(d.width, d.height);
    }
    if(oldHour < hour || (oldHour==12 && hour == 1) )
    {
        oldHour = hour;
        updateHour(d.width, d.height);
    }



    Graphics2D g2 = createGraphics2D(d.width, d.height);
    drawClockArms(d.width, d.height, g2);
    g2.dispose();
    g.drawImage(bimg, 0, 0, this);
}

public Graphics2D createGraphics2D(int w, int h) {
    // standard Java 2D code
    Graphics2D g2 = null;
    if (bimg == null || bimg.getWidth() != w || bimg.getHeight() != h) {
        bimg = (BufferedImage) createImage(w, h);
        reset(w, h);
    } 
    g2 = bimg.createGraphics();
    g2.setBackground(getBackground());
    g2.clearRect(0, 0, w, h);
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    return g2;
}

private void drawClockArms(int w, int h, Graphics2D g2) {

    ellipse.setFrame(w/2-size,h/2-size,size*2,size*2);
    g2.setColor(Color.black);
    g2.draw(ellipse);

    for (int i = 0; i < lines.length; i++) {
        AffineTransform at = AffineTransform.getTranslateInstance(w/2,h/2);
        at.rotate(Math.toRadians(rAmt[i]));
        g2.setStroke(strokes[i]);
        g2.setColor(colors[i]);
        g2.draw(at.createTransformedShape(lines[i]));
        g2.draw(at.createTransformedShape(path));
    }

    g2.setStroke(bs1);
    g2.setColor(Color.black);
    for (int i = 0; i < pts.length; i++) {
        ellipse.setFrame(pts[i].getX(), pts[i].getY(), 9, 9);
        g2.draw(ellipse);
    }
}

/**
 * step forward on the display: move arm forward
 */
  public void step(int w, int h) {
        for (int i = 0; i < lines.length; i++) 
        {
            rAmt[i] += speed[i];
            System.out.println(rAmt[i]);
            if (rAmt[i] == 360) {
                rAmt[i] = 0;
            } 
        }
    }   

public void updateSecond(int w, int h) {
        rAmt[0] += speed[0];
        if (rAmt[0] == 360) {
            rAmt[0] = 0;
        } 
}   
public void updateMinute(int w, int h) {
        rAmt[1] += speed[1];
        if (rAmt[1] == 360) {
            rAmt[1] = 0;
        } 
}   
public void updateHour(int w, int h) {
        rAmt[2] += speed[2];
        if (rAmt[2] == 360) {
            rAmt[2] = 0;
        } 
}   

}

and here is the parent class that extends JPanel:

/** 
 * Digital Clock view base classes
 */
abstract class DigitalClockView extends JPanel 
{
protected int second = 0;
protected int minute = 0;
protected int hour = 0;


public void draw() 
{
    this.repaint();
}


public void updateTime(int second, int minute, int hour)
{
    this.second = second;
    this.minute = minute;
    this.hour = hour;
}

public abstract void paint(Graphics g);
}

my menu buttons are showing on the right side when I use the menu bar. It's almost as if it is just cloning the view on the left side and showing it on the right side again. Why is this?

Was it helpful?

Solution

super.repaint()

Don't do that, as calling repaint from within a paint method has potential for danger. Call the super.paint(g) method inside of a paint(Graphics g) override.

Or even better yet, don't override paint but instead override your JPanel's paintComponent(Graphics g) method and call super.paintComponent(g). For graphics you must call the same super method as the overridden method, and you're not doing that.


Also and again, you should avoid use of null layout as this makes for very inflexible GUI's that while they might look good on one platform look terrible on most other platforms or screen resolutions and that are very difficult to update and maintain.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top