【问题标题】:Use keyListener to update paint().使用 keyListener 更新paint()。
【发布时间】:2017-05-03 23:43:42
【问题描述】:

我试图让向上箭头键在我按下它时重新绘制屏幕部分,但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();
}

【问题讨论】:

    标签: java paint keylistener


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的快速回复!我实际上是在尝试更新弧的颜色而不是位置。我应该澄清一下。你有什么建议吗?
    • @ShawnSharp:是的,同样的想法。问题是当您想使用变量时,您正在使用文字对所有内容进行硬编码。创建一个 Color 字段 arcColor,并在您的键侦听器中更改其状态,然后调用 repaint。
    • 感谢您的指导!
    猜你喜欢
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-08
    • 2020-12-08
    • 2014-03-16
    相关资源
    最近更新 更多