2013-05-10 76 views
2

我有以下代碼。在這段代碼中,我有一個從左到右移動的圖像和一個有事件的按鈕。但我想把這兩個任務放在線程中。這樣它才能正常工作。這個代碼的問題在於,按鈕事件在它到達最右點時才起作用。如何在線程中放置兩個不同的任務

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

class MyImage extends JFrame implements ActionListener 
{ 
    static int xPixel = 20; 
    Image myImage, offScreenImage; 
    Graphics offScreenGraphics; 
    JPanel p = new JPanel(); 
    Button btn = new Button("bun"); 
    JFrame f = new JFrame(); 


    public MyImage() 
    { 
     myImage = Toolkit.getDefaultToolkit().getImage("mywineshoplogo.jpg"); 
     setExtendedState(JFrame.MAXIMIZED_BOTH); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setVisible(true); 
     add(p); 
     p.add(btn); 
     moveImage(); 
     btn.addActionListener(this); 
    } 

    public void update(Graphics g) 
    { 
     paint(g); 
    } 

    public void paint(Graphics g) 
    { 
     int width = getWidth(); 
     int height = getHeight(); 
     if (offScreenImage == null) 
     { 
     offScreenImage = createImage(width, height); 
     offScreenGraphics = offScreenImage.getGraphics(); 
     } 
// clear the off screen image 
     offScreenGraphics.clearRect(0, 0, width + 1, height + 1); 
// draw your image off screen 
     offScreenGraphics.drawImage(myImage, xPixel, 10, this); 
// draw your image off screen 
// show the off screen image 
     g.drawImage(offScreenImage, 0, 0, this); 
// show the off screen image 
    } 

    void moveImage() //left to right move 
    { 
    Thread hilo = new Thread() { 

    public void run() { 
try { 

     for (int i = 0; i < 530; i++) 
     { 

     xPixel += 1; 
     repaint(); 
     // then sleep for a bit for your animation 
     try 
     { 
      Thread.sleep(4); 
     } /* this will pause for 50 milliseconds */ 

     catch (InterruptedException e) 
     { 
      System.err.println("sleep exception"); 
     } 
     } 
    } //try 
    catch (Exception ex) { 
     // do something... 
    } 
    } 
    }; 
    hilo.start(); 
    } 

/* void moveimg() // right to left move 
    { 
     for (int i = 529; i > 0; i--) 
     { 
     if (i == 1) 
     { 
      moveImage(); 
     } 
     xPixel -= 1; 
     repaint(); 
// then sleep for a bit for your animation 
     try 
     { 
      Thread.sleep(40); 
     } // this will pause for 50 milliseconds 

     catch (InterruptedException e) 
     { 
      System.err.println("sleep exception"); 
      } 
     } 
    } */  

    public void actionPerformed(ActionEvent ae) 
    { 
     try 
     { 
     if (ae.getSource() == btn) 
     { 
      p.setBackground(Color.RED); 
     } 
     } 
     catch (Exception e) 
     { 
     System.out.println("error"); 
     } 
    } 

    public static void main(String args[]) 
    { 
     MyImage me = new MyImage(); 
    } 
} 
+0

你可以嘗試在'paint'方法中註釋'clearRect'嗎?當然,圖像會塗在屏幕上,但至少您可以驗證背景在最多4毫秒內不會變紅,然後將被塗料方法覆蓋... – 2013-05-10 11:22:13

+2

offScreenImage的用途是什麼?如果你的目標是雙緩衝,這是無用的,因爲Swing已經在你的內部爲你做了。順便說一句,你不應該擴展'JFrame',而是擴展'JPanel',覆蓋'paintCOmponent'而不是'paint',並將該面板設置爲JFrame的內容窗格。另外,總是調用所有'paintXXX'方法的超級方法,否則您將看到可視故障 – 2013-05-10 11:54:38

回答

2

每當你要寫Thread.sleep在你的GUI代碼,阻止自己,介紹定於Swing的Timer的任務。這正是您的代碼所需要的:將每個更新作爲Timer上的單獨計劃任務進行安排。 Timer非常簡單易用,請參閱this official Oracle tutorial

相關問題