2017-01-12 46 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()方法會導致閃爍。但是當我們只畫兩個形狀時沒有閃爍。 –

相關問題