在java中实现Galton板

时间:2014-05-06 22:48:32

标签: java multithreading swing awt

我使用Java awt,Swing和线程编写了Java中Galton Board的实现。我的程序有三个文本字段,可以同时选择插槽数,球数和球数,两个按钮用于显示,一个用于启动程序。我试着让它工作,就像我可以选择球的数量和点击开始和球自动从烟囱落下。目前,我的计划能够丢球并运行良好,但我不知道如何实施能够丢球的球。任何建议或帮助表示赞赏,谢谢。这是Main.Class

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Random;
import javax.swing.*;

public class Main extends JFrame {
   private String num_slots;
   private String num_balls;
   private String ball_free;
   private JButton Display;
   private JButton Start;
   private JPanel textpanel;
   private JPanel mainpanel;
   private JPanel graphpanel;

   public Main() {
      textpanel = new JPanel();
      textpanel.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 20));
      textpanel.add(new JLabel("Number of Slots"));
      final JTextField text1 = new JTextField(10);
      textpanel.add(text1);
      textpanel.add(new JLabel("Number of Balls"));
      final JTextField text2 = new JTextField(10);
      textpanel.add(text2);
      textpanel.add(new JLabel("How many balls can be freed"));
      final JTextField text3 = new JTextField(10);
      textpanel.add(text3);
      Display = new JButton("Display");
      textpanel.add(Display);
      Start = new JButton("Start");
      textpanel.add(Start);
      // Create panel p2 to hold a text field and p1
      mainpanel = new JPanel(new BorderLayout());
      mainpanel.add(textpanel, BorderLayout.NORTH);
      /*
       * graphpanel = new JPanel(); graphpanel.setLayout(new
       * BoxLayout(graphpanel, BoxLayout.Y_AXIS));
       */
      add(mainpanel, BorderLayout.CENTER);
      Display.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            if (e.getSource() == Display) {
               num_slots = text1.getText();
               int slots = Integer.parseInt(num_slots);
               num_balls = text2.getText();
               int balls = Integer.parseInt(num_balls);
               MainPanel pa = new MainPanel(slots, balls);
               mainpanel.add(pa);
               mainpanel.revalidate();
            }
         }
      });
      Start.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            if (e.getSource() == Start) {
               num_slots = text1.getText();
               int slots = Integer.parseInt(num_slots);
               num_balls = text2.getText();
               int balls = Integer.parseInt(num_balls);
               MainPanel pa = new MainPanel(slots, balls);
               mainpanel.add(pa, BorderLayout.CENTER);
               pa.start();
               mainpanel.revalidate();
               mainpanel.repaint();
            }
         }
      });
   }

   public static void main(String[] args) {
      // TODO Auto-generated method stub
      Main frame = new Main();
      frame.setTitle("The Galton board");
      frame.setSize(1000, 800);
      frame.setLocationRelativeTo(null); // Center the frame
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setVisible(true);
      frame.setAutoRequestFocus(true);
   }
}

主面板类包含烟囱和球

import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;

import javax.swing.JPanel;

class MainPanel extends JPanel implements Runnable {
   private int num;
   private int number_ball;
   public static int start_y = 100;
   private float ball_x = 385;
   private float ball_y = 50;
   private float radius = 15;
   private static int panel_x = 300;
   private static int panel_y = 100;
   private int diameter = 20;
   private int last_x = 0;
   private final static Random generator = new Random();
   ArrayList<Balls> list_ball = new ArrayList<Balls>();
   private int m_interval = 100;
   private Timer m_timer;
   public MainPanel() {
   }

   public MainPanel(int number) {
      num = number;
   }

   public MainPanel(int number, int ball) {
      num = number;
      number_ball = ball;
      for (int i = 1; i <= number_ball; i++)   
      {   
            list_ball.add(new Balls()); 

      }   
      m_timer = new Timer(m_interval, new TimerAction());
   }

   public int getPanel_y() {
      return panel_y;
   }
   public void start()
   {
        m_timer.setInitialDelay(250);
        m_timer.start();

   }
   @Override
   protected void paintComponent(Graphics g) {
      int start_y = 100;
      panel_x = 300;
      panel_y = 100;
      diameter = 20;
      last_x = 0;
      super.paintComponent(g);
      if (num % 2 == 0) {
         for (int i = 1; i <= num; i++) {
            if ((i % 2) != 0) {
               for (int k = 1; k <= num; k++) {
                  g.setColor(Color.BLUE);
                  g.fillOval(panel_x, panel_y, diameter, diameter);
                  panel_x = panel_x + 40;
               }
            } else if ((i % 2) == 0) {
               for (int k = 1; k <= num + 1; k++) {
                  g.setColor(Color.BLUE);
                  g.fillOval(panel_x - 20, panel_y, diameter, diameter);
                  panel_x = panel_x + 40;
               }
            }
            panel_y = panel_y + 40;
            panel_x = 300;
         }
      } else if (num % 2 != 0) {
         for (int i = 1; i <= num; i++) {
            if ((i % 2) != 0) {
               for (int k = 1; k <= num; k++) {
                  g.setColor(Color.BLUE);
                  g.fillOval(panel_x, panel_y, diameter, diameter);
                  panel_x = panel_x + 40;
               }
            } else if ((i % 2) == 0) {
               for (int k = 1; k <= num + 1; k++) {
                  g.setColor(Color.BLUE);
                  g.fillOval(panel_x - 20, panel_y, diameter, diameter);
                  panel_x = panel_x + 40;
               }
            }
            panel_y = panel_y + 40;
            panel_x = 300;
         }
      }
      for (int n = 40; n < panel_y - 40; n = n + 40) {
         if (num % 2 == 0) {
            g.drawLine(panel_x - 50 + n, panel_y - 10, panel_x - 50 + n,
                  panel_y + 80);
            g.drawLine(panel_x, panel_y + 80, panel_x - 50 + n, panel_y + 80);
            last_x = panel_x - 50 + n;
         } else if (num % 2 != 0) {
            g.drawLine(panel_x - 30 + n, panel_y - 10, panel_x - 30 + n,
                  panel_y + 80);
            g.drawLine(panel_x, panel_y + 80, panel_x - 30 + n, panel_y + 80);
            last_x = panel_x - 30 + n;
         }
      }
      for (int i = 0; i< list_ball.size(); i++)
      {
       list_ball.get(i).draw(g);

      }
   }
    class TimerAction implements ActionListener {   
        public void actionPerformed(ActionEvent e) {
            for (int i = 0; i< list_ball.size(); i++)
            {

                    list_ball.get(i).move();
                    //return;

                    //m_timer.stop();
                    repaint();


            }
}

球类

    import java.awt.geom.Ellipse2D;
    import java.util.Random;
    import java.awt.*;

    public class Balls {
     private Ellipse2D.Double thisBall;
     private int Ball_x;
     private int Ball_y;
     public int radius;
     public  int start_y; 
     private final static Random generator = new Random();  
     Mainpanel pa = new Mainpanel();
     public Balls()
     {
    start_y = 100;
    Ball_x = 385;
    Ball_y = 50;
    radius = 15;

     }
     public void draw(Graphics g)
     {
    g.setColor(Color.RED);
    g.fillOval(Ball_x, Ball_y, radius, radius);
     }
     public void move()
     {
     if (Ball_y < pa.getPanel_y() + 65)  
             {  
               int direction = generator.nextInt(2); 
               Ball_y = Ball_y + 5;  
               if (Ball_y == start_y - 10 && start_y < pa.getPanel_y()) 
               { 
                   if (direction == 0) 
                   { 
                     Ball_x = Ball_x - 20; 
                   } 
               else Ball_x = Ball_x + 20; 
               start_y = start_y + 40; 
          } 

        System.out.println(Ball_y);
        System.out.println(pa.getPanel_y());    
     }  
    // Ball_x = Ball_x + 5;


}

}

1 个答案:

答案 0 :(得分:3)

为Ball创建一个新的逻辑类,而不是GUI类,一个不扩展JPanel或任何Swing组件的逻辑类,而是一个具有Ball背后逻辑的逻辑类,也可能是一个接受a的渲染方法Graphics或Graphics2D对象。然后给你的绘图JPanel类一个这些Ball对象的ArrayList,在你的游戏循环中移动它们 - 注意我更喜欢使用Swing Timer而不是后台线程,然后在你的JPanel的paintComponent方法中迭代Ball的ArrayList,通过调用其渲染方法绘制每个Ball。

顺便说一句:所有类名都应以大写字母开头,除常量之外的所有标识符都应使用驼峰大小写,因此您的主面板类应命名为MainPanel。我编辑了你的代码,使代码格式化,并为你做了这个改变。

除了数字2:您当前的代码在paintComponent中有代码逻辑。不要这样做,因为那会弄乱你。您无法完全控制何时或甚至调用paintComponent。