簡體   English   中英

單擊鼠標后在JPanel上繪制圓圈

[英]Draw circle on JPanel after mouse click

我只想在鼠標單擊后繪制圓圈。 由於paintComponent方法調用了自身,因此首先繪制圓而無需單擊。

public class DrawPanel extends JPanel implements MouseListener {
private static final long serialVersionUID = 1L;
int x, y;

public DrawPanel() {
    setBackground(Color.WHITE);
    addMouseListener(this);
}

public void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    g2.setColor(Color.red);
    g2.fillOval(x, y, 20, 20);
}

@Override
public void mouseClicked(MouseEvent e) {
    x = e.getX();
    y = e.getY();
    repaint();
}

}

您的代碼存在一些問題:

  1. 您永遠不會調用super.paintComponent();
  2. 你只有一個xy
  3. 請注意,當您調整框架大小時,某些圓圈將消失,並且總體上以奇怪的方式表現。
  4. 我會將用戶單擊的所有Point都存儲在ArrayList ,然后在paintComponent方法內遍歷該列表。 這樣,您可以調用super.paintComponent(); 沒有圓圈消失。

更改后的工作代碼:

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class DrawPanel extends JPanel {
    private static final long serialVersionUID = 1L;
    private ArrayList<Point> points;

    public DrawPanel() {
        points = new ArrayList<Point>();
        setBackground(Color.WHITE);
        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                points.add(new Point(e.getX(), e.getY()));
                repaint();
            }
        });
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.red);
        for (Point point : points) {
            g2.fillOval(point.x, point.y, 20, 20);
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new DrawPanel());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setSize(400, 400);
                frame.setVisible(true);
            }
        });
    }

}

您應該具有一些初始狀態,因此您知道在設置時不會繪制。

這可以通過一個簡單的布爾變量來完成,您可以在用戶按下屏幕時將其設置為true。

public class DrawPanel extends JPanel implements MouseListener {
private static final long serialVersionUID = 1L;
int x, y;
boolean mustDraw = false;

public DrawPanel() {
    setBackground(Color.WHITE);
    addMouseListener(this);
}

public void paintComponent(Graphics g) {
    if(!mustDraw) return;
    Graphics2D g2 = (Graphics2D) g;
    g2.setColor(Color.red);
    g2.fillOval(x, y, 20, 20);
}

@Override
public void mouseClicked(MouseEvent e) {
    x = e.getX();
    y = e.getY();
    mustDraw = true;
    repaint();
}

}

您應該將圈子放入自己的班級中。 該類將保存有關其位置,半徑和顏色的信息。 您可以提取形狀,並在面板上繪制一系列形狀。 這將使以后易於實現三角形,正方形,六邊形等變得容易。

以后可以向形狀對象添加更多方法和屬性,而只需更改其對IRIR OWN paintComponent(g)方法的內部實現。 這使得DrawPanel取決於每個Shape如何進行自己的繪圖。

應用截圖


App.java

import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class App {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame f = new JFrame("Circle Click Application");
                DrawPanel p = new DrawPanel(10f);

                p.setPreferredSize(new Dimension(300, 200));;

                f.setContentPane(p);
                f.pack();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setLocationRelativeTo(null);
                f.setVisible(true);
            }
        });
    }
}

DrawPanel.java

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;

public class DrawPanel extends JPanel implements MouseListener {
    private static final long serialVersionUID = -6817035652787391530L;

    private List<Shape> shapes;
    protected float radius;

    private float sat = 0.7f;
    private float bri = 0.8f;

    public DrawPanel(float radius) {
        this.shapes = new ArrayList<Shape>();
        this.radius = radius;

        setBackground(Color.WHITE);
        addMouseListener(this);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        for (Shape shape : shapes) {
            shape.paintComponent(g);
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        shapes.add(new Circle(e.getX(), e.getY(), radius, ColorUtils.randHue(sat, bri)));

        repaint();
    }

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

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

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

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

Shape.java

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;

public interface Shape {
    Point getOrigin();
    void setOrigin(Point origin);

    Color getColor();
    void setColor(Color color);

    void paintComponent(Graphics g);
}

Circle.java

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;

public class Circle implements Shape {
    private Point origin;
    private float radius;
    private Color color;

    public Circle() {
        this(0, 0, 0.5f, Color.BLACK);
    }

    public Circle(int x, int y, float radius, Color color) {
        this(new Point(x, y), radius, color);
    }

    public Circle(Point origin, float radius, Color color) {
        this.origin = origin;
        this.radius = radius;
        this.color = color;
    }

    @Override
    public Point getOrigin() {
        return origin;
    }

    @Override
    public void setOrigin(Point origin) {
        this.origin = origin;
    }

    public float getRadius() {
        return radius;
    }

    public void setRadius(float radius) {
        this.radius = radius;
    }

    @Override
    public Color getColor() {
        return color;
    }

    @Override
    public void setColor(Color color) {
        this.color = color;
    }

    @Override
    public void paintComponent(Graphics g) {
        int diameter = (int) (this.radius * 2);
        int x = (int) (origin.x - this.radius);
        int y = (int) (origin.y - this.radius);

        g.setColor(this.color);
        g.fillOval(x, y, diameter, diameter);
    }
}

ColorUtils.java

import java.awt.Color;
import java.util.Random;

public class ColorUtils {
    private static final Random RAND;

    static {
        RAND = new Random(System.currentTimeMillis());
    }

    public static Color randHue(float saturation, float brightness) {
        return Color.getHSBColor(RAND.nextFloat(), saturation, brightness);
    }
}

延期

您只需實現Shape接口就可以輕松添加一個類,例如Triangle

DrawPanel#mouseClicked

@Override
public void mouseClicked(MouseEvent e) {
    long time = System.currentTimeMillis();
    boolean isEven = time % 2 == 0;

    if (isEven) {
        shapes.add(new Circle(e.getX(), e.getY(), radius, ColorUtils.randHue(sat, bri)));
    } else {
        shapes.add(new Triangle(e.getX(), e.getY(), radius * 2, ColorUtils.randHue(sat, bri)));
    }

    repaint();
}

Triangle.java

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.geom.Point2D;

public class Triangle implements Shape {
    private Point origin;
    private float side;
    private Color color;

    private Polygon poly;

    public Triangle(int x, int y, float side, Color color) {
        this(new Point(x, y), side, color);
    }

    public Triangle(Point origin, float side, Color color) {
        this.origin = origin;
        this.side = side;
        this.color = color;

        recalculate();
    }

    protected void recalculate() {
        this.poly = createPolygon((float) origin.getX(), (float) origin.getY(), side, false);
    }

    protected Polygon createPolygon(float x, float y, float side, boolean invert) {
        float xOff = side / 2f;
        float yOff = (float) (xOff * Math.sqrt(3));

        float r1 = 1f / 3f;
        float r2 = 2f / 3f;

        if (invert) {
            yOff *= -1;
        }

        return createPolygon(new Point2D.Float[] {
            new Point2D.Float(x,        y - (yOff * r2)), // Top
            new Point2D.Float(x - xOff, y + (yOff * r1)), // Left
            new Point2D.Float(x + xOff, y + (yOff * r1))  // Right
        });
    }

    protected Polygon createPolygon(Point2D.Float[] points) {
        int nPoints = points.length + 1;
        int xCoords[] = new int[nPoints];
        int yCoords[] = new int[nPoints];

        for (int i = 0; i < nPoints; i++) {
            xCoords[i] = (int) points[i % points.length].x;
            yCoords[i] = (int) points[i % points.length].y;
        }

        return new Polygon(xCoords, yCoords, nPoints);
    }

    @Override
    public Point getOrigin() {
        return origin;
    }

    @Override
    public void setOrigin(Point origin) {
        this.origin = origin;

        recalculate();
    }

    public float getSide() {
        return side;
    }

    public void setSide(float side) {
        this.side = side;

        recalculate();
    }

    @Override
    public Color getColor() {
        return color;
    }

    @Override
    public void setColor(Color color) {
        this.color = color;
    }

    @Override
    public void paintComponent(Graphics g) {
        g.setColor(this.color);
        g.fillPolygon(poly);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM