java - Keylistener 可以工作,但没有执行预期的操作。为什么?

标签 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 监听器可以工作,但它没有执行我打算执行的任务。

控制台输出

I am inside paint Going to move up

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

moving out Going to move down

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

moving out

输出:

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)

最佳答案

首先,您不应该添加 KeyListener从里面paint方法,因为它每次都会额外注册一个 paint被调用。

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

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

所以在下面的代码中:

  • addKeyListener已移至 paint 之外。
  • 关键听众 来电 move索引为Shape移动。
  • move方法 现在只注册Shape根据收到的索引突出显示,并调用 repaint
  • Graphics2D object 设置为局部变量 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");

    }
}

关于java - Keylistener 可以工作,但没有执行预期的操作。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41608971/

相关文章:

java - 设置csipsimple项目

Java,我的图像不会更新/移动

java - 使用 Apache Tomcat 在 Eclipse 中运行 RESTful Web 服务

java - 真的是多态吗?

java - 最好将jar添加到新模块或Android Studio项目的l​​ibs文件夹中

c# - 截图工具滞后荧光笔

java - Paint 方法被多次调用...如何限制?

delphi - 怎么可能清除以前画的东西?

java - 我试图让球逐渐移动

java - 为该组件构造函数之外的某个 swing 组件添加 KeyListener 对象时,KeyAdapter 不起作用