Java Drawing Multiple Squares in Same JFrame

前端 未结 1 919
甜味超标
甜味超标 2021-01-28 16:48

I am trying to make an animation with multiple thread. I want to paint n squares where this n comes from commend-line argument. Every square has their x-y coor

1条回答
  •  無奈伤痛
    2021-01-28 17:34

    So, starting with...

    public class DrawSquare extends JPanel {
        public Square square;
        public DrawSquare() {
            square = new Square();
        }
    
        @Override
        public void paintComponents(Graphics g) {
            // TODO Auto-generated method stub
            super.paintComponents(g);
    
        }
    
        @Override
        public void paint(Graphics g) {
            // TODO Auto-generated method stub
            super.paint(g);
    
            g.setColor(square.getC());
            g.fillRect(square.getX(), square.getY(), square.getR(), square.getR());
        }
    }
    

    As general recommendation, it's preferred to put custom painting in the paintComponent method (note, there's no s at the end)

    When paint is called, the Graphics context has already been translated to the component coordinate position. This means that 0x0 is the top/left corner of the component, this also means that...

    g.fillRect(square.getX(), square.getY(), square.getR(), square.getR());
    

    is painting the rect at x + x x y + y, which will, at the very least, paint the rect in the wrong position, at worst paint it beyond the visible scope of the component.

    You're also not providing any sizing hints for the component, so it's default size will be 0x0, which prevent it from been painted.

    Since I am using multi thread I assume I have to control each squares.

    Well, since I can't really see what's driving the animation, I imagine that when you say "multi thread" you're suggesting that each square has it's own `Thread. In this case, that's a bad idea. Let's put aside the thread synchronisation issues for a moment, more threads doesn't equate to more work you can do, at some point, it will begin to degrade the system performance.

    In most cases, a single, well managed thread, is all you really need. You also have to understand that Swing is NOT thread safe. This means that you shouldn't update the UI (or states that the UI relies on) from outside the context of the Event Dispatching Thread.

    So, why you're thread can update the position of the rects, you need to take care to ensure that they are not been painted why they are been update. Once you've updated the state, you then need to trigger a paint pass (which is trivial in of itself)

    So I have to store each square object in the ArrayList.

    Yep, good start

    However, I am having trouble with painting those squares. I can paint one square but when I try to paint multiple squares, it does not show.

    Okay, so instead of using multiple components, use one. Run through your ArrayList within the paintComponent method of this component and paint all the rects to it. This provides a much simpler way to manage things like bounds detection, as you have only one container to worry about.

    I'd highly recommend you have a look at:

    • Java Bouncing Ball which demonstrates many of the concepts discussed here
    • Concurrency in Swing
    • How to use Swing Timers
    • Performing Custom Painting
    • Painting in AWT and Swing

    0 讨论(0)
提交回复
热议问题