JPanel如何实际运作?

时间:2013-05-11 15:27:50

标签: java swing jframe jpanel

我对Java很陌生,我正在尝试创建一个程序,在这个程序中,计算机绘制随机圆圈,矩形和线条,然后计算它们下面显示的数字。

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在调用它们时没有问题。我不明白它是如何运作的

2 个答案:

答案 0 :(得分: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类它应该按预期工作,但正如Hovercraft Full Of Eels所提到的那样你应该分离逻辑(控制器)和渲染(视图)

答案 1 :(得分: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;
    }
}