简体   繁体   中英

Overrided paint method not being called after repaint is

My problem is essentially creating a physics engine with a few different scenarios. I would like to consolidate the different scenarios into one window by having buttons that run each individually. The frame works properly and the buttons show up and can be pressed; however, that print line in the pain method is never happening and from there I concluded that paint is not being called even after repaint is. I understand that they are not the same but I don't understand why paint isn't being accessed in this instance compared to others.

  import java.awt.Graphics;
  import java.awt.Graphics2D;
  import java.awt.RenderingHints;
  import java.awt.event.*;
  import javax.swing.JFrame;
  import javax.swing.JPanel;
  import java.awt.Color;
  import javax.swing.JButton;

  public class PhysicsEngine extends JPanel{
     double x ,y;

     JFrame frame;
     JPanel pan;
     JButton b1;
     JButton b2;
     JButton b3;
     JButton b4;
     JButton b5;

     public static void main(String[] args){
        PhysicsEngine gui = new PhysicsEngine();
    }

     public PhysicsEngine(){
        frame = new JFrame("Ball Engine");

        pan = new JPanel();
        frame.add(pan);

        b1 = new JButton("1");
        b1.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent event){
              try{
                 startFirst();
              } 
              catch(InterruptedException exception){}
           }
        });
        pan.add(b1);

        b2 = new JButton("2");
        b2.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e){
              try{
                 startSecond();
              } 
              catch(InterruptedException exception){}
           }
        });
        pan.add(b2);


        b3 = new JButton("3");
        b3.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e){
              try{
                 startThird();
              } 
              catch(InterruptedException exception){}
           }
        });
        pan.add(b3);

        b4 = new JButton("4");
        b4.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e){
              try{
                 startFourth();
              } 
              catch(InterruptedException exception){}
           }
        });
        pan.add(b4);

       b5 = new JButton("5");
       b5.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e){
             try{
                startFifth();
             } 
             catch(InterruptedException exception){}
          }
       });
       pan.add(b5);

       frame.setSize(600, 600);
      frame.setVisible(true);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     }

     public void paint(Graphics g) {
          super.paint(g);

          System.out.println(""+y);

          Graphics2D g2d = (Graphics2D) g;
         g2d.setColor(Color.RED);   
         g2d.fillOval((int)x, (int)y, 30, 30);
    }

     public void startFirst() throws InterruptedException{
        x = 300;

        for(int t = 1;;t++){
           //xPos= 0*t*t + 0*t + 300 this is constant at 300
           if(y>=615) break; //stops the loop when the ball is off the screen

           y = .1*t*t + 0*t + 80; //parametric equation for y
           repaint();
           Thread.sleep(10);
        }
     }

     public void startSecond() throws InterruptedException{
        x = 300;

        for(int t = 1;;t++){
           //xPos= 0*t*t + 0*t + 300 this is constant at 300
           if(y>=615) break; //stops the loop when the ball is off the screen

           y = .1*t*t - 10*t + 550; //parametric equation for y
           repaint();
           Thread.sleep(10);
        }
     }

     public void startThird() throws InterruptedException{      
        for(int t = 1;;t++){
           if(y>=615||x>=615) break; //stops the loop when the ball is off the screen

           y = .1*t*t - 10*t + 550; //parametric equation for y
           x = 0*t*t + 5*t + 50; //parametric equation for x
           repaint();
           Thread.sleep(10);
        }
     }

     public void startFourth() throws InterruptedException{      
        for(int t = 1;;t++){
           //xPos= 0*t*t + 0*t + 300 this is constant at 300
           if(y>=615||x>=615) break; //stops the loop when the ball is off the screen

           y = t*t*t + 50; //given parametric equation for y
           x = t - 4; //given parametric equation for x
           repaint();
           Thread.sleep(10);
        }
     }

     public void startFifth() throws InterruptedException{      
        for(int t = 1;t<500 /* goes for 5 seconds */;t++){        
           y = 200*Math.sin(t) + 300; //given parametric equation for y
           x = 200*Math.cos(t) + 300; //given parametric equation for x
           repaint();
           Thread.sleep(10);
        }
     }
  }

The basic problem is you are overriding the paint() method of the PhysicsEngine class. But you never add an instance of this class to the frame.

However, the bigger problem is the structure of your class. Your main class should not be extending a JPanel just so you can create a JFrame. The logic for creating the frame should be in the main() method and then your PysicsEngine panel should contain all the components you want to build for your frame. Also, custom painting should be done by overriding the paintComponent(...) method, not the paint() method.

Read the section from the Swing tutorial on Custom Painting for basic painting information and demos.

Then you can look at other sections in the tutorial for a better way to structure your code. For example the ButtonDemo code found in the How to Use Buttons tutorial will show you how to extend a JPanel and add buttons to it.

repaint() stores a request for refreshing a component, request that will be executed by the GUI thread later on. But a component will be refreshed only if it is visible on screen, alas your PhysicsEngine class doesn't seem to be used as a visible component in some visible GUI hierarchy.

Your paint method should be paintComponent and also should call the paintComponent method of super class.

And you don't add the PhysicsEngine JPanel into the JFrame, and it is very bad approach to create a JFrame in the constructor of JPanel subclass. I create a JFrame in the main method and create a object of PhysicsEngine (JPanel Subclass) and add it into the JFrame. I add the buttons by using this which reference to the PhysicsEngine (JPanel subclass) object.

Here is the working code:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JButton;

public class PhysicsEngine extends JPanel {

double x, y;

JPanel pan;
JButton b1;
JButton b2;
JButton b3;
JButton b4;
JButton b5;

public static void main(String[] args) {

    JFrame frame = new JFrame("Ball Engine");
    PhysicsEngine gui = new PhysicsEngine();
    frame.add(gui, BorderLayout.CENTER);
    frame.setSize(600, 600);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

public PhysicsEngine() {

    b1 = new JButton("1");
    b1.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent event) {
            try {
                startFirst();
            } catch (InterruptedException exception) {
            }
        }
    });
    this.add(b1);

    b2 = new JButton("2");
    b2.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            try {
                startSecond();
            } catch (InterruptedException exception) {
            }
        }
    });
    this.add(b2);

    b3 = new JButton("3");
    b3.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            try {
                startThird();
            } catch (InterruptedException exception) {
            }
        }
    });
    this.add(b3);

    b4 = new JButton("4");
    b4.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            try {
                startFourth();
            } catch (InterruptedException exception) {
            }
        }
    });
    this.add(b4);

    b5 = new JButton("5");
    b5.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            try {
                startFifth();
            } catch (InterruptedException exception) {
            }
        }
    });
    this.add(b5);

}

public void paintComponent(Graphics g) {
    super.paintComponent(g);

    System.out.println("" + y);

    Graphics2D g2d = (Graphics2D) g;
    g2d.setColor(Color.RED);
    g2d.fillOval((int) x, (int) y, 30, 30);
}

public void startFirst() throws InterruptedException {
    x = 300;

    for (int t = 1;; t++) {
        // xPos= 0*t*t + 0*t + 300 this is constant at 300
        if (y >= 615)
            break; // stops the loop when the ball is off the screen

        y = .1 * t * t + 0 * t + 80; // parametric equation for y
        repaint();
        Thread.sleep(10);
    }
}

public void startSecond() throws InterruptedException {
    x = 300;

    for (int t = 1;; t++) {
        // xPos= 0*t*t + 0*t + 300 this is constant at 300
        if (y >= 615)
            break; // stops the loop when the ball is off the screen

        y = .1 * t * t - 10 * t + 550; // parametric equation for y
        repaint();
        Thread.sleep(10);
    }
}

public void startThird() throws InterruptedException {
    for (int t = 1;; t++) {
        if (y >= 615 || x >= 615)
            break; // stops the loop when the ball is off the screen

        y = .1 * t * t - 10 * t + 550; // parametric equation for y
        x = 0 * t * t + 5 * t + 50; // parametric equation for x
        repaint();
        Thread.sleep(10);
    }
}

public void startFourth() throws InterruptedException {
    for (int t = 1;; t++) {
        // xPos= 0*t*t + 0*t + 300 this is constant at 300
        if (y >= 615 || x >= 615)
            break; // stops the loop when the ball is off the screen

        y = t * t * t + 50; // given parametric equation for y
        x = t - 4; // given parametric equation for x
        repaint();
        Thread.sleep(10);
    }
}

public void startFifth() throws InterruptedException {
    for (int t = 1; t < 500 /* goes for 5 seconds */; t++) {
        y = 200 * Math.sin(t) + 300; // given parametric equation for y
        x = 200 * Math.cos(t) + 300; // given parametric equation for x
        repaint();
        Thread.sleep(10);
    }
}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM