JPanel няма да рисува правилно

Аз съм съвсем нов в Java и Swing и това също е първият ми пост, така че съжалявам, ако няма много смисъл.

Това, което се опитвам да направя, е, когато щракна върху JPanel, искам той да добави кръг, където щракна. В момента всичко, което изглежда се случва, е, че когато щракна, вътре в JPanel, към който искам да добавя, се появява малък сив квадрат, но изглежда не мога да намеря начин да го накарам да изчертае като кръг.

Имам клас, който разширява JPanel, наречен "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);
    }

}

Мога да предположа, че това е нещо общо с метода paintComponent, но навсякъде, където съм търсил, изглежда няма решение за мен.

Всяка помощ би била чудесна, благодаря!


person Stefoth    schedule 15.10.2012    source източник
comment
За по-добра помощ по-рано, публикувайте SSCCE.   -  person Andrew Thompson    schedule 16.10.2012


Отговори (2)


Контекстът Graphcis вече е преведен, за да отговаря на местоположението x/y, където компонентът трябва да се появи в своя родителски контейнер, това означава, че горният ляв ъгъл на контекста Graphics в рамките на метода paintComponent всъщност е 0x0.

Трябва да определите някакъв размер за топката, рисувате на 10x10, което предполага, че вашият компонент топка трябва да върне preferredSize от 10x10

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

Вие ще поемете отговорност за предоставянето на подходящи подробности за оформлението на топката, когато бъде добавена към родителския контейнер...

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);
}

Това, разбира се, предполага, че имате зададено оформление null за родителския контейнер

АКТУАЛИЗИРАНО

Нещо като...

Вижте изпълнение на място

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();
        }
    }
}
person MadProgrammer    schedule 15.10.2012
comment
Така че внедрих това и сега рисува обекта там, където щракна, но как да го накарам да рисува кръг вместо правоъгълника? Съжалявам, ако това е наистина основно, но наистина съм нов в това. - person Stefoth; 16.10.2012
comment
Опитайте да зададете Ball на прозрачен (setOpaque(false)) - person MadProgrammer; 16.10.2012

Вероятно имате основен JPanel, където щракнете.

Предпочитам да проектирам основния панел да обработва щракването на мишката и класът Ball да бъде прост Object, който дефинира drawBall(Graphics g, int x, int y) метод, който знае как да рисува Ball. Това ще бъде извикано от метода paintComponent() в главния панел. В главния панел управлявате щракването на мишката, създавате обект от тип Ball и извиквате repaint(). Вътре в paintComponent() викате ball.drawBall().

person Dan D.    schedule 15.10.2012