簡體   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