简体   繁体   English

JPanel无法正确绘制

[英]JPanel won't paint correctly

I am quite new to Java and Swing, and this is also my first post so sorry if it doesn't make too much sense. 我是Java和Swing的新手,这也是我的第一篇文章,如果它没有多大意义,那就很抱歉。

What I am trying to do is when I click on a JPanel, I want it to add a circle where I click. 我想要做的是当我点击JPanel时,我希望它在我点击的位置添加一个圆圈。 At the moment, all that seems to happen is when I click, a small grey square appears inside the JPanel I want to add to, but I can't seem to find any way of making it draw as a circle. 目前,所有似乎都发生的事情就是当我点击时,我要添加的JPanel中会出现一个小的灰色方块,但我似乎找不到任何方法让它像圆圈一样绘制。

I have a class that extends JPanel called "Ball" which is what is being added when I click. 我有一个扩展JPanel的类叫做“Ball”,这是我点击时添加的内容。 At the moment, I am not too worried about it being in the correct location, just for it to draw the ball correctly. 目前,我并不担心它在正确的位置,只是为了正确地抽球。 Below is the code for my "Ball" class: 以下是我的“Ball”类的代码:

package paintsliders;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;

class Ball extends JPanel{

private int x,y,w,h;

//I will use this constructor to put the ball in the correct location later.
Ball(){
    /*this.w = 100;
    this.h = 100;
    this.x = 200;
    this.y = 200;*/
}

//draw the ball
    @Override
public void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawOval(200,200,10,10);
      g.setColor(Color.RED);
    }

}

I can kind of guess that it is something to do with the paintComponent method, but everywhere I have looked doesn't seem to have a solution for me. 我可以猜测它与paintComponent方法有关,但我看到的任何地方似乎都没有解决方案。

Any help would be great, thanks! 任何帮助都会很棒,谢谢!

The Graphcis context has already been translated to meet the x/y location that the component should appear within it's parent container, this means that the top, left corner of the Graphics context within the paintComponent method is actually 0x0. Graphcis上下文已经被转换为满足组件应该在其父容器中出现的x / y位置,这意味着paintComponent方法中Graphics上下文的左上角实际上是0x0。

You need to define some size for the ball, you're painting at 10x10, which would suggest that your ball component should return a preferredSize of 10x10 你需要为球定义一些大小,你在10x10上绘画,这表明你的球组件应该返回10x10的preferredSize

public Dimension getPreferredSize() {
    return new Dimension(10, 10);
}

You will become responsible for providing appropriate layout details to the ball when it's added to the parent container... 当球被添加到父容器时,您将负责为球提供适当的布局细节...

public void mouseClicked(MouseEvent evt) {
    Point p = evt.getPoint();
    Ball ball = new Ball();
    Dimension size = ball.getPreferredSize();
    ball.setBounds(new Rectangle(p, size));
    add(ball);
}

This, of course, assumes you have a null layout set for the parent container 当然,这假设您为父容器设置了null布局

UPDATED 更新

Something like... 就像是...

见现场运行

public class PaintBalls {

    public static void main(String[] args) {
        new PaintBalls();
    }

    public PaintBalls() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new Board());
                frame.setSize(200, 200);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class Board extends JPanel {

        public Board() {
            setLayout(null);
            setBackground(Color.WHITE);
            addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent e) {
                    Point p = e.getPoint();
                    Ball ball = new Ball();
                    Dimension size = ball.getPreferredSize();
                    p.x -= size.width / 2;
                    p.y -= size.height / 2;

                    ball.setBounds(new Rectangle(p, size));
                    add(ball);
                    repaint();
                }

            });
        }

    }

    public class Ball extends JPanel {

        public Ball() {
            setOpaque(false);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(10, 10);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(Color.RED);
            g2d.fillOval(0, 0, 10, 10);
            g2d.dispose();
        }
    }
}

You probably have a main JPanel where you click. 你可能有一个主要的JPanel ,你点击。

I would rather design the main panel to handle the mouse click and the Ball class to be a simple Object that defines a drawBall(Graphics g, int x, int y) method that knows how to paint a Ball . 我宁愿设计主面板来处理鼠标单击而Ball类是一个简单的Object ,它定义了一个知道如何绘制BalldrawBall(Graphics g, int x, int y)方法。 This would be called by the paintComponent() method in the main panel. 这将由主面板中的paintComponent()方法调用。 In the main panel, you handle the mouse click, create an object of type Ball and call repaint() . 在主面板中,您处理鼠标单击,创建Ball类型的对象并调用repaint() Inside the paintComponent() you call ball.drawBall() . paintComponent()你调用ball.drawBall()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM