使用 keyListener 更新 paint()。

Use keyListener to update paint().

我试图让向上箭头键在按下时重新绘制屏幕部分,但 paint() 不能包含 keyPressed(),而且 keyPressed 无法访问 g2。你有什么建议吗?

public void paint(Graphics g) 
{
    Graphics2D g2 = (Graphics2D) g;
    g2.setPaint(Color.RED.darker().darker());
    g2.fill(new Arc2D.Double(200, 100, 350, 350, 45, 90, Arc2D.PIE));
}


@Override
public void keyPressed(KeyEvent e) 
{
    int keyCode = e.getKeyCode();
    if (keyCode == KeyEvent.VK_UP) {
    System.out.println("Pressed Up Key");
    g2.setPaint(Color.RED);
    g2.fill(new Arc2D.Double(200, 100, 350, 350, 45, 90, Arc2D.PIE));
    repaint();
}

Swing 绘画不是这样完成的。与其尝试在键侦听器(或键绑定)中直接操作 Graphics 对象,不如通过按键更改对象的字段并调用重绘。

private Arc2D myArc = null;

public void paint(Graphics g)  {
    Graphics2D g2 = (Graphics2D) g;

    if (myArc != null) {
        g2.setPaint(Color.RED.darker().darker());
        // g2.fill(new Arc2D.Double(200, 100, 350, 350, 45, 90, Arc2D.PIE));
        g2.fill(myArc);
    }
}


@Override
public void keyPressed(KeyEvent e) {
    int keyCode = e.getKeyCode();
    if (keyCode == KeyEvent.VK_UP) {
    System.out.println("Pressed Up Key");
    // g2.setPaint(Color.RED);
    // g2.fill(new Arc2D.Double(200, 100, 350, 350, 45, 90, Arc2D.PIE));

    // here change or create new Arc2D object and assign to myArc
    // perhaps changing the Y location of the arc
    myArc = // .... critical code here

    // then repaint
    repaint();
}

请注意,如果这是一个 Swing GUI,您几乎总是最好使用 Key Bindings 而不是 KeyListener。其一,您可以轻松地抓住焦点。

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.geom.Arc2D;

import javax.swing.*;

@SuppressWarnings("serial")
public class ColorArc extends JPanel {
    private static final int PREF_W = 600;
    private static final int PREF_H = 450;
    private int arcX = 150;
    private int arcY = 150;
    private float hue = 0.5f;
    private float saturation = 0.5f;
    private float brightness = 0.5f;
    private Color arcColor = Color.getHSBColor(hue, saturation, brightness);
    private Arc2D myArc = new Arc2D.Double(arcX, arcY, 300, 300, 45, 90, Arc2D.PIE);

    public ColorArc() {
        addKeyListener(new MyKey());
        setFocusable(true);
        requestFocusInWindow();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (myArc != null) {
            Graphics2D g2 = (Graphics2D) g;            
            // use rendering hints to help draw a smooth graphic
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setPaint(arcColor);
            g2.fill(myArc);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H); // set GUI's preferred size
    }

    private class MyKey extends KeyAdapter {

        @Override
        public void keyPressed(KeyEvent e) {
            int keyCode = e.getKeyCode();
            if (keyCode == KeyEvent.VK_UP) {
                hue += 0.01f;
                hue %= 1.0f;
            } else if (keyCode == KeyEvent.VK_LEFT) {
                saturation += 0.01f;
                saturation %= 1.0f;
            } else if (keyCode == KeyEvent.VK_RIGHT) {
                brightness += 0.01f;
                brightness %= 1.0f;
            } else {
                return;
            }
            arcColor = Color.getHSBColor(hue, saturation, brightness);
            repaint();
        }
    }

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

        JFrame frame = new JFrame("Color Arc");
        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());
    }
}