I am trying to develop a game in which I need to draw a grid. For that I am using the paintComponent(Graphics g)
method which is being called by repaint()
method.
The problem is that the repaint method is inside the infinite While loop and it never calls the paintComponent()
method unless I minimize and maximize the screen. After that it works fine and calls the paintComponent()
perfectly in the while loop.
So in short, I need to trigger it by Minimizing-Maximizing the screen.
Can anybody help me out?
In the code you can see 3 classes namely, Frame.java, MenuHandler.java & Screen.java. Code starts from the main method in Frame class and it adds the Screen class to itself as Screen extends JPanel. However, the control goes to the Screen class only when user selects "Create Map" on the menu. Then MenuHandler class passes the control to the Screen class where the run method is called in the createMap method and I invoking the repaint method inside this run method. package so;
public class Screen extends JPanel implements Runnable {
Frame frame;
public Screen(Frame frame) {
this.frame = frame;
}
public void createMap() {
thread.start();
}
public void paintComponent(Graphics g) {
g.setColor(Color.BLUE);
}
@Override
public void run() {
System.out.println("Success******");
long lastFrame = System.currentTimeMillis();
int frames = 0;
running = true;
scene = 0;
// the map grid would be refreshed every 2 ms so that we don't get the
// flickering effect
while (running) {
frames++;
if (System.currentTimeMillis() - 1000 >= lastFrame) {
fps = frames;
frames = 0;
lastFrame = System.currentTimeMillis();
}
// to draw stuff all the time on the screen : goes around 2 millions
// frames per second. Which is of no use.
repaint();
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.exit(0);
}
}
Timer code in the run method:
public void run() {
System.out.println("Success");
long lastFrame = System.currentTimeMillis();
int frames = 0;
running = true;
scene = 0;
// the map grid would be refreshed every 2 ms so that we don't get the
// flickering effect
while (running) {
frames++;
if (System.currentTimeMillis() - 1000 >= lastFrame) {
fps = frames;
frames = 0;
lastFrame = System.currentTimeMillis();
}
System.out.println("before repaint");
// to draw stuff all the time on the screen : goes around 2 millions
// frames per second. Which is of no use.
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
repaint();
}
};
new Timer(200, taskPerformer).start();
System.out.println("after repaint");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.exit(0);
}
I figured out the issue. it was just one line that I had to add to trigger the paintComponent method instead of doing it by minimizing-maximizing the window.
Frame was my top level container and I was adding Screen component (that extends JPanel and has the implementation of paintComponent) to the frame. So while adding, earlier I was doing
frame.add(screen);
I changed this to:
frame.getContentPane().add(screen);
frame.getContentPane().validate();
Calling the validate method after adding it did it for me. I don't know if it makes sense but yes that was the only line that worked for me.
Hope it helps.