Surangie
Surangie

Reputation: 59

Understanding paintComponent

UPDATE 19/01/14(for people who has issues like this one)
The problem I described under originated from the fact that my circle class extends JPanel. So every circle I create from this class is in fact its own panel. Therefore by adding a layout I could see both circles. I've learned now that its Wiser to have a separate "board class" that extends JPanel, and the let the circles, in this case, extend nothing. That way I can implement a drawMySelf method in the circleclass and draw them in my board. This way I can have various geometric objects in the same panel!
UPDATE END.

I'm doing a task where I need to draw two circles. These circles are supposed to relocate randomly when I resize my frame. And needs to have a line between their centers which states the distance. I'm getting trouble with my class for the circles. When I add my custom circles to my testprogram, only one of them appears. I can't figure out why. I think there's an error in my code making the program skip some of it. because I only get one circle to appear. Can anyone see what is wrong with this code?

Keep in mind I'm supposed to use the tools I have learned so far. JPanel, JFrame, Overriding paintComponent().

The circle Class:

    package oppgave4;
    import javax.swing.*;
    import java.awt.*;

    public class Circle extends JPanel {
    
    public static final int OVAL = 1;
    public static final int ANOTHEROVAL = 2;
    
    public int OVALCENTER = 0;
    public int ANOTHEROVALCENTER = 0;
    
    private int type = 1;
    private boolean filled = false;
    
    public Circle(){
        
    }
    
    public Circle(int type){
        this.type = type;
    }
    
    public Circle(int type, boolean filled){
        this.type = type;
        this.filled = filled;
    }
    
    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        
        int width = getWidth();
        int height = getHeight();
        int randomWidth = (int)(width * Math.random());
        int randomHeight = (int)(height * Math.random());
        
        switch (type){
        case OVAL:
            g.setColor(Color.BLUE);
            if(filled)
                g.fillOval(randomWidth, randomHeight, 30, 30);    
            else
                g.drawOval(randomWidth, randomHeight, 30, 30);
      
            
        case ANOTHEROVAL:
            g.setColor(Color.RED);
                if(filled)
                    g.fillOval(randomWidth, randomHeight, 30, 30);
                else
                    g.drawOval(randomWidth, randomHeight, 30, 30);
                break;
            
        }
    }
    
}

And the test program: When I run this, only the red circle will appear.

    package oppgave4;
    import javax.swing.*;
    import java.awt.*;

    public class TestProgram extends JFrame {
        public TestProgram(){
        add(new Circle(Circle.OVAL));
        add(new Circle(Circle.ANOTHEROVAL));
   
        }

    public static void main(String[] args) {
        TestProgram sirkel = new TestProgram();
        sirkel.setSize(400, 300);
        sirkel.setLocationRelativeTo(null);
        sirkel.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        sirkel.setVisible(true);
    }
}

Upvotes: 1

Views: 156

Answers (2)

Paul Samsotha
Paul Samsotha

Reputation: 209112

Try adding them with a layout manager besides the default BorderLayout and see what happens

import java.awt.*;    

public TestProgram(){
    setLayout(new GridLayout(1, 2);
    add(new Circle(Circle.OVAL));
    add(new Circle(Circle.ANOTHEROVAL));
}

Another solution would just be to use the default BorderLayout of the JFrame. When you just .add(something), it will get added automatically to the BorderLayout.CENTER, unless you specify the position. A BorderLayout and only hold one component in each position. So when you try and add a second one, Only the second one will appear in the CENTER position.

If you did

public TestProgram(){
    setLayout(new GridLayout(1, 2);
    add(new Circle(Circle.OVAL), BorderLayout.CENTER);
    add(new Circle(Circle.ANOTHEROVAL), BorderLayout.SOUTH);
}

it would also work

Upvotes: 1

mattdee123
mattdee123

Reputation: 213

First off, by making each Circle a JPanel, you are going to have unexpected results because two JPanels cannot draw to the same place. Rather, they are placed my the LayoutManager. In this case, I would imagine that one of your panels is on top of the other, so you're only seeing one.

If you want the circles to be in the same "panel" (they can overlap) then you will need one JPanel which can draw multiple circles.

If you want them to be "side-by-side" in separate panels, I'd look at GridLayout

Upvotes: 1

Related Questions