Colin Jang
Colin Jang

Reputation: 5

JLabel in JFrame setText() issue

I'm a novice coder, and while I was working on a project containing JFrame, JPanel and JLabel, I ran into some weird problem of JLabel showing up in two places, where I set it to be at and the top-left corner of the frame rather than where it's supposed to be.

Here's the basic outline of the code:

import java.awt.event.*;     // for key listener
import java.awt.*;         

import javax.swing.JFrame; 
import javax.swing.JLabel;
import javax.swing.BoxLayout;
import javax.swing.*;

import java.util.Random;

public class Game extends JFrame {



   JFrame Game;
   JLabel label;
   GamePanel panel;   // GamePanel class is the panel class that extends JPanel

   public Game(String title) {

      super(title);
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      this.setSize(420 + 110,420 + 220);
      this.setLocationRelativeTo(null); 
      this.setLayout(new BoxLayout(this.getContentPane(), BoxLayout.Y_AXIS));
      this.setResizable(false);

      label = new JLabel("Score : " + score);
      label.setAlignmentX(JLabel.CENTER_ALIGNMENT);
      label.setAlignmentY(JLabel.CENTER_ALIGNMENT);

      panel = new GamePanel(..appropriate variables);

      this.add(panel);
      this.add(label);
      this.add(Box.createRigidArea(new Dimension(0,50)));

      panel.setFocusable(true);
      panel.addKeyListener(new KeyHandler());

   }

   // some variables..


   class KeyHandler extends KeyAdapter {

      public void keyPressed(KeyEvent e)
      {
         int keycode = e.getKeyCode(); 

         switch(keycode) {

             //cases for arrow keys, which will update the variable that panel uses

         }

         //some other tasks for the game..

         panel.updateVariables(...appropriate variables to update);
         panel.repaint();
         label.setText("Score : " + score);

      }

   }

   public static void main(String [] args)  {

      Game me = new Game("GAME");        

      me.setVisible(true);


   }

}   

So the summary of the problem is that whenever setText ACTUALLY UPDATES the label, the label seems to show up in two places: top left corner of the JFrame and where I assigned it to show up. Interestingly the "buggy" label on the top left corner also updates when the real one is updated.

Thanks in advance!

Edit: Here's the layout of GamePanel.

import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.BasicStroke;

public class GamePanel extends JPanel
{      

   // some variables..

   // setXxx methods for corresponding variables

   void drawCursor(int x, int y)
   {
      //draws thicker rectangle around the selected position
      //uses setStroke, setColor, and draw(Rectangle)
   }

   public void paintComponent( Graphics g )   
   {
      Graphics2D g2 = (Graphics2D) g;         

      for(int i = 0; i < size; i++) {

         for(int j = 0; j < size; j++) {

            switch(gameGrid[j][i]) {   // I have an array grid[][] that has information of which color goes into the specific position of the grid

               // each case will setColor the corresponding color and use g2.fill(new Rectangle(...));
               case 0:
                  g2.setColor(...);
                  g2.fill(new Rectangle(...));
                  break;
               // and so on

            }
            g2.setColor(Color.BLACK);
            g2.draw(new Rectangle(50 + (j * 420/size), 50 + (i * 420/size), 420/size,420/size));         
         }    
      }
      drawCursor(x, y);
   }
}

Upvotes: 0

Views: 1568

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347214

As I said in my comments, you are overriding paintComponent (in GamePanel) but are not call super.paintComponent...

public void paintComponent( Graphics g )   
{
    Graphics2D g2 = (Graphics2D) g;   
    for(int i = 0; i < size; i++) { 

Graphics is a shared resource and is used to paint the contents of all the components been updated during a given paint cycle, this means, that when you receive a reference to the Graphics context, it will still have the "stuff" that was painted on it before you. One of the jobs of paintComponent is to clear the context ready for painting

Call super.paintComponent(g); before you do any custom painting

public void paintComponent( Graphics g )   
{
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;   
    for(int i = 0; i < size; i++) { 

Check out Painting in AWT and Swing and Performing Custom Painting for details about how painting in Swing works

Upvotes: 1

Related Questions