【问题标题】:If I use paintComponent, how do I show a JLabel?如果我使用paintComponent,我如何显示一个JLabel?
【发布时间】:2021-04-27 02:01:25
【问题描述】:

我对 Java 比较陌生,我正在制作一个游戏,你可以上下冲刺以避开障碍物。我几乎完成了所有主要功能,还必须完成评分系统和背景。认为分数会更容易,我写了一个 JLabel 并将其添加到我的 JFrame 中。它一闪而逝。我相当肯定这是因为我直接在之后添加了整个图形方法,或者类似的东西。但是,如果我在之后添加 JLabel,这就是添加的全部内容,并且会占据整个屏幕。

package dash;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Main extends JPanel implements ActionListener {//ignore yellow line
//setting up class
    Variables var = new Variables();
    Timer timer = new Timer(5,this);
    boolean spacePressed;
    boolean gameActive = false;
    boolean creatingObstacles = true;
    int arrayLength;
    int creationStep = 50;
    int backgroundx;
    int speed = 30;
    int x;
    int y;
    int playery = 700;
    int highscore;
    int score = 1;
    static int[] obstacles = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
//making label
    JLabel label = new JLabel("score: " + score);
//setting up graphics method
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
//player
        ImageIcon player = new ImageIcon("C:\\Users\\myname\\Documents\\Eclipse Projects\\dash\\player.png");
        player.paintIcon(this,g,300,playery);
//label properties
        label.setBounds(300,900,100,100);
//Some really cool code that took a while to write, this is going to generate random obstacles so I don't
//have to make all the levels since I'm lazy. This also makes graphics easier, since now I don't have
//to draw out the map taking up a lot of memory, at least several gigs probably more, for small levels. 
        int min = 500;
        int max = 1500;
        arrayLength = obstacles.length - 1;
//creating random array, im really proud of this
//code. it took me hours to write and looks badass
//except i have no clue how to label anything now T-T
        while (creationStep > 0) {
            if (creatingObstacles == true) {
                obstacles[arrayLength] = (int)Math.floor(Math.random()*(max-min+1)+min) + var.previousNumber;
                var.previousNumber = obstacles[arrayLength];
                arrayLength--;
                creationStep--;
                if (arrayLength == -1) {
                    creatingObstacles = false;
                    arrayLength = obstacles.length - 1;
                }}}
//drawing with the array
//ps i have no clue why this works, but it does
        boolean onTop = true;
        
        while (arrayLength >= 0) {
//drawing obstacles
            ImageIcon obstacle = new ImageIcon("C:\\Users\\myname\\Documents\\Eclipse Projects\\dash\\obstacle.png");
            obstacle.paintIcon(this,g,obstacles[arrayLength] + backgroundx,y);
//checking collision
            if (obstacles[arrayLength] + backgroundx >= 300 && obstacles[arrayLength] + backgroundx <= 400 && y == playery) {
                spacePressed = false;
                gameActive = false;
                backgroundx = 0;
            }
//finishing loop
            arrayLength--;
//deciding if it puts the obstacle on top or bottom
            if (onTop) {
                y = 200;
            } else {
                y = 700;
            }
//toggling onTop boolean
            onTop = !onTop;
        }
//when to make a new array
        if (obstacles[0] <= -backgroundx) {
            var.previousNumber = -backgroundx + 2000;
            creationStep = 50;
            creatingObstacles = true;
            speed = speed + 5;
        }
//pause
        if (gameActive == false) {
            ImageIcon pauseScreen = new ImageIcon("C:\\Users\\myname\\Documents\\Eclipse Projects\\dash\\pausescreen.png");
            pauseScreen.paintIcon(this,g,0,0);
        }
//timer, this starts physics
        timer.start();
    }
//setting up keys
    KeyListener key = new KeyListener() {
        @Override
        public void keyTyped(KeyEvent e) {
            if(e.getKeyChar() == KeyEvent.VK_ESCAPE) {
                gameActive = !gameActive;
            }
        }
        @Override
        public void keyPressed(KeyEvent e) {
            if(e.getKeyChar() == KeyEvent.VK_SPACE && gameActive == true) {
                spacePressed = !spacePressed;
            }
        }
        @Override
        public void keyReleased(KeyEvent e) {
        }
    };
//physics go here
    public void actionPerformed(ActionEvent e) {
        if (spacePressed == true) {
            playery = 200;
        } else {
            playery = 700;
        }
//movement
        if (gameActive == true) {
            backgroundx = backgroundx - speed;
        }
        repaint();
        }   
//main method
    public static void main(String[] args) {
//implementing method
        Main main = new Main();
//creating frame
        JFrame frame = new JFrame();
        frame.setFocusable(true);
        frame.setSize(1920,1080);
        frame.setVisible(true);
        frame.addKeyListener(main.key);
        frame.add(main.label);
        frame.add(main);
    }
}
class Variables{
    int previousNumber;
}

【问题讨论】:

    标签: java swing jlabel paintcomponent


    【解决方案1】:
        frame.add(main.label);
        frame.add(main);
    

    框架的默认布局管理器是 BorderLayout。

    不能将两个组件添加到BorderLayout的“CENTER”,如果不指定约束,这是默认的。

    试试下面的方法看看有什么不同:

        frame.add(main.label, BorderLayout.PAGE_START);
        frame.add(main, BorderLayout.CENTER);
    

    阅读 Layout Manager 上的 Swing 教程部分,了解有关 BorderLayout 和其他布局管理器如何工作的更多信息。

    【讨论】:

    • 仍然没有显示任何内容,我什至尝试将 JLabel 移动到 main 方法中,然后图形没有显示,只有标签。我把它改成你写的,没有添加任何其他内容。
    • 您阅读教程了吗?从教程中的工作演示开始。它将向您展示如何更好地构建您的代码。因此,首先尝试显示仅绘制矩形的标签和面板。不应在paintComponent 方法中修改标签。然后,一旦成功,您就可以添加游戏逻辑。在开始测试之前,您不应该编写整个应用程序。本教程还有一个关于“自定义绘画”的部分。从基础开始。
    • 是的,我让它工作了。必须颠倒我添加两件事的顺序,并且按照您的建议,我将标签从paintcomponent方法中移出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多