重绘时是否会再次执行随机函数?

时间:2014-07-29 00:11:09

标签: java swing jpanel repaint

我正在编写代码,我在JPanel上绘制多个形状然后调用repaint。我认为当我调用重绘时,JPanel中的形状应该移动到一个新位置,因为随机函数现在将提供不同的值。但形状根本不动。任何想法为什么会发生这种情况?

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

@SuppressWarnings("serial")
public class Filter extends JFrame
{
    public static void main(String[] args)
      {
            SwingUtilities.invokeLater(new Runnable()
            {  
                public void run() 
                {
                    Filter mainFrame = new Filter();
                    mainFrame.setVisible(true);
                }
            });
      }

    public Filter()
    {
        //Creating the JFrame main window
        setSize(800, 500);
        setTitle("Particle Filter");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLocation(100, 100);
        getContentPane().setLayout(new BoxLayout(this.getContentPane(), BoxLayout.X_AXIS));

        //creates two panels content and sidebar. Sidebar has null layout       
        JPanel content = new JPanel();
        content.setPreferredSize(new Dimension(700,500));
        content.setBackground(Color.LIGHT_GRAY);
        this.getContentPane().add(content);
        JPanel sidebar = new JPanel();
        sidebar.setBackground(Color.LIGHT_GRAY);
        sidebar.setPreferredSize(new Dimension(100,500));
        this.getContentPane().add(sidebar);
        sidebar.setLayout(null);

        //creates three buttons in sidebar
        JButton start_button = new JButton("START");
        start_button.setBounds(10, 75, 77, 23);

        start_button.addActionListener(new MainPanel());       

        sidebar.add(start_button);
        JButton stop_button = new JButton("STOP");
        stop_button.setBounds(10, 109, 77, 23);
        sidebar.add(stop_button);
        JButton reset_button = new JButton("RESET");
        reset_button.setBounds(10, 381, 77, 23);
        sidebar.add(reset_button);

        //calls the content_Walls class and sends the number of ovals to be generated
        content.add( new MainPanel());
    }

}

@SuppressWarnings("serial")
class MainPanel extends JPanel implements ActionListener
{
    public MainPanel()
    {
        setPreferredSize(new Dimension(680,450));
        setBackground(Color.WHITE);
        setBorder(BorderFactory.createLineBorder(Color.black));
    }

    public void actionPerformed(ActionEvent e)
    {
        if (e.getActionCommand().equals("START"))
        {
            repaint();
        }


    }

    @Override
    public void paintComponent(Graphics g)
    {   
        super.paintComponent(g);
        drawParticles(g);
        createObstacles(g,150,225,100,40);
        createObstacles(g,500,300,40,100);
        createRobot(g);        
    }

    private void createRobot(Graphics g)
    {
        int x=0, y=0;     
        int robot_radius=50;
        ArrayList<Integer> robot_list= new ArrayList<Integer>();
        robot_list=positionRobot(x,y);
        drawRobot(g,robot_list.get(0),robot_list.get(1),robot_radius);
    }

    private void drawParticles(Graphics g)
    {
        int n=1000; // n denotes the number of particles    
        ArrayList<Integer> list;        
        list = new ArrayList<Integer>(Collections.nCopies(n, 0));
        for(int i=0;i<list.size();i++)
        {
           generateParticles(g);
        }
    }

    private void generateParticles(Graphics g)
    {
        int x=0;
        int y=0;
        int radius = 4;
        ArrayList<Integer> list= new ArrayList<Integer>();
        list=positionParticles(x,y);
        g.setColor(Color.RED);
        g.fillOval(list.get(0),list.get(1), radius, radius);
    }

    private ArrayList<Integer> positionParticles(int x, int y)
    {
        int radius = 4;
        ArrayList<Integer> list= new ArrayList<Integer>();
        x=randomInteger(2,678); // bounds of x between which the particles should be generated
        y=randomInteger(2,448); // bounds of y between which the particles should be generated
        x=x-(radius/2);
        y=y-(radius/2);
        if((x<251&&x>=150)&&(y<266&&y>=225))
        {
            x=0;
            y=0;
            positionParticles(x,y);
        }
        if((x<541&&x>499)&&(y<401&&y>299))
        {
            x=0;
            y=0;
            positionParticles(x,y);
        }
        list.add(x);
        list.add(y);
        return list;
    }

    private ArrayList<Integer> positionRobot(int x, int y)
    {
        int robot_radius=50;   
        ArrayList<Integer> list= new ArrayList<Integer>();
        x=randomInteger(25,655);//so that it stays inside the content_Walls panel 
        y=randomInteger(25,425); //so that it stays inside the content_Walls panel 
        x=x-(robot_radius/2);
        y=y-(robot_radius/2);
        if((x<250&&x>=150)&&(y<=265&&y>=225))
        {
           x=0;
           y=0;
           positionRobot(x,y);
        }
        if((x<=540&&x>=500)&&(y<=400&&y>=300))
        {
            x=0;
            y=0;
            positionRobot(x,y);
        }
        list.add(x);
        list.add(y);
        return list;            
    }

    private void createObstacles(Graphics g, int x, int y, int width, int height)
    {
        g.setColor(Color.BLACK);
        g.fillRect(x, y, width, height);
    }

    private void drawRobot(Graphics g, int x, int y, int radius)
    {
        g.setColor(Color.GREEN);
        g.fillOval(x, y, radius, radius);   
    }

    private static int randomInteger(int min, int max)
    {
        Random rand = new Random();
        int randomNum = rand.nextInt((max - min) + 1) + min;
        return randomNum;
    }

}

2 个答案:

答案 0 :(得分:5)

基本问题是,响应MainPanel的{​​{1}}实例与屏幕上JButton的实例不同...

MainPanel

相反,创建一个实例并在两种情况下使用它......

// Instance one...
start_button.addActionListener(new MainPanel());
//...
// Instance two...
//calls the content_Walls class and sends the number of ovals to be generated
content.add(new MainPanel());

当你开始插入停止按钮的功能时,再次使用相同的实例。

答案 1 :(得分:0)

那可能是因为你没有使用种子值,对于Random的cunstructor。但不确定这是用Java还是用其他语言。 (阅读文档,也许是另一种语言)

Random rand = new Random();

您可以将时间用作种子值:

Random rand = new Random(System.currentTimeMillis());

也可以将rand作为一个字段并且只对它进行一次修改:

private static Random rand;
private static int randomInteger(int min, int max)
{
    if (rand == null)
       rand = new Random();
    int randomNum = rand.nextInt((max - min) + 1) + min;
    return randomNum;
}

代码不是testet。对不起,我快要睡了。