简体   繁体   中英

Swing Timer in main class doesn't repaint JFrame class

I have a main class that holds a Array List of objects and has a Swing timer that repaints a separate JFrame Class. Despite the repaint method being called, the screen isn't being updated.

What's supposed to happen: When any key is pressed, the x location of two objects are updated. A swing timer that ticks every half second calls the repaint method. The images are then redrawn in their updated locations.

From what I can tell the location of the images are being updated, as when I minimize and reopen the JFrame window, the images have moved.

I've tried changing the intervals at which the timer runs, moving the swing timer to the JFrame class, putting the repaint(); in a thread. However I still don't know why repaint(); isn't updating the screen.

Here's a sketch of my code: 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);
    }
}
}

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

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

Object 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
}
}
  • You are creating multiple instances of qwq , in testingGround and Keyboard , these having nothing to do with each other and only mean that you are now creating a new Timer each time you create a new instance of it
  • In your testingGround#createGUI you create a new instance of testingGround , which gets added to a new instance of a JFrame , so the reference that qwq has to testingGround has nothing to do with the instance which is actually on the screen!? Further more, you create a new instance of JFrame in createGUI which has no relationship to the instance of JFrame you return from getFrame !?

OO is all about responsibilities, whose responsible for what. For example, you testingGround class shouldn't be making frames, it's not it's responsibility. It should be responsible for rendering the current state of the game.

For example...

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

Now, it would easy to have the Timer separate, but I was to lazy

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