简体   繁体   English

JLabel中的JFrame setText()问题

[英]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. 我是一个新手程序员,在从事包含JFrame,JPanel和JLabel的项目时,我遇到了两个奇怪的问题,即JLabel出现在两个地方,我将其设置在的左上角框架,而不是它应该在的位置。

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. 因此,问题的摘要是,每当setText实际更新标签时,标签似乎就会显示在两个位置:JFrame的左上角和我分配它显示的位置。 Interestingly the "buggy" label on the top left corner also updates when the real one is updated. 有趣的是,当实际的标签更新时,左上角的“ buggy”标签也会更新。

Thanks in advance! 提前致谢!

Edit: Here's the layout of GamePanel. 编辑:这是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);
   }
}

As I said in my comments, you are overriding paintComponent (in GamePanel ) but are not call super.paintComponent ... 正如我在评论中所说,您正在覆盖paintComponent (在GamePanel ),但未调用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. Graphics是共享资源,用于绘制在给定绘制周期中已更新的所有组件的内容,这意味着,当您收到对Graphics上下文的引用时,它仍将具有绘制的“材料”在你面前。 One of the jobs of paintComponent is to clear the context ready for painting paintComponent的工作之一是清除准备绘画的上下文

Call super.paintComponent(g); 调用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 查看AWT和Swing中的 绘画以及执行自定义绘画以获取有关Swing中绘画工作原理的详细信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM