Java Swing单击创建椭圆形

时间:2018-09-16 15:27:04

标签: java swing mouselistener

我认为用java创建一个小程序很容易:

  • 我创建了一个jFrame =>(大小为500,500,可见)
  • 我将mouseListener添加到jFrame
  • 当我单击我要在此位置创建一个椭圆形

所以我做了什么:

  • 我创建了一个课堂圈子(JPanel)
  • 每次mouslistener注意到我单击jFrame时,都会向其添加一个新的圆圈。 (它获取x和y点作为参数)

然后发生了令人震惊的事情: 我点击进入我的jFrame ...什么都没发生。 我以为:好吧,让我们在创建新圈子后重新粉刷...但是什么也没发生! 仅当我单击windwos边框并重新拉伸它时,它才能“重新绘制”它。

同时,如果我单击某个位置,然后单击另一个位置,然后重新拉伸框架,则还真的很不好,也很难过,它只会绘制最后一个圆圈:(应该同时绘制两个圆圈!)

现在我将repaint()放在了数千个不同的地方,但是没有区别。我还尝试了setopaque等技术,只是因为我现在不知道该怎么办!

此处是mouseListener:,您可以忽略颜色

if (rhs[0] == '+')
    {
                rhs = rhs.Replace("+", "");
    }


//Some code here

现在是圆圈:

public class Aufgabe3 {
    public static Circ.CircleColor actualColor = CircleColor.ROT;

    // fromone color to another depend on the actual
    public static Circ.CircleColor getNextColor(Circ.CircleColor aktuell) {
        switch (aktuell) {
        case ROT:
            return Circ.CircleColor.GRÜN;
        case GRÜN:
            return Circ.CircleColor.GELB;
        case GELB:
            return Circ.CircleColor.ROT;
        default:
            return null;
        }

    }

    public static void main(String[] args) {

        JFrame jFrame = new JFrame();
        jFrame.setVisible(true);
        jFrame.setSize(500, 500);
        jFrame.setDefaultCloseOperation(jFrame.EXIT_ON_CLOSE);
        // jFrame.add()
        // farbenfolge rot,grün,gelb--
        jFrame.addMouseListener(new MouseListener() {

            @Override
            public void mouseReleased(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mousePressed(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mouseExited(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mouseEntered(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("clicked");
                int x = e.getX();
                int y = e.getY();
                System.out.println("coords:" + x + "|" + y);
                Circ circ = new Circ(x, y, actualColor);
                circ.repaint();
                jFrame.add(circ);
                jFrame.repaint();
                System.out.println(actualColor);
                // actualisation of the next color
                actualColor = getNextColor(actualColor);

            }
        });
    }

}

2 个答案:

答案 0 :(得分:1)

JFrame的默认布局为BorderLayout。 在不指定位置的情况下将组件添加到BorderLayout时,会将它们添加到BorderLayout.CENTER中,以替换先前设置的组件。 这意味着您始终只将一个Circle添加到您的JFrame中。

在任何情况下,您似乎都想在光标的位置绘制圆圈,这意味着您必须在Circle的不同位置添加JFrame组件这么容易。 取而代之的是,最好只在框架中添加一个组件并绘制该组件中的所有圆圈。

答案 1 :(得分:0)

如果您在mouseClicked事件中添加组件,则可能是因为要更改容器(JFrame)而应重新调用该组件。此外,JFrame非常特殊:它们具有内容窗格,您应该通过以下方式添加组件:

frame.getContentPane().add(...);

默认内容窗格使用BorderLayout

为每次点击添加一个组件可能会过大,除非您将其设置为null(例如,绝对布局),然后调用setBounds(x,y,50,50)进行布局,否则就会遇到布局问题每个圆圈。

但是,由于您覆盖了paintComponent,因此您可以直接绘制椭圆形而不必关心布局或组件。

添加一次Circle组件,并带有BorderLayout.CENTER约束。这样可以确保您的Circle将获得最大尺寸。

MouseListener应该在圆上,并且必须使其具有焦点(setFocus(true))。

每次在Circle上单击鼠标时,将鼠标位置注册在列表中(例如:List<Point>),然后调用重绘:

circle.points.add(new Point(e.getX(), e.getY()); // 
circle.repaint();

每次调用paintComponent(Graphics)时,请使用列表按其被调用的顺序绘制椭圆。

@Override
protected void paintComponent(Graphics g) {
    System.out.println("paint");
    Graphics2D g2d = (Graphics2D) g;
    super.paintComponent(g2d);
    g2d.setColor(decodeCircleColor(circleColor));
    // if you know lambda
    points.forEach(p -> g2d.fillOval(p.x, p.y, 50, 50)); 
    // or if you don't know lambda yet.
    // for (Point p : points) g2d.fillOval(p.x, p.y, 50, 50)); 
}

请注意,您可以使用Point或任何相关类(例如,可以使用存储Paint之类的具体对象,例如java.awt.Color来更改椭圆的颜色)。 / p>