2012-11-26 33 views
1

這是線程使數字顯示:號沒有出現在JFrame的

class CoOrdCounter extends Thread{ 
    public void run(){ 
     try{ 
      while(true){ 
        Thread.sleep(500); 
        printX = cow.x; 
        printY = cow.y; 
      } 
     }catch(Exception e){} 
    } 
} 
//Of course I also have CoOrdCounter co = new CoOrdCounter; co.start(); 

然後...
g.drawString("Co-ords: ("+printX+","+printY+")",50,100); 它始終顯示(0,0),可能是因爲int printX = 0, printY = 0;。所以這意味着變量根本不會被改變......爲什麼?我該如何做這項工作......?
[請]我知道我不應該用油漆(),但我初學者,中級所以...
[編輯]而現在,MadProgrammer提到它,我得到一個EventDispatchThread錯誤。
[編輯2]我明白通過您的代碼段使用Timer@MadProgrammer我怎麼cow.xcow.y
[編輯3]如果鍵入關鍵pKeyListener將啓動ThreadSliderthread的實例。
[更新CLASS 2(真品)

import javax.swing.*; 

import java.awt.*; 
import java.awt.event.*; 
import java.awt.geom.*; 
import java.util.*; 
import java.io.*; 
import java.net.*; 
@SuppressWarnings({"serial","rawtypes","unchecked"}) 
public class CowbenderI extends JFrame implements MouseListener, KeyListener{ 

CoOrdCounter co; 
Counter cnt; 
Icon icon = new ImageIcon("resources/img/cow.png"); 
int focusX = 0, focusY = 0, counter = 0; 
ArrayList lines = new ArrayList(); 
Point2D.Double start; 
final Color BROWN = new Color(156,93,82); 
Slider thread; 
Rectangle cow = null; 
boolean drawGuy = false, useFinal = false, checkedForWin = false, alive = true; 
int finalTime = 0; 
int printX = 0, printY = 0; 
public CowbenderI(){ 
    super("Cowbender I - \"Slope Run\""); 
    setSize(700,700); 
    setVisible(true); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    addMouseListener(this); 
    addKeyListener(this); 

    cnt = new Counter(); 
    cnt.go = false; 
    cnt.start(); 
    co = new CoOrdCounter(); 
    co.go = false; 
    co.start(); 
} 

public void paint(Graphics g){ 
    super.paint(g); 
    try{ 
     g.setColor(Color.WHITE); 
     g.fillRect(-2000, -2000, 5000, 5000); 
     URL url = this.getClass().getResource("resources/img/world/slope.png"); 
     Image bckgrnd = Toolkit.getDefaultToolkit().getImage(url); 
     g.drawImage(bckgrnd,0,0,this); 
    }catch(Exception e){} 
    g.setColor(BROWN); 
    for(int i = 0; i < lines.size(); i++){ 
     Line2D.Double temp = (Line2D.Double) lines.get(i); 
     int x1 = Integer.parseInt(""+Math.round(temp.getX1())); 
     int x2 = Integer.parseInt(""+Math.round(temp.getX2())); 
     int y1 = Integer.parseInt(""+Math.round(temp.getY1())); 
     int y2 = Integer.parseInt(""+Math.round(temp.getY2())); 

     g.drawLine(x1-focusX,y1-focusY,x2-focusX,y2-focusY); 
    } 

    if(drawGuy){ 
     try{ 
      g.setFont(new Font("Arial",Font.BOLD,16)); 
      if(useFinal == false) g.drawString("Current Time: "+counter,50,50); 
      else g.drawString("Current Time: "+finalTime,50,50); 
      g.drawString("Co-ords: ("+printX+","+printY+")",50,100); 
      if(alive == true){ 
       URL url = this.getClass().getResource("resources/img/world/char.png"); 
       Image image = Toolkit.getDefaultToolkit().getImage(url); 
       g.drawImage(image, cow.x-focusX, cow.y-focusY, this); 
      } 
      else{ 
       URL url = this.getClass().getResource("resources/img/world/deadchar.png"); 
       Image image = Toolkit.getDefaultToolkit().getImage(url); 
       g.drawImage(image, cow.x-focusX, cow.y-focusY, this); 
        if(checkedForWin == false){ 
         finalTime = counter; 
         useFinal = true; 
         checkWin(); 
        } 
       } 
     } catch(Exception exc){} 
     focusX = cow.x-100; 
     focusY = cow.y-100; 
    } 
} 

public void checkWin(){ 
    if(finalTime >= 45){ 
     JOptionPane.showMessageDialog(null,"You won!\nThe farmer got tired and ran back!","Cowbender I - The Slope",JOptionPane.INFORMATION_MESSAGE,icon); 
     System.exit(0); 
    } 
} 

public void mouseClicked(MouseEvent e){} 
public void mouseEntered(MouseEvent e){} 
public void mouseExited(MouseEvent e){} 
public void mousePressed(MouseEvent e){ 
    start = new Point2D.Double(e.getX()+focusX,e.getY()+focusY); 
} 
public void mouseReleased(MouseEvent e){ 
    Point2D.Double end = new Point2D.Double(e.getX()+focusX,e.getY()+focusY); 
    lines.add(new Line2D.Double(start,end)); 
    repaint(); 
} 
public void keyPressed(KeyEvent e){} 
public void keyReleased(KeyEvent e){} 
public void keyTyped(KeyEvent e){ 
    if(e.getKeyChar()=='w'||e.getKeyChar()=='W'){ 
     focusY-=100; 
     repaint(); 
    } 
    if(e.getKeyChar()=='a'||e.getKeyChar()=='A'){ 
     focusX-=100; 
     repaint(); 
    } 
    if(e.getKeyChar()=='s'||e.getKeyChar()=='S'){ 
     focusY+=100; 
     repaint(); 
    } 
    if(e.getKeyChar()=='d'||e.getKeyChar()=='D'){ 
     focusX+=100; 
     repaint(); 
    } 
    if(e.getKeyChar()=='p'||e.getKeyChar()=='P'){ 
     alive = true; 
     counter = 0; 
     cnt.go = true; 
     co.go = true; 
     useFinal = false; 
     thread = new Slider(); 
     thread.start(); 
     thread.action(true); 
    } 
    if(e.getKeyChar()=='z'||e.getKeyChar()=='Z'){ 
     lines.remove(lines.size()-1); 
     repaint(); 
    } 
    if(e.getKeyChar()=='x'||e.getKeyChar()=='X'){ 
     int response = milkSwing.confirmBox(null, "Do you really want to remove all of your summoned earth?", "Cowbender - The Slope", JOptionPane.YES_NO_OPTION); 
     if(response == JOptionPane.YES_OPTION) lines.clear(); 
     repaint(); 
    } 
    if(e.getKeyChar()=='q'||e.getKeyChar()=='Q'){ 
     System.exit(0); 
    } 
} 

class CoOrdCounter extends Thread{ 
    public boolean go = true; 
    public void run(){ 
     try{ 
      while(true){ 
       if(go){ 
        Thread.sleep(500); 
        printX = cow.x; 
        printY = cow.y; 
        repaint(); 
       } 
      } 
     }catch(Exception e){} 
    } 
} 

class Counter extends Thread{ 
    public boolean go = true; 
    public void run(){ 
     try{ 
      while(true){ 
       if(go){ 
        Thread.sleep(1000); 
        counter++; 
       } 
      } 
     } catch(Exception e){} 
    } 
} 

private class Slider extends Thread{ 
    double velocity, gravity; 
    boolean go = false; 
    public void run(){ 
     if(go){ 
      initGuy(); 
      velocity = 0; 
      gravity = 1; 
     } 
     while(go){ 
      try{ 
       Line2D.Double lineTaken = null; 
       boolean onLine = false; 
       int firstOnLine = -1; 
       for(int i = lines.size()-1; i>=0; i--){ 
        Line2D.Double temp = (Line2D.Double) lines.get(i); 
        if(temp.intersects(cow.x,cow.y,50,50)){ 
         lineTaken = temp; 
         onLine = true; 
         if(firstOnLine!=i){ 
          firstOnLine = i; 
          gravity = 0; 
         } 
         break; 
        } 
       } 
       if(onLine){ 
        double grav = (lineTaken.y2-lineTaken.y1)/50; 
        double vlct = (lineTaken.x2-lineTaken.x1)/100; 
        if(velocity<5)velocity+=vlct; 
        if(gravity<2.5)gravity+=grav; 
       } 
       else{ 
        gravity+=.2; 
       } 
       cow.x+=velocity; 
       cow.y+=gravity; 
       if(cow.x > 10000) alive = false; 

       Thread.sleep(75); 
       repaint(); 
      }catch(Exception e){break;} 
     } 
    } 
    public void action(boolean b){ 
     go = b; 
    } 
    public void initGuy(){ 
     Line2D.Double firstLine = (Line2D.Double) lines.get(0); 
     int x = Integer.parseInt(""+Math.round(firstLine.x1)); 
     int y = Integer.parseInt(""+Math.round(firstLine.y1)); 
     cow = new Rectangle(x+90,y-60,50,50); 
     drawGuy = true; 
    } 
} 
/** 
* @param args 
*/ 
public static void main(String[] args) { 
    CowbenderI g = new CowbenderI(); 

} 
}<br /> 

[編輯4] @MadProgrammer不工作:
enter image description here

+1

使用'javax.swing.Timer'(你的圖形沒有我的機器上對上述原因的工作)來代替,爲[示例](http://stackoverflow.com/a/3256941/230513)。 – trashgod

+0

好吧,我會嘗試 – blustone

+0

@trashgod,但我如何讓數字顯示出來? – blustone

回答

5

你需要告訴您要更新的Swing UI。在你遇到這種情況時可能會違反與事件派發線程的合同(你不應該從任何線程以外的事件派發線程更新UI)

我已經完成的例子下面使用一個簡單的javax.swing.Timer,其克服了這個問題

public class PrintNumbers { 

    public static void main(String[] args) { 
     new PrintNumbers(); 
    } 

    public PrintNumbers() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new PrintPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class PrintPane extends JPanel { 

     private int printX; 
     private int printY; 

     public PrintPane() { 
      Timer timer = new Timer(500, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        printX = (int) Math.round(Math.random() * 1000); 
        printY = (int) Math.round(Math.random() * 1000); 
        repaint(); 
       } 
      }); 
      timer.setRepeats(true); 
      timer.setCoalesce(true); 
      timer.start(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(100, 100); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      int width = getWidth() - 1; 
      int height = getHeight() - 1; 
      FontMetrics fm = g.getFontMetrics(); 
      String text = printX + "x" + printY; 
      int x = (width - fm.stringWidth(text))/2; 
      int y = ((height - fm.getHeight())/2) + fm.getAscent(); 
      g.drawString(text, x, y); 
     } 

    } 

} 

修訂

從示例代碼。

首先,事情是不對您的示例代碼列表...

  • 沒有理由從JFrame擴展或覆蓋paint方法。你最好從JPanel延伸到paintComponent。首先這將爲您提供自動雙緩衝,其次,它將爲您提供靈活的部署選項(將面板添加到JFrameJApplet
  • 您的線程管理需要更多的工作。在while循環中運行線程(什麼都不做)(go爲false)正在浪費CPU,因爲這些線程仍然需要安排運行。請仔細閱讀Concurrency,特別是Synchronization和鎖
  • 通過KeyListener使用key bindings API。它具有更好的焦點控制(組件不必爲了觸發操作而專注)並生成可插入和可重用的代碼。
  • 使用inner classes爲您的事件監聽器。當你真的不想要
  • 時,它將減輕你需要通過主類暴露事件處理方法。在實際情況下,應該避免使用空的異常塊。如果出現問題,catch (Exception e) {}不會告訴你任何事情。至少你應該記錄異常。

至於你的問題..

開始通過使CoOrdCounter#goCounter#goSlider#goCowvolatile

CoOrdCounter#go逃走了,並能夠看到打印到正確的控制檯結果

+0

現在你提到它了,我得到了一個EventDispatchThread錯誤。 – blustone

+0

用於'javax.swing.Timer'的+1。什麼是「EventDispatchThread錯誤?」 – trashgod

+0

@trashgod我不明白了嗎? – blustone