繁体   English   中英

Java Swing单击创建椭圆形

[英]Java Swing create Oval by Click

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

  • 我创建一个jFrame =>(大小为500,500,它是可见的)
  • 我向jFrame添加mouseListener
  • 当我单击时,我想在此位置创建一个椭圆形

所以我做了什么:

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

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

同时还使我感到非常难过和难过的是,如果我单击某个位置,然后单击另一个位置,然后重新拉伸框架,则它只会绘制最后一个圆圈:(它应该同时绘制两个!)

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

这里是mouseListener:您可以忽略颜色

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

            }
        });
    }

}

现在是圆:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JComponent;
import javax.swing.JPanel;

public class Circ extends JComponent {
    static public enum CircleColor {
        ROT, GRÜN, GELB
    };

    private int x;
    private int y;
    private CircleColor circleColor;

    public Circ() {
        super();

    }

    public Circ(int x, int y, CircleColor circColor) {
        super();
        this.x = x;
        this.y = y;
        this.circleColor = circColor;
        System.out.println("new circle created");
        setSize(new Dimension(50, 50));
        setVisible(true);
        setOpaque(true);
    }

    public Color decodeCircleColor(CircleColor farbe) {
        switch (farbe) {
        case GRÜN:
            return Color.GREEN;
        case GELB:
            return Color.yellow;
        case ROT:
            return Color.red;
        default:
            return null;
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        System.out.println("paint");
        Graphics2D g2d = (Graphics2D) g;
        super.paintComponent(g2d);
        g2d.setColor(decodeCircleColor(circleColor));
        // g2d.drawOval(x, y, 50, 50);
        g2d.fillOval(x, y, 50, 50);
    }
}

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

无论如何,您似乎都试图在光标的位置绘制圆,这意味着您必须将Circle组件添加到JFrame的不同位置,这并不容易。 取而代之的是,最好只在框架中添加一个组件并绘制该组件中的所有圆。

如果将组件添加到mouseClicked事件中,则可能会重新验证应该调用的内容,因为更改了容器( JFrame )。 而且,JFrame非常特殊:它们具有内容窗格 ,您应该通过以下方式添加组件:

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

默认的内容窗格使用BorderLayout

每次单击添加一个组件可能会过大,除非将其设置为null (例如,绝对布局)并为每个圆调用setBounds(x,y,50,50),否则布局会有问题。

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

使用BorderLayout.CENTER约束添加一次Circle组件。 这将确保您的Circle能够获得最大尺寸。

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

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

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来更改椭圆的颜色)。

暂无
暂无

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

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