【问题标题】:How do I change the graphics of a panel each time a listener executes?每次侦听器执行时如何更改面板的图形?
【发布时间】:2018-09-02 17:35:33
【问题描述】:

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

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) {
        }
    }
}

【问题讨论】:

    标签: java swing graphics listener panel


    【解决方案1】:

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

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

    在您的侦听器中,创建您的点及其颜色,并使用您想要的任何技术将它们关联起来。

    例如,使用HashMap&lt;Shape, Color&gt; 关联一个Shape(这里是一个Ellipse2D 包含圆)和一个名为shapeColorMap的颜色

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

    【讨论】:

    • 我不确定我是否理解。我无法从侦听器中引用 paintComponent 方法中的任何内容。如果我在侦听器中创建点,如何将它们与图形相关联?
    • @TurnerWheat:您将要绘制的对象放在某个集合中,例如 ArrayList 或此处的 HashMap,然后在 paintComponent 方法中,遍历该集合,绘制每个项目。见上面的例子
    猜你喜欢
    • 2016-12-27
    • 2020-08-13
    • 1970-01-01
    • 2016-11-15
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    相关资源
    最近更新 更多