有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java repaint()方法未重新绘制JPanel

好的,首先我知道关于这个问题还有很多其他的线程,但是他们只说尝试使用invalidate()和validate(),这对我没有任何影响

我的问题是——正如标题所表明的——JPanel的repaint()方法不会重新绘制。我在paintComponent()方法中添加了一些调试消息,以下是控制台输出:

Debug
-10 421 010 441
repainted
Moved mouse
Moved mouse
Moved mouse
Moved mouse
Moved mouse
Moved mouse
Moved mouse
Moved mouse
Moved mouse
Moved mouse
Moved mouse
Moved mouse
Moved mouse
Moved mouse
Moved mouse
Moved mouse

请注意,在程序开始时,您只看到debug(co-ordinates)repainted一次,但我调用repaint();每次移动鼠标时

我将我的五个类添加到一个类中,因为我认为这是调试的首选:

package com.trtld.spacewar;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class GroupClass {
     private static Content content = new Content();

    public static void main(String[] args) {
        JFrame window = new JFrame("Spacewar!");
        content.setVisible(true);
        window.setContentPane(content);
        MouseInput listener = new MouseInput();
        content.addMouseMotionListener(listener);
        content.addMouseListener(listener);
        window.setSize(600, 480);
        window.setLocation(100, 100);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setVisible(true);
        //window.setResizable(false);
        System.out.println("Debug");
    }


}

 class Target {

    private int x1, y1;
    private int x2, y2;

    public Target(int x1, int y1, int x2, int y2){
        this.x1 = x1; 
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;

    }

    public int getX1(){
        return x1;
    }
    public int getX2(){
        return x2;
    }
    public int getY1(){
        return y1;
    }
    public int getY2(){
        return y2;
    }
}
class Content extends JPanel{

        private static Content instance;
        private Target[] targets = new Target[9];   
        private Bullet[] bullets = new Bullet[999];//assuming no more than 1000 bullets are on the screen at
                                                  //once (they'd have to have a really fancy-nice auto-clicker ha ha)
        int spaceShipX = (getWidth()/2); 





        public Content (){
            int yLevel = (((int)Math.random())*(getHeight() / 4));
            int xPos = ((int)Math.random())*getWidth();
            for(int i = 0;!(i == 9); i++){                                         //Create the randomly located targets
                targets[i] = new Target(xPos, yLevel, xPos-15, yLevel-10);
            }
        }

        public void paintComponent(Graphics g){
             super.paintComponent(g);  
             g.setColor(Color.RED);
             System.out.println(spaceShipX-10 + " " + (getHeight()-20) + " " + spaceShipX+10 + " " + getHeight());
             System.out.println("repainted");
             g.fillRect(spaceShipX+50, getHeight()-20 ,spaceShipX+100 , getHeight());

             /**  //commented out for simplicity + needs to be fixed:
                for(Target t : this.targets){        //paint targets
                    g.drawRect(t.getX1(), t.getY1(), t.getX2(), t.getY2());
                }
                for(Bullet b : this.bullets){         //paint bullets and remove invalid ones plus check for hits
                    if(b != null){


                    g.drawRect(b.getX1(), b.getY1(), b.getX2(), b.getY2());

                    if(!(b.checkTargetPresence() == null)){
                        for(Target target : targets){
                            if(b.checkTargetPresence() == target){
                                target = null;
                            }
                        }
                    }

                    if(b.isValid() == false){
                        b = null;
                    }
                }
                }*/
        }


        public static Content getInstance(){
            if(instance == null) {
                instance = new Content();     //TODO: Singletons are out-dated and not preferred; fix this
                }
                return instance;
        }


    //Getters and setters:

        public Bullet[] getBullets(){
            return bullets;
        }

        public Target[] getTargets(){
            return targets;
        }

        public void setTarget(Target t, int loc){
            this.targets[loc] = t;
        }

        public void setBullet(Bullet b){
            int location = -1;
            if(bullets[0] == null){
            this.bullets[0] = b;
            return;
            }
            for(Bullet bullet: bullets){
                location++;
            if(bullets[location] == null){ //TODO: Messy, clean this up
                bullets[location] = b;
                return;
            }   
            }

        }
        public int getSpaceShipX(){
        return spaceShipX;
        }
        public void setSpaceShipX(int x){
            spaceShipX = x-10;
            repaint();

        }

    }
class Bullet implements ActionListener{

    int x1, x2;
    int y1 = 10, y2 = 5;

    Timer timer = new Timer(250, this);

    public Bullet(int x1, int x2){
        this.x1 = x1;
        this.x2 = x2;
        timer.start();
    }

    public void actionPerformed(ActionEvent evt) {
        y1 = y1 + 2;
        y2 += 2;
        Content.getInstance().repaint();
    }

    public Target checkTargetPresence(){
        for(Target t : Content.getInstance().getTargets()){
            if(x1 <= t.getX1() && x1 >= t.getX2()){
                if(y1 <= t.getY1() && y1 >= t.getY2()){
                         //HIT!
                    return t;
                }
            }
        }
        return null; //TODO

    }

    public boolean isValid(){//Checks if the bullet is still on the screen

        if(y1 >= Content.getInstance().getHeight() || y2 >= Content.getInstance().getHeight()){
            return false;
        }else{
            return true;
        }

    }
    public int getX1(){
        return x1;
    }
    public int getX2(){
        return x2;
    }
    public int getY1(){
        return y1;
    }
    public int getY2(){
        return y2;
    }
}
class MouseInput implements MouseListener, MouseMotionListener {

    public void mouseDragged(MouseEvent arg0) {     
    }

    public void mouseMoved(MouseEvent evt) {
        Content.getInstance().setSpaceShipX(evt.getX());
        Content.getInstance().repaint(); // I try to repaint here and in the Content class, but nothing happens.
        System.out.println("Moved mouse");
    }

    public void mouseClicked(MouseEvent arg0) {

    }

    public void mouseEntered(MouseEvent arg0) {     
    }

    public void mouseExited(MouseEvent arg0) {      
    }

    public void mousePressed(MouseEvent evt) {  
    Content.getInstance().setBullet(new Bullet(evt.getX()-2, evt.getX()+2));
    System.out.println("clicked");
    }

    public void mouseReleased(MouseEvent arg0) {    
    }

}

我将非常感谢任何帮助,如果我需要不同的格式,请让我知道。 请注意,这是我的第一个GUI程序


共 (1) 个答案

  1. # 1 楼答案

    我认为问题在于创建一个内容类,然后将其添加到框架中

    但是,在MouseListener代码中,调用内容类的getInstance()方法,并且“instance”变量为null,因此创建了一个新的内容实例(但从未添加到框架中,因此它永远不会被绘制)

    所以这个基本逻辑是错误的,因为你不想创建一个新的实例

    相反,在内容类的构造函数中,您只需执行以下操作:

    instance = this;
    

    然后getInstance()方法将只返回变量,因为它总是有一个值

    此外,mouseListener应该是内容类的内部类。也就是说,您应该创建侦听器并将其添加到类中。当您这样做时,您甚至不需要静态getInstance()方法,因为您可以直接访问实例变量

    but they only say to try using invalidate() and validate() which had no effect for me.

    你不应该使用那些方法。这些用于AWT。在Swing中,您可以使用:

    revalidate();
    repaint();
    

    在GUI可见后向GUI添加组件时,或在自定义类中更改属性时。revalidate()将调用布局管理器。repaint()将绘制组件。在您的类中,您不会更改任何内容的大小,因此您只需要在setter方法中重新绘制()

    编辑:

    Mind sharing the code you added?

    我添加了一行代码:

        public Content (){
            int yLevel = (((int)Math.random())*(getHeight() / 4));
            int xPos = ((int)Math.random())*getWidth();
            for(int i = 0;!(i == 9); i++)   { 
                 //Create the randomly located targets
                targets[i] = new Target(xPos, yLevel, xPos-15, yLevel-10);
            }
    
            instance = this; // added
        }
    

    一次做一个改变。一旦您通过添加一行代码来验证我的假设是否有效。然后你就可以收拾班上的其他同学了。如果您同时进行多个更改,您不知道是哪一个导致了问题