简体   繁体   English

重新绘制后未调用覆盖的绘制方法

[英]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. 但是,pain方法中的打印行是永远不会发生的,因此我得出结论,即使重新绘制,也不会调用绘制。 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. 基本问题是您要重写PhysicsEngine类的paint()方法。 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. 您的主类不应只是为了扩展JPanel而创建一个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. 创建框架的逻辑应在main()方法中,然后PysicsEngine面板应包含要为框架构建的所有组件。 Also, custom painting should be done by overriding the paintComponent(...) method, not the paint() method. 另外,自定义绘画应通过重写paintComponent(...)方法而不是paint()方法来完成。

Read the section from the Swing tutorial on Custom Painting for basic painting information and demos. 阅读有关定制绘画的Swing教程中的部分,以获取基本绘画信息和演示。

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. 例如,“ How to Use Buttons教程中的ButtonDemo代码将向您展示如何扩展JPanel并向其中添加按钮。

repaint() stores a request for refreshing a component, request that will be executed by the GUI thread later on. repaint()存储用于刷新组件的请求,该请求稍后将由GUI线程执行。 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. 但是,只有在屏幕上可见的情况下,组件才会刷新,因为您的PhysicsEngine类似乎没有在某些可见的GUI层次结构中用作可见的组件。

Your paint method should be paintComponent and also should call the paintComponent method of super class. 您的paint方法应该是paintComponent ,还应该调用超类的paintComponent方法。

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. 而且您没有将PhysicsEngine JPanel添加到JFrame中,在JPanel子类的构造函数中创建JFrame是非常糟糕的方法。 I create a JFrame in the main method and create a object of PhysicsEngine (JPanel Subclass) and add it into the JFrame. 我在main方法中创建了一个JFrame,并创建了PhysicsEngine(JPanel子类)的对象,并将其添加到JFrame中。 I add the buttons by using this which reference to the PhysicsEngine (JPanel subclass) object. 我使用按钮添加了对PhysicsEngine(JPanel子类)对象的引用。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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