2013-05-11 84 views
0

我對Java相當陌生,我試圖創建一個程序,在這個程序中,計算機繪製隨機的圓圈,矩形和線條,然後計算它們的正下方顯示的數字。JPanel實際上如何工作?

import java.awt.Graphics; 
import java.util.Random; 
import javax.swing.JPanel; 

public class Shapes extends JPanel{ 

` private int noOfCircles; 
    private int noOfLines; 
    private int noOfRect; 

    public void paintComponent(Graphics g){ 

     Random rand = new Random(); 
     super.paintComponent(g); 

     int x = 10; 
     int y = 10; 

     noOfCircles = 0; 
     noOfLines = 0; 
     noOfRect = 0; 


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

      int choice = rand.nextInt(3); 

      if(choice == 0){ 
       noOfLines++; 
       g.drawLine(x, y, i*10+50, i+100); 
      } 
      else if(choice == 1){ 
       noOfRect++; 
       g.drawRect(i*20, y*20, x*10, y *10); 
      } 
      else{ 
       noOfCircles++; 
       g.drawOval(x*10, i*20, x*10, y*10); 
      } 
      x+=5; 
      y+=5; 

     } 

     System.out.println(status()); 

    } 

    public String status(){ 

     String message = String.format("Circles : %d; Rect : %d; Lines : %d;", noOfCircles, noOfRect, noOfLines); 
     return message; 
    } 

} 

而且

import java.awt.BorderLayout; 
import javax.swing.JLabel; 
import javax.swing.JFrame; 

public class ShapesTest { 

    public static void main(String args[]){ 

     Shapes panel  = new Shapes(); 
     JFrame app  = new JFrame(); 
     JLabel statusBar = new JLabel(); 

     String message = panel.status(); 
     statusBar.setText(message); 
     statusBar.setSize(400, 20); 

     app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     app.add(panel); 
     app.add(statusBar, BorderLayout.SOUTH); 
     app.setSize(400, 400); 
     app.setVisible(true); 

    } 

} 

問題是,Shape類總是返回noOfCircles,noOfLines,noOfRect = 0不管它們被稱爲時。我不明白它是如何工作

+0

你有程序邏輯的paintComponent方法,通常是一個壞主意的內部,並且在邏輯您重新零出你的int字段在方法的開始。你的實際任務狀態你必須做什麼? – 2013-05-11 15:29:50

回答

1

這工作和調整大小不更新。 同樣的看法和邏輯是分開的。

import java.awt.BorderLayout; 
import javax.swing.JLabel; 
import javax.swing.JFrame; 

public class ShapesTest { 

    public static void main(String args[]){ 

     Shapes panel  = new Shapes(); 
     JFrame app  = new JFrame(); 
     JLabel statusBar = new JLabel(); 

     statusBar.setSize(400, 20); 
     app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     app.add(panel); 
     app.add(statusBar, BorderLayout.SOUTH); 
     app.setSize(400, 400); 
     app.setVisible(true); 

     statusBar.setText(panel.status()); 

    } 

} 

import java.awt.Graphics; 
import javax.swing.JPanel; 
import java.util.Random; 

public class Shapes extends JPanel{ 
    private static final int TYPE_LINE = 0; 
    private static final int TYPE_RECT = 1; 
    // private static final int TYPE_OVAL = 2; // not used 
    private int[] forms = new int[10]; 

    private int c = 0, r = 0, l = 0; 

    public Shapes() { 
     super(); 

     Random rand = new Random(); 

     for(int i = 0; i < forms.length; i++) { 
      int choice = rand.nextInt(3); 

      if(choice == TYPE_LINE) 
       c++; 
      else if(choice == TYPE_RECT) 
       r++; 
      else 
       l++; 

      forms[i] = choice; 
     } 
    } 

    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 

     int x = 10; 
     int y = 10; 

     for(int i = 0; i < forms.length; i++) { 
      int choice = forms[i]; 

      if(choice == TYPE_LINE){ 
       g.drawLine(x, y, i*10+50, i+100); 
      } 

      else if(choice == TYPE_RECT){ 
       g.drawRect(i*20, y*20, x*10, y *10); 
      } 

      else { 
       g.drawOval(x*10, i*20, x*10, y*10);  
      } 

      x+=5; 
      y+=5; 
     } 
    } 

    public String status(){   
     String message = String.format("C:%d;R:%d;L:%d", c, r, l); 
     return message; 
    } 
} 
+0

謝謝,現在它的工作。你能解釋一下我的代碼出了什麼問題嗎?我可以看到paintComponent和其他方法中對象變量的增量工作方式不同。 – tehTerminator 2013-05-12 12:11:05

+1

我分離了視圖和邏輯,所以在開始時計算了繪製了多少個矩形,線條和圓。因此在調用status()之前不需要繪製面板。所以在你的代碼中,狀態可能在'paintComponent(g)'被執行之前更新 – kelunik 2013-05-12 12:20:05

2

你的問題是,你叫

String message = panel.status(); 
statusBar.setText(message); 

在你的JPanel是可見的,所以它從未被繪製。

import java.awt.BorderLayout; 
import javax.swing.JLabel; 
import javax.swing.JFrame; 

public class ShapesTest { 

    public static void main(String args[]){ 

     Shapes panel  = new Shapes(); 
     JFrame app  = new JFrame(); 
     JLabel statusBar = new JLabel(); 

     statusBar.setSize(400, 20); 

     app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     app.add(panel); 
     app.add(statusBar, BorderLayout.SOUTH); 
     app.setSize(400, 400); 
     app.setVisible(true); 

     String message = panel.status(); 
     statusBar.setText(message); 
    } 

} 

有了這個ShapesTest級應該按預期工作,但由於氣墊船全鰻魚提到你應該分開邏輯(控制器)和渲染(視圖)

+0

不錯的拿起和回答。 1+ – 2013-05-11 16:39:45

+0

好的根據氣墊船充滿了鰻魚我已經分開了paintComponent的邏輯,在app.setVisible之後也被稱爲setText方法,但問題沒有解決。它仍然顯示0,0,0爲圓形,矩形和線條。 – tehTerminator 2013-05-12 11:02:40

+0

[鏈接](http://pastebin.com/1F3Gpa0W)** Shapes.java ** [鏈接](http://pastebin.com/jM3kgiSR)** ShapesTest.java ** [鏈接](http ://pastebin.com/DKGBUrs3)** Counter.java ** – tehTerminator 2013-05-12 11:09:43