【问题标题】:Keylistener works but is not executing the intended operation. Why?Keylistener 工作但没有执行预期的操作。为什么?
【发布时间】:2017-05-27 07:29:20
【问题描述】:

这是 MainApplication,它创建一个 Frame 并保存实现 Graphics 的类。

MainApplication.java

import java.awt.*;  

public class MainApplication 
{  
    public MainApplication()  
    {
        Frame frame= new Frame("Test App");
        frame.add(new KeyTest());
        frame.setBackground(Color.RED);
        frame.setLayout(null);  
        frame.setSize(700,750);  
        frame.setVisible(true); 
    } 
    public static void main(String args[])  
    {  

        new MainApplication();

    }
}  

该类创建所有图形形状并实现 KeyListener。

KeyTest.java

import java.awt.BasicStroke;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.RoundRectangle2D;

public class KeyTest extends Canvas {


    /**
     * 
     */
    private static final long serialVersionUID = 3L;
    Graphics2D graphics2D;
    Color color = Color.BLACK;
    private static float borderThickness = 5;
    Shape firstShape = new RoundRectangle2D.Double(20,40,300,50,10,10);
    Shape secondShape = new RoundRectangle2D.Double(20,150,300,50,10,10);
    public KeyTest()
    {
        setBackground(Color.RED);
        setSize(700,750);               
    }
    public void paint(Graphics graphics)  
    {  

        graphics2D = (Graphics2D)graphics; //TypeCasting to 2D
        System.out.println("I am inside paint");

        //      Smoothening the corners
        graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        //      Apple border color
        Stroke oldStroke = graphics2D.getStroke();
        graphics2D.setStroke(new BasicStroke(borderThickness));
        graphics2D.setColor(Color.WHITE);

        //      Drawing a RoundedRectangle for Apple    
        graphics2D.draw(firstShape);
        graphics2D.setStroke(oldStroke);

        //      Setting the Background Color
        graphics2D.setColor(Color.BLACK); 
        graphics2D.fill(firstShape);


        //      Setting the font inside the shape
        Font firstFont = new Font("Serif", Font.BOLD,35);
        graphics2D.setFont(firstFont);
        graphics2D.setColor(Color.WHITE);
        graphics2D.drawString("Apple",30,80);


        //      Pineapple border color 
        graphics2D.setStroke(new BasicStroke(borderThickness));
        graphics2D.setColor(Color.WHITE);

        //      Drawing a RoundedRectangle for Pineapple    
        graphics2D.draw(secondShape);
        graphics2D.setStroke(oldStroke);

        //      Setting the Background Color
        graphics2D.setColor(Color.BLACK); 
        graphics2D.fill(secondShape);

        //      Setting the font inside the shape
        Font secondFont = new Font("Serif", Font.BOLD,35);
        graphics2D.setFont(secondFont);
        graphics2D.setColor(Color.WHITE);
        graphics2D.drawString("Pineapple",30,190);

        addKeyListener(new KeyListener(){

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

            }

            @Override
            public void keyPressed(KeyEvent e) {
                int keyCode = e.getKeyCode();

                System.out.println(keyCode);
                System.out.println(KeyEvent.VK_UP);
                if(keyCode==KeyEvent.VK_UP){
                    System.out.println("Going to move up");
                    move(firstShape);

                }
                if(keyCode==KeyEvent.VK_DOWN){
                    System.out.println("Going to move down");
                    move(secondShape);

                }
            }

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

            }});
    }
    public void move(Shape s){

        System.out.println("Check:"+s.getBounds2D());
        graphics2D.setColor(Color.GREEN);
        graphics2D.fill(s);
        System.out.println("moving out");
    }
}

我的控制台输出清楚地显示我的 Key Listener 工作,但它没有执行我打算执行的任务。

控制台输出

我在油漆里面要向上移动

检查:java.awt.geom.Rectangle2D$Double[x=20.0,y=40.0,w=300.0,h=50.0]

搬出去要搬下来

检查:java.awt.geom.Rectangle2D$Double[x=20.0,y=150.0,w=300.0,h=50.0]

搬出去

输出:

现在得到的输出..(图 1)

当我按下向下箭头按钮时我期望的输出(图 2)

当我按下向上箭头按钮时我期望的输出(图 3)

【问题讨论】:

  • 可能你必须在你的框架上触发某种重绘/刷新。并提示:在您的问题中包含 all 它们的图像绝对没有意义。
  • paint 方法中添加KeyListener 看起来一点也不好看。
  • 在外部添加它并没有达到目的,这就是为什么我将它添加到 paint 方法中

标签: java paint keylistener graphics2d shapes


【解决方案1】:

首先,您不应该在paint 方法中添加KeyListener,因为它会在每次调用paint 时额外注册一个。

然后,不要依赖存储 ComponentGraphics 对象并在其上绘制东西,因为它可能会发生许多超出您控制范围的事情(例如,它可能会被其他发生的事情清除) AWT UI 操作)。

唯一相关的Graphics 对象是您在paint 中收到的实例,并且仅在paint 方法的范围内。

所以在下面的代码中:

  • addKeyListener 已移出 paint
  • 关键监听器 使用Shape 的索引调用move 来移动。
  • move 方法 现在只根据收到的索引注册Shape 以突出显示,并调用repaint
  • Graphics2D 对象被设置为paint 的局部变量,因为它 与外部无关。
  • paintHighlightedShape 负责在作为参数接收的Graphics2D 对象上绘制突出显示的Shape
  • paint 方法现在调用 paintHighlightedShape 并将其 Graphics2D 对象作为参数传递。

请注意,main 方法已添加到 KeyTest 用于测试目的,其内容应放在您的主类中。

此外,如果您计划要突出显示更多形状,则可以使用Shape 的数组,传递给move 的索引可以是要突出显示的Shape 的数组索引。

最后,为了优化,我们不应该绘制高亮的常规形状,因为无论如何它都会被绿色形状隐藏。 考虑创建一个drawShape(Graphics2D, Shape) 方法,该方法将绘制常规形状或绿色形状,具体取决于突出显示的形状。 您可以从 paint 方法调用此方法,循环所有形状。

import java.awt.BasicStroke;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.RoundRectangle2D;

public class KeyTest extends Canvas {

    /**
     *
     */
    private static final long serialVersionUID = 3L;
    Color color = Color.BLACK;
    private static float borderThickness = 5;
    Shape firstShape = new RoundRectangle2D.Double(20, 40, 300, 50, 10, 10);
    Shape secondShape = new RoundRectangle2D.Double(20, 150, 300, 50, 10, 10);

    Shape highlightedShape;

    public KeyTest() {
        setBackground(Color.RED);
        setSize(700, 750);
    }

    public static void main(final String[] args) {
        Frame frame = new Frame("Test App");
        final KeyTest keyTest = new KeyTest();
        keyTest.addKeyListener(new KeyListener() {

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

            }

            @Override
            public void keyPressed(final KeyEvent e) {
                int keyCode = e.getKeyCode();

                System.out.println(keyCode);
                System.out.println(KeyEvent.VK_UP);
                if (keyCode == KeyEvent.VK_UP) {
                    System.out.println("Going to move up");
                    keyTest.move(1);

                }
                if (keyCode == KeyEvent.VK_DOWN) {
                    System.out.println("Going to move down");
                    keyTest.move(2);

                }
            }

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

            }
        });
        frame.add(keyTest);
        frame.setBackground(Color.RED);
        frame.setLayout(null);
        frame.setSize(700, 750);
        frame.setVisible(true);
    }

    public void paint(final Graphics graphics) {

        Graphics2D graphics2D = (Graphics2D) graphics; //TypeCasting to 2D
        System.out.println("I am inside paint");

        //      Smoothening the corners
        graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        //      Apple border color
        Stroke oldStroke = graphics2D.getStroke();
        graphics2D.setStroke(new BasicStroke(borderThickness));
        graphics2D.setColor(Color.WHITE);

        //      Drawing a RoundedRectangle for Apple
        graphics2D.draw(firstShape);
        graphics2D.setStroke(oldStroke);

        //      Setting the Background Color
        graphics2D.setColor(Color.BLACK);
        graphics2D.fill(firstShape);

        //      Setting the font inside the shape
        Font firstFont = new Font("Serif", Font.BOLD, 35);
        graphics2D.setFont(firstFont);
        graphics2D.setColor(Color.WHITE);
        graphics2D.drawString("Apple", 30, 80);

        //      Pineapple border color
        graphics2D.setStroke(new BasicStroke(borderThickness));
        graphics2D.setColor(Color.WHITE);

        //      Drawing a RoundedRectangle for Pineapple
        graphics2D.draw(secondShape);
        graphics2D.setStroke(oldStroke);

        //      Setting the Background Color
        graphics2D.setColor(Color.BLACK);
        graphics2D.fill(secondShape);

        //      Setting the font inside the shape
        Font secondFont = new Font("Serif", Font.BOLD, 35);
        graphics2D.setFont(secondFont);
        graphics2D.setColor(Color.WHITE);
        graphics2D.drawString("Pineapple", 30, 190);

        paintHighlightedShape(graphics2D);

    }

    private void paintHighlightedShape(final Graphics2D graphics2D) {

        if (highlightedShape != null) {

            graphics2D.setColor(Color.GREEN);
            graphics2D.fill(highlightedShape);

        }
    }

    public void move(final int shapeNumber) {

        switch (shapeNumber) {
        case 1:
            highlightedShape = firstShape;
            break;
        case 2:
            highlightedShape = secondShape;
            break;
        default:

        }

        System.out.println("Check:" + highlightedShape.getBounds2D());
        System.out.println("Moving shape : " + highlightedShape);
        repaint();

        System.out.println("moving out");

    }
}

【讨论】:

  • 这个答案将解决您在使用绘画方法和 Keylistener 时出现的任何问题。非常感谢。
  • 1.实际上,形状不一定要移动,我希望每次按箭头键时每个形状的背景颜色都从黑色变为绿色。换句话说,我希望通过按箭头键选择形状时以绿色突出显示。 2. repaint() 方法在我绘制许多形状时会导致闪烁。但是当我们只绘制 2 个形状时没有闪烁。
  • 确实我误用了“移动”这个词,我刚刚在上次编辑中纠正了这个问题。关于闪烁问题,请参阅stackoverflow.com/questions/4203685/…stackoverflow.com/questions/29424960/…
猜你喜欢
  • 2020-08-26
  • 1970-01-01
  • 2014-08-04
  • 2021-01-03
  • 2018-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多