Im trying to add a Score and Elapsed Time label (scoreAndTimer) to my already working snake game code. The problem is when I use scoreAndTimer.setText(); it stacks with previous text.
I tried to setText(); then setText(String); to clear previous one but it doesnt work also.
private JLabel scoreAndTimer;
private int sec, min;
private Game game;
public Frame() {
JFrame frame = new JFrame();
game = new Game();
frame.add(game);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Snake");
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
scoreAndTimer = new JLabel();
scoreAndTimer.setVerticalAlignment(SwingConstants.TOP);
scoreAndTimer.setHorizontalAlignment(SwingConstants.CENTER);
frame.add(scoreAndTimer);
timer();
}
private void timer(){
while(game.isRunning()){
scoreAndTimer.setText("SCORE: "+(game.getSnakeSize()-3)+" Elapsed Time: "+timeFormatter());
try{
if(sec == 60){
sec = 0;
min++;
}
sec++;
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
if(!game.isRunning())
scoreAndTimer.setText("Game Over");
}
private String timeFormatter(){
if(sec < 10 && min < 10)
return "0"+min+":0"+sec;
else if(sec >= 10 && min < 10)
return "0"+min+":"+sec;
else if(sec < 10 && min >= 10)
return min+"0:"+sec;
else
return min+":"+sec;
}
public static void main(String[] args) {
new Frame();
}
}
Program is working well but could'nt prevent overlap. There is no error. Im using totally 3 Threads in my program, im not sure if threads are making a problem about this. Code is a bit long thats why i dont share the rest for now, if needed i can share other parts also but i dont think the problem occurs at other classes.
JFrame
, or more precisely it contentpane
uses BorderLayout
by default.
When you add components to a JFrame
:
frame.add(game);
You implicitly add it to the BorderLayout.CENTER
position, which is the default position. So frame.add(game);
is equivalent to frame.add(game, BorderLayout.CENTER);
The BorderLayout.CENTER
position (as well as other BorderLayout
positions) can hold one component.
The problem is that you add another component to the same BorderLayout.CENTER
position by:
frame.add(scoreAndTimer);
The solution is to add scoreAndTimer
to a different position:
frame.add(scoreAndTimer, BorderLayout.PAGE_END);
and have
frame.pack();
frame.setVisible(true);
at the end, after you have added all components.
Important side note:
timer()
as written is not going to work. Think of Swing Application as an application that runs on a single thread. When this thread is
busy with running the long while loop (like the one you have in timer()
, it does not update the gui. The gui becomes unresponsive(freezes).
Use Swing timer.