Frage

I am writing the implementation of Galton Board in Java by using Java awt, Swing and thread. My Program has three text field to choose number of slots, number of balls, and number of ball drops at the same time, two buttons one for display and one for start the program. I try to make it work like I can choose the amount of balls and click start and the balls auto falling down the chimney. Currently, My program be able to drop one ball and running fine, but I don't know how to implement that be able drop more than one ball. Any suggestions or help are appreciated, Thank you. This is 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);
   }
}

main panel class contains the chimneys and balls

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();


            }
}

Balls Class

    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;


}

}

War es hilfreich?

Lösung

Create a new logical class, not a GUI class, for your Ball, one that does not extend a JPanel or any Swing component, but rather one that has the logic behind the Ball as well as perhaps a rendering method that accepts a Graphics or Graphics2D object. Then give your drawing JPanel class an ArrayList of these Ball objects, move them in your game loop -- note that I would prefer using a Swing Timer and not a background thread, and then in your JPanel's paintComponent method iterate through the ArrayList of Balls, drawing each Ball by calling its rendering method.

As an aside: all your class names should begin with an upper case letter, and all identifiers other than constants should use camel case, so your mainpanel class should be named MainPanel. I've edited your code prettify the code formatting and have made this change for you.

Aside number 2: your current code has code logic inside of paintComponent. Don't do that as that will mess you up. You don't have full control over when or even if paintComponent will be called.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top