每次执行侦听器时,如何更改面板的图形?

时间:2018-09-02 17:35:33

标签: java swing graphics listener panel

我正在尝试更改按下鼠标后的点的颜色。因此,理想情况下,您将在程序运行时连续绘制随机着色的点。似乎无法解决这个问题,因为如果我尝试在侦听器中引用图形“页面”,则无法识别它。如果我将随机颜色线放入图形构造函数中,则程序将以一种随机颜色运行,并且对于每个点都不会更改。

import java.util.ArrayList;
import java.util.Random;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;

public class DotsPanel extends JPanel {
    private final int SIZE = 6; // radius of each dot
    Random rand = new Random();
    private ArrayList<Point> pointList;
    Color randomColor = new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));

    public DotsPanel() {
        pointList = new ArrayList<Point>();

        addMouseListener(new DotsListener());
        addMouseMotionListener(new DotsListener());

        setBackground(Color.black);
        setPreferredSize(new Dimension(300, 200));
    }

    public void paintComponent(Graphics page) {
        super.paintComponent(page);
        for (Point spot : pointList) {
            page.setColor(randomColor);
            page.fillOval(spot.x - SIZE, spot.y - SIZE, SIZE * 2, SIZE * 2);
        }
        page.drawString("Count: " + pointList.size(), 5, 15);
    }

    private class DotsListener implements MouseListener, MouseMotionListener {
        public void mousePressed(MouseEvent event) {
            pointList.add(event.getPoint());
            repaint();
        }

        public void mouseDragged(MouseEvent event) {
            pointList.add(event.getPoint());
            repaint();
        }

        public void mouseClicked(MouseEvent event) {
        }

        public void mouseReleased(MouseEvent event) {
        }

        public void mouseEntered(MouseEvent event) {
        }

        public void mouseExited(MouseEvent event) {
        }

        public void mouseMoved(MouseEvent e) {
        }
    }
}

1 个答案:

答案 0 :(得分:1)

首先,您需要将点与颜色相关联,这可以通过以下两种方式之一进行:

  1. 通过在BufferedImage上绘制点,然后在组件的绘制方法(JPanel的paintComponent)中绘制该图像,或者
  2. 通过用某种方式直接将颜色与点(例如与Map或将两者结合在一起的自定义对象)相关联,在paintComponent方法中绘制所有点及其关联的颜色。

在您的听众中,创建圆点及其颜色,然后使用所需的任何一种技术将它们关联起来。

例如,使用一个HashMap<Shape, Color>来关联一个Shape(这里是一个保存圆形的Ellipse2D)和一个名为shapeColorMap的Color

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.*;

@SuppressWarnings("serial")
public class RandomDot extends JPanel {
    // size of JPanel
    private static final int PREF_W = 800;
    private static final int PREF_H = 650;
    // width of dot
    public static final int DOT_WIDTH = 40;
    private Map<Shape, Color> shapeColorMap = new HashMap<>();

    public RandomDot() {
        setPreferredSize(new Dimension(PREF_W, PREF_H));
        addMouseListener(new MyMouse());
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        // smooth out jaggies in graphics
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // iterate through the Map getting color and circle
        for (Entry<Shape, Color> entry : shapeColorMap.entrySet()) {
            Color color = entry.getValue();
            Shape shape = entry.getKey();
            g2.setColor(color);
            g2.fill(shape);
        }
    }

    private class MyMouse extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) {
            // get a random color using HSB
            float multiplier = 0.3f;
            float hue = (float)Math.random();
            float saturation = (float) (multiplier * Math.random() + (1 - multiplier));
            float brightness = (float) (multiplier * Math.random() + (1 - multiplier));
            Color color = Color.getHSBColor(hue, saturation, brightness);

            // create a circle at mouse click
            double x = e.getX() - DOT_WIDTH / 2;
            double y = e.getY() - DOT_WIDTH / 2;
            double w = DOT_WIDTH;
            Ellipse2D circle = new Ellipse2D.Double(x, y, w, w);

            // put both into the map
            shapeColorMap.put(circle, color);

            // repaint
            repaint();
        }
    }

    private static void createAndShowGui() {
        RandomDot mainPanel = new RandomDot();

        JFrame frame = new JFrame("RandomDot");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}