Keylistener工作但未执行预期的操作。为什么?

时间:2017-01-12 09:06:16

标签: java paint keylistener graphics2d shapes

这是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中$双[X = 20.0,Y = 40.0,W = 300.0,H = 50.0]

         

搬出去往下移

         

检查:java.awt.geom.Rectangle2D中$双[X = 20.0,Y = 150.0,W = 300.0,H = 50.0]

         

搬出

  

输出:

The Output which am getting now

The output I expect when I press DOWN ARROW Button

The Output I expect when I press UP ARROW Button

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

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

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

1 个答案:

答案 0 :(得分:2)

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

然后,不要依赖于存储Component的{​​{1}}对象并在其上绘画,因为许多事情都可能发生在你无法控制的事情上(例如它可能会被其他发生的AWT UI操作清除)。

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

所以在下面的代码中:

  • addKeyListener已移至paint之外。
  • 关键听众 调用move并移动Shape的索引。
  • move方法 现在只根据收到的索引注册Shape以突出显示,并调用repaint
  • Graphics2D对象被设置为paint的局部变量,因为它 在外面并不相关。
  • paintHighlightedShape负责在作为参数收到的Shape对象上绘制突出显示的Graphics2D
  • 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");

    }
}