main class 中的 Swing Timer 不重绘 JFrame class

Swing Timer in main class doesn't repaint JFrame class

我有一个 main class,它包含一个对象数组列表,还有一个 Swing 计时器,它重新绘制一个单独的 JFrame Class。尽管调用了重绘方法,但屏幕并未更新。

应该发生什么: 当按下任意键时,两个对象的 x 位置都会更新。每半秒计时一次的摇摆计时器调用重绘方法。然后在更新后的位置重新绘制图像。

据我所知,图像的位置正在更新,当我最小化并重新打开 JFrame window 时,图像已移动。

我试过更改计时器运行的间隔,将摆动计时器移至 JFrame class,将 repaint();在一个线程中。但是我仍然不知道为什么 repaint();没有更新屏幕。

这是我的代码草图: JFrame class

public class testingGround extends JPanel {
    private Image image;
    private qwq getter = new qwq();
    protected Keyboard keyboard = new Keyboard(); //KeyListener, imported from Keyboard class
    private JFrame frame = new JFrame(); //JFrame variable

public void createGUI(){
    testingGround panel = new testingGround(); // Creating a new JPanel, for objects to be drawn on
    JFrame frame = new JFrame("Game"); //Creating a new JFrame called frame 
    frame.setSize(600, 600); //Setting the size of the JFrame frame to be 600x600
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// Setting so the frame exits on close
    frame.setVisible(true);
    frame.add(panel);// Adding the JPanel panel to the JFrame frame, so it's visible 
    frame.addKeyListener(keyboard); //Adding a KeyListener to detect users input in the JFrame frame
}   
public Frame getFrame() { //Constructor class to get JFrame in other classes
    return frame;
}

public void initComponents(){
    ImageIcon imageIcon = new ImageIcon("C:/Users/destr/workspace/GameWIP3/bin/A2.png");
    image =imageIcon.getImage();
}

protected void paintComponent (Graphics g){//Drawing
    super.paintComponent(g);
    initComponents();
    for (int i=0;i<getter.getFListSize();i++)
    {
    System.out.print("paint called");   
    g.drawImage(image, getter.getFighter(i).getFighterX(), getter.getFighter(i).getFighterY(), null);
    }
}
}

键盘Class

public class Keyboard implements KeyListener {

private qwq getter = new qwq();

@Override
public void keyPressed(KeyEvent e) {
    getter.getFighter(0).setFighterX(500);;
    getter.getFighter(1).setFighterX(200);; 
    System.out.print("Updated the x value of two");
}

主要Class

public class qwq implements ActionListener {
private static ArrayList<Fighter> FighterList = new ArrayList<Fighter>(); // ArrayList                                                                          // of                                                               // Fighters
Timer timer = new Timer(500, this);
private static testingGround GUI = new testingGround();

public qwq() {
    timer.start();
}

public Fighter getFighter(int i) {
    return FighterList.get(i); // To retrieve a fighter from the Array List
}

public void addFighter(Fighter i) {
    FighterList.add(i); // To add a fighter to the Array list
}

public int getFListSize() {
    return FighterList.size();
}

public static void main(String[] args) {
    GUI.createGUI();
    GUI.getFrame();
    FighterList.add(new Fighter(0, 0));
    FighterList.add(new Fighter(20, 50));
}

@Override
public void actionPerformed(ActionEvent e) {
    if (e.getSource() == timer) {
        GUI.repaint();
    }
}
}

对象Class

public class Fighter { 

    private int fighterX;
    private int fighterY;

public Fighter ( int fighterX, int fighterY) {
this.setFighterX(fighterX);
this.setFighterY (fighterY);
}

public int getFighterX (){
return fighterX; //method to get x coordinate of a fighter
}

public int getFighterY (){
return fighterY;//method to get y coordinate of a fighter
}

public void setFighterX(int fighterX) {
this.fighterX = fighterX; //method to set the x coordinate of a fighter
}

public void setFighterY(int fighterY) {
this.fighterY = fighterY; //method to set the y coordinate of a fighter
}
}
  • 您在 testingGroundKeyboard 中创建了 qwq 的多个实例,它们彼此无关,只意味着您现在正在创建一个新的 Timer 每次创建它的新实例时
  • 在您的 testingGround#createGUI 中,您创建了一个 testingGround 的新实例,它被添加到 JFrame 的一个新实例中,因此 qwq 的引用必须testingGround 与实际出现在屏幕上的实例无关!?此外,您在 createGUI 中创建了一个 JFrame 的新实例,它与 JFrame 您 return 来自 getFrame!?[=35 的实例没有关系=]

面向对象就是责任,谁负责什么。比如你testingGround class 不应该做框架,这不是它的责任。它应该负责渲染游戏的当前状态。

例如...

import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Qwq {

    public static void main(String[] args) {
        new Qwq();
    }

    public Qwq() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestingGround());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class Keyboard extends KeyAdapter {

        private List<Fighter> fighterList;

        public Keyboard(List<Fighter> fighterList) {
            this.fighterList = fighterList;
        }

        @Override
        public void keyPressed(KeyEvent e) {
            fighterList.get(0).setFighterX(500);
            fighterList.get(1).setFighterX(200);
            System.out.print("Updated the x value of two");
        }
    }

    public class TestingGround extends JPanel {

        private ArrayList<Fighter> fighterList = new ArrayList<>(); 

        private Image image;
        private Keyboard keyboard;

        public TestingGround() {
            loadImages();
            addKeyListener(new Keyboard(Collections.unmodifiableList(fighterList)));
            Timer timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    repaint();
                }
            });
            timer.start();
        }

        public void loadImages() {
            ImageIcon imageIcon = new ImageIcon("C:/Users/destr/workspace/GameWIP3/bin/A2.png");
            image = imageIcon.getImage();
        }

        protected void paintComponent(Graphics g) {//Drawing
            super.paintComponent(g);
            for (Fighter fighter : fighterList) {
                System.out.print("testing");
                g.drawImage(image, fighter.getFighterX(), fighter.getFighterY(), null);
            }
        }
    }

    public static class Fighter {

        private int fighterX;
        private int fighterY;

        public Fighter(int fighterX, int fighterY) {
            this.setFighterX(fighterX);
            this.setFighterY(fighterY);
        }

        public int getFighterX() {
            return fighterX; //method to get x coordinate of a fighter
        }

        public int getFighterY() {
            return fighterY;//method to get y coordinate of a fighter
        }

        public void setFighterX(int fighterX) {
            this.fighterX = fighterX; //method to set the x coordinate of a fighter
        }

        public void setFighterY(int fighterY) {
            this.fighterY = fighterY; //method to set the y coordinate of a fighter
        }
    }
}

现在,将 Timer 分开很容易,但我太懒了