2013-05-11 95 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