2017-01-12 32 views
0

这是创建一个Frame并保存实现Graphics的类的MainApplication。Keylistener可以工作,但并未执行预期的操作。为什么?

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

我的控制台输出清楚地表明,我的主要作品监听器,但其不执行,我想让它做任务。

控制台输出

我里面的油漆要拉升

检查: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]

移出

OUTPUT:

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

现在正在逐渐输出..(IMAGE 1)

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

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

+0

可能你必须在你的框架上触发某种重绘/刷新。提示:在你的问题中包含所有**图像绝对没有意义。 – GhostCat

+0

在'paint'方法内部添加'KeyListener'根本看起来不太好。 – Berger

+0

将它添加到外面并没有达到目的,这就是为什么我将它添加到“paint”方法内的原因。 –

回答

2

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

然后,不依赖于存储在其上的Component和绘画的东西Graphics对象,因为很多东西可以是你无法控制的外部(例如它可以通过其他发生的历史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"); 

    } 
} 
+1

此答案将解决您在使用绘画方法和Keylistener时遇到的任何问题。非常感谢。 –

+1

不客气:) – Berger

+0

1.实际上,形状不一定必须移动,我希望每次按下箭头键时,每个形状的背景颜色从黑色变为绿色。换句话说,我希望当通过箭头键按下选择时,形状用绿色突出显示。 2.绘制多个形状时,repaint()方法会导致闪烁。但是当我们只画两个形状时没有闪烁。 –