You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在KeyListener中设置g.setColor()以修改后续绘制的圆和线条颜色?

问题

我编写了一段Java Swing代码,可根据用户点击位置绘制圆并连接线条。默认颜色为黑色,希望用户通过输入r、b、g、l(对应红、蓝、绿、黑)设置后续绘制的圆和线条颜色。已在KeyTyped方法中为对应字符设置if/else语句,请问该方法内需要编写什么代码实现此功能?

原代码如下:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Circle extends JPanel implements MouseListener, KeyListener, MouseMotionListener {

    private List<Point> points;

    public static void main(String[] args) {

        EventQueue.invokeLater(() -> new Circle().buildAndDisplayGui());
    }

    public Circle() {
        points = new ArrayList<>();
        setPreferredSize(new Dimension(500, 500));
        setBackground(Color.white);
        addMouseListener(this);
    }

    private void buildAndDisplayGui() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(this);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
        frame.addKeyListener(this);
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.black);
        int count = points.size();
        for (int i = 0; i < count; i++) {
            Point pt0 = points.get(i);
            g.fillOval(pt0.x - 10, pt0.y - 11, 20, 20);
            if (i > 0) {
                Point pt1 = points.get(i - 1);
                g.drawLine(pt1.x, pt1.y, pt0.x, pt0.y);
            }
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        //Prints the coordinates of the clicks
        System.out.println("X: " + e.getX() + "  Y: " + e.getY());
        Point pt = new Point(e.getX(), e.getY());
        points.add(pt);
        repaint();
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // Do nothing.
    }

    @Override
    public void mouseExited(MouseEvent e) {
        // Do nothing.
    }

    @Override
    public void mousePressed(MouseEvent e) {
        // Do nothing.
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // Do nothing.
    }

    @Override
    public void mouseDragged(MouseEvent e) {

    }

    @Override
    public void mouseMoved(MouseEvent e) {

    }

    @Override
        public void keyTyped(KeyEvent e) {
    
     if (e.getKeyChar() == 'r') { 
         
        //Sets the color of the next circle and lines to red
    
        } else {
      
            if (e.getKeyChar() == 'b') { 
                
                //Sets the color of the next circle and lines to blue
      
                } else {
      
                    if (e.getKeyChar() == 'g') { 
                        
                        //Sets the color of the next circle and lines to green
      
                        } else {
      
                            if (e.getKeyChar() == 'l') { 
                                
                                //Sets the color of the next circle and lines to black
                            
                            } 
                        } 
                    } 
                } 
            }
     

    @Override
    public void keyPressed(KeyEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub

    }
}

当前输出效果:
当前输出

期望输出效果(用户点击两次后按“r”再点击两次):
期望输出

解决方案

要实现按按键切换后续绘制颜色的功能,需要补充以下核心逻辑并修改相关代码:

1. 添加颜色管理成员变量

需要新增两个变量:

  • currentColor:保存当前选中的绘制颜色,默认设为黑色
  • colorList:和点列表points一一对应,记录每个点的绘制颜色

2. 完善keyTyped方法

在每个字符判断分支中,直接给currentColor赋值对应颜色,同时简化嵌套的if结构:

@Override
public void keyTyped(KeyEvent e) {
    if (e.getKeyChar() == 'r') { 
        currentColor = Color.RED;
    } else if (e.getKeyChar() == 'b') { 
        currentColor = Color.BLUE;
    } else if (e.getKeyChar() == 'g') { 
        currentColor = Color.GREEN;
    } else if (e.getKeyChar() == 'l') { 
        currentColor = Color.BLACK;
    }
}

3. 修改鼠标点击逻辑

添加点的同时,把当前颜色同步加入colorList:

@Override
public void mouseClicked(MouseEvent e) {
    System.out.println("X: " + e.getX() + "  Y: " + e.getY());
    Point pt = new Point(e.getX(), e.getY());
    points.add(pt);
    colorList.add(currentColor);
    repaint();
}

4. 调整绘制逻辑

在paintComponent中,根据每个点对应的颜色绘制圆和连线:

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    int count = points.size();
    for (int i = 0; i < count; i++) {
        Color color = colorList.get(i);
        g.setColor(color);
        Point pt0 = points.get(i);
        g.fillOval(pt0.x - 10, pt0.y - 11, 20, 20);
        if (i > 0) {
            Point pt1 = points.get(i - 1);
            g.drawLine(pt1.x, pt1.y, pt0.x, pt0.y);
        }
    }
}

修改后的完整代码

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Circle extends JPanel implements MouseListener, KeyListener, MouseMotionListener {

    private List<Point> points;
    private List<Color> colorList;
    private Color currentColor;

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> new Circle().buildAndDisplayGui());
    }

    public Circle() {
        points = new ArrayList<>();
        colorList = new ArrayList<>();
        currentColor = Color.BLACK;
        setPreferredSize(new Dimension(500, 500));
        setBackground(Color.white);
        addMouseListener(this);
    }

    private void buildAndDisplayGui() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(this);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
        frame.addKeyListener(this);
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        int count = points.size();
        for (int i = 0; i < count; i++) {
            Color color = colorList.get(i);
            g.setColor(color);
            Point pt0 = points.get(i);
            g.fillOval(pt0.x - 10, pt0.y - 11, 20, 20);
            if (i > 0) {
                Point pt1 = points.get(i - 1);
                g.drawLine(pt1.x, pt1.y, pt0.x, pt0.y);
            }
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.println("X: " + e.getX() + "  Y: " + e.getY());
        Point pt = new Point(e.getX(), e.getY());
        points.add(pt);
        colorList.add(currentColor);
        repaint();
    }

    @Override
    public void mouseEntered(MouseEvent e) {}

    @Override
    public void mouseExited(MouseEvent e) {}

    @Override
    public void mousePressed(MouseEvent e) {}

    @Override
    public void mouseReleased(MouseEvent e) {}

    @Override
    public void mouseDragged(MouseEvent e) {}

    @Override
    public void mouseMoved(MouseEvent e) {}

    @Override
    public void keyTyped(KeyEvent e) {
        if (e.getKeyChar() == 'r') { 
            currentColor = Color.RED;
        } else if (e.getKeyChar() == 'b') { 
            currentColor = Color.BLUE;
        } else if (e.getKeyChar() == 'g') { 
            currentColor = Color.GREEN;
        } else if (e.getKeyChar() == 'l') { 
            currentColor = Color.BLACK;
        }
    }

    @Override
    public void keyPressed(KeyEvent e) {}

    @Override
    public void keyReleased(KeyEvent e) {}
}

效果说明

修改后,初始绘制为黑色;按r键后,后续点击的圆和连线变为红色;按b切换蓝色,g切换绿色,l切回黑色,完全符合期望的输出效果。

内容的提问来源于stack exchange,提问作者user20483070

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 08:56:04