简体   繁体   English

添加paint方法后我的JPanel不显示

[英]My JPanel doesn't show after adding the paint method

I recently created my first board for my first board game and draw the board multiple ways on my JPanel.I finally decided to use Label, but since I needed to add pictures to that label, I had to change it into JLabel.The syntax is correct, but the Jlabels do not show.我最近为我的第一个棋盘游戏创建了我的第一个棋盘,并在我的 JPanel 上以多种方式绘制棋盘。我最终决定使用 Label,但是由于我需要在 label 中添加图片,因此我不得不将其更改为 JLabel。语法为正确,但 Jlabels 不显示。 I tried cleaning my paint method and It started to show,but the background of the labels doesn't change.我尝试清理我的绘画方法并开始显示,但标签的背景没有改变。

I tried putting the code inside my paint method and It didn't work.我尝试将代码放在我的绘画方法中,但它没有用。 I also tried adding the container to the frame after my draw method and it didn't work either.我还尝试在我的绘制方法之后将容器添加到框架中,但它也不起作用。

Here are some essential parts of my code:以下是我的代码的一些重要部分:

    ////////////////////////////////////
    //The constructor, Creates the frame.
    ////////////////////////////////////
    public SecondFrame() {
        setTitle("Counter Strike");
        setIconImage(Toolkit.getDefaultToolkit().getImage(SecondFrame.class.getResource("/cs/resources/icon2.png")));

        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(150, 10, WIDTH, HEIGHT);
        contentPane = new JPanel();
        //contentPane.setBackground(Color.CYAN);
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
       
        setContentPane(contentPane);
        GroupLayout gl_contentPane = new GroupLayout(contentPane);
        gl_contentPane.setHorizontalGroup(
            gl_contentPane.createParallelGroup(Alignment.LEADING)
                .addGap(0, 984, Short.MAX_VALUE)
        );
        gl_contentPane.setVerticalGroup(
            gl_contentPane.createParallelGroup(Alignment.LEADING)
                .addGap(0, 662, Short.MAX_VALUE)
        );
        contentPane.setLayout(gl_contentPane);
        
    
        
        

        //Starting the game.
        start();
        
        
        
          //Initializing the label "boardParts" 2D array.
            frame();


    }
    
    
    
    
    
    //////////////////
    //Draws the board
    //////////////////
    
    public void frame() {
        
        boardParts=new JLabel[rows][columns];
        
        for(int i=0;i<rows;i++)
            for(int j=0;j<columns;j++) {
                
                boardParts[i][j]=new JLabel();
                boardParts[i][j].setBounds(100*i+100, 100*j+100, tilesize, tilesize);
                boardParts[i][j].setBorder(new LineBorder(new Color(0, 0, 0)));

                if(randomBarrier()) 
                     boardParts[i][j].setIcon(new ImageIcon(FirstFrame.class.getResource("/cs/resources/boundIcon.png")));
                else
                    boardParts[i][j].setBackground(Color.yellow);
                 contentPane.add(boardParts[i][j]);
                 
            }
        
    }
    
  

I also create a new object of this class in another one of my classes and when I run it It shows errors for like 1sec and then wipes them off so I don't know what those errors are for.我还在我的另一个课程中创建了这个 class 的新 object,当我运行它时它显示错误大约 1 秒,然后将它们擦掉,所以我不知道这些错误是为了什么。

So this is my reduced code:所以这是我的简化代码:

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Toolkit;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.GroupLayout;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.GroupLayout.Alignment;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.event.ActionEvent;

public class Frame1 {

    private JFrame frame;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Frame1 window = new Frame1();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public Frame1() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        JButton btnNewButton = new JButton("New button");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                frame.setVisible(false);
                SecondFrame frame2 = new SecondFrame();
                frame2.setVisible(true);
                
            }
        });
        GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
        groupLayout.setHorizontalGroup(
            groupLayout.createParallelGroup(Alignment.LEADING)
                .addGroup(groupLayout.createSequentialGroup()
                    .addGap(42)
                    .addComponent(btnNewButton)
                    .addContainerGap(303, Short.MAX_VALUE))
        );
        groupLayout.setVerticalGroup(
            groupLayout.createParallelGroup(Alignment.LEADING)
                .addGroup(Alignment.TRAILING, groupLayout.createSequentialGroup()
                    .addContainerGap(183, Short.MAX_VALUE)
                    .addComponent(btnNewButton)
                    .addGap(56))
        );
        frame.getContentPane().setLayout(groupLayout);
    }
}


package hello;

import java.awt.Color;
import java.awt.Toolkit;

import javax.swing.GroupLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.GroupLayout.Alignment;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class SecondFrame extends JFrame implements Runnable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private JPanel contentPane;
    private static int WIDTH=1000,HEIGHT=700;
    private static int boardWidth=500,boardHeight=500;  //The width and height of the game board.
    private Thread thread;
    private boolean isRunning;
    private BoardParts barriers;
    private int rows=8,columns=5,tilesize=100;
    private JLabel[][] boardParts;
    private boolean[][] notBarrier;

    
    
    

    ////////////////////
    //Creates the frame.
    ////////////////////
    public SecondFrame() {
        setTitle("Counter Strike");
        setIconImage(Toolkit.getDefaultToolkit().getImage(SecondFrame.class.getResource("/cs/resources/icon2.png")));

        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(150, 10, WIDTH, HEIGHT);
        contentPane = new JPanel();
        contentPane.setBackground(Color.CYAN);
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
       
        setContentPane(contentPane);
        GroupLayout gl_contentPane = new GroupLayout(contentPane);
        gl_contentPane.setHorizontalGroup(
            gl_contentPane.createParallelGroup(Alignment.LEADING)
                .addGap(0, 984, Short.MAX_VALUE)
        );
        gl_contentPane.setVerticalGroup(
            gl_contentPane.createParallelGroup(Alignment.LEADING)
                .addGap(0, 662, Short.MAX_VALUE)
        );
        contentPane.setLayout(gl_contentPane);
        
    
        
        

        //Starting the game.
        start();
        
        
        
        //Initializing the label "boardParts" 2D array.
        frame();
        


    }
    

    
    
    //////////////////
    //Draws the board
    //////////////////
    
    public void frame() {
        
        boardParts=new JLabel[rows][columns];
        notBarrier=new boolean[rows][columns];
        
        for(int i=0;i<rows;i++)
            for(int j=0;j<columns;j++) {
                
                boardParts[i][j]=new JLabel();
                boardParts[i][j].setBounds(100*i+100, 100*j+100, tilesize, tilesize);
                boardParts[i][j].setBorder(new LineBorder(new Color(0, 0, 0)));

                if(randomBarrier()) {
                     boardParts[i][j].setIcon(new ImageIcon(Frame1.class.getResource("/cs/resources/boundIcon.png")));
                     notBarrier[i][j]=false;
                }
                else {
                    boardParts[i][j].setBackground(Color.yellow);
                    notBarrier[i][j]=true;
                }
                 contentPane.add(boardParts[i][j]);
                 
            }
    

    }
    
    


    
    ///////////////////////////////////////////////////////////////////////////
    //finds a random place for the barrier objects in the beginning of the game.
    ///////////////////////////////////////////////////////////////////////////

    public static boolean randomBarrier() {  //Should put all the parts to this method to see if the are barrier material or not.
        
        
        int row = WIDTH/100;
        int column = HEIGHT/100;
        
        int min = 0;
        int max = row*column;
        
        double random = Math.random();
        
        if(random<0.4)
            return true;
        
        else if(random>=0.4)
           return false;
        
        return true;
        
    }


    
    
    
    
    //////////////////
    //Starts the game.
    /////////////////
    public void start() {
        
        isRunning = true;
        thread = new Thread(this);
        thread.start();
        
    }
    
    
    
    
    ////////////////
    //Stops the game.
    ///////////////
    public void stop() {
        
        isRunning = false;
        try {
            thread.join();
        } catch (InterruptedException e) {
            System.out.println("An error occured...");
            e.printStackTrace();
        }
        
    }
    
    
    
    public void tick() {
        
        
    }
    

    
    
    @Override
    public void run() {


        while(isRunning) {
            tick();
            repaint();
        }
        
    }
    
    
}


package hello;

public class BoardParts {

}
  1. When posting code don't use the "Code Snippet".发布代码时不要使用“代码片段”。 Instead you paste your code, select the code and then use the {} button to highlight the code.相反,您粘贴代码 select 代码,然后使用{}按钮突出显示代码。

  2. Post a proper minimal reproducible example when posting code.发布代码时发布适当的最小可重现示例 This is minimal code that directly demonstrates the stated problem.这是直接演示所述问题的最小代码。 The code should be in a single file and we should be able to copy/paste/compile and test the code.代码应该在一个文件中,我们应该能够复制/粘贴/编译和测试代码。 The point of this is to force you to eliminate all unnecessary code so it is easy to understand the problem.这样做的目的是迫使您消除所有不必要的代码,以便于理解问题。 Most time you will find your own problem.大多数时候你会发现自己的问题。 You have been asked for an MRE is previous questions.您已被要求提供 MRE 是以前的问题。 Every question should have an MRE so we don't have to guess what you are doing.每个问题都应该有一个 MRE,这样我们就不必猜测你在做什么。

  3. It looks to me like you have a 2D grid.在我看来,您有一个 2D 网格。 Don't use the GroupLayout.不要使用 GroupLayout。 This tells me you are using the IDE to generate your code.这告诉我您正在使用 IDE 来生成您的代码。 You are spending time learning the IDE and not learning Swing.您正在花时间学习 IDE 而不是学习 Swing。 You can easily use a GridLayout for a 2D grid.您可以轻松地将GridLayout用于 2D 网格。

  4. Don't use static variables.不要使用 static 变量。 Your width, height, boardWidth and boardHeight variables are not needed.不需要您的 width、height、boardWidth 和 boardHeight 变量。 Each Swing component should be responsible for determining its own preferred size.每个 Swing 组件应负责确定自己的首选大小。 Then after all components are added to the frame, you pack() the frame before making it visible.然后在将所有组件添加到框架之后,在使其可见之前打包()框架。 The frame will then determines its appropriate size.然后框架将确定其适当的大小。 In this case you can use setPreferredSize(...) for each of the JLabels to make them the size of your tile.在这种情况下,您可以对每个 JLabel 使用 setPreferredSize(...) 以使它们成为您的 tile 的大小。 So outside the loop you create an single instance of a Dimension object to be shared by all labels.因此,在循环之外,您创建一个Dimension object 的单个实例以供所有标签共享。

  5. Don't use magic numbers in the setBounds() method.不要在 setBounds() 方法中使用幻数。 In you last question you were given the solution without using magic numbers.在您的最后一个问题中,您在不使用幻数的情况下获得了解决方案。 In fact you should not even be using the setBounds() method.事实上,您甚至不应该使用 setBounds() 方法。 It is the job of the layout manager to set the size/location of the component.布局管理器的工作是设置组件的大小/位置。

  6. Don't use a Thread for animation.不要为 animation 使用线程。 Animation should be done using a Swing Timer . Animation 应该使用Swing Timer来完成。 All updates to Swing components should be done on the Event Dispatch Thread (EDT).对 Swing 组件的所有更新都应在事件调度线程 (EDT) 上完成。 The Swing Timer will execute on the EDT. Swing 定时器将在 EDT 上执行。

  7. Don't create multiple instance of your Icon .不要创建Icon的多个实例。 An Icon can be shared by multiple components.一个图标可以被多个组件共享。 So you create a single instance of the Icon outside the looping code and use that instance for all components.因此,您在循环代码之外创建 Icon 的单个实例,并将该实例用于所有组件。

  8. Same with the LineBorder .LineBorder相同。 You only need a single instance.您只需要一个实例。

  9. In the comments from your last question you were given a suggestion on how to write your randomBarrier() method using a single statement.在您上一个问题的评论中,您获得了有关如何使用单个语句编写randomBarrier()方法的建议。 The code you post here is completely unnecessary.您在此处发布的代码完全没有必要。 The variable from the first 4 statement are not even used.甚至没有使用前 4 条语句中的变量。

but the Jlabels do not show.但 Jlabels 没有显示。

As I suggested earlier you can use a GridLayout on your panel and add the labels to the panel and the panel to the frame.正如我之前建议的那样,您可以在面板上使用GridLayout并将标签添加到面板并将面板添加到框架。 Read the Swing tutorial on Layout Manager for more information and working examples.阅读有关布局管理器的 Swing 教程,了解更多信息和工作示例。

I tried cleaning my paint method我尝试清洁我的油漆方法

There is no reason to use a custom paint method.没有理由使用自定义绘制方法。 You are using Swing components (JLabel) now and Swing will do all the painting for you.您现在正在使用 Swing 组件 (JLabel),Swing 将为您完成所有的绘画工作。 Also, as mentioned in your last question, it you ever do need to do custom painting you override the paintComponent() method.此外,正如您在上一个问题中提到的,您确实需要进行自定义绘画,您会覆盖paintComponent()方法。 We should not have to keep repeating the same advice.我们不应该一直重复同样的建议。

the background of the labels doesn't change.标签的背景不会改变。

A JLabel is the only Swing component that is not opaque by default. JLabel是唯一默认不透明的 Swing 组件。 So you need to use:所以你需要使用:

label.setOpaque( true );

when you create each JLabel.当您创建每个 JLabel 时。

I think, you have to override paintComponent(Graphics g) for your board.我认为,您必须为您的电路板覆盖paintComponent(Graphics g)。 You have to save everything you want to draw in a Collection and draw them in paintComponent override.您必须将要绘制的所有内容保存在 Collection 中,并在 paintComponent 覆盖中绘制它们。

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

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