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. 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.
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 { }
Advertisement
Answer
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.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. Every question should have an MRE so we don’t have to guess what you are doing.
It looks to me like you have a 2D grid. Don’t use the GroupLayout. This tells me you are using the IDE to generate your code. You are spending time learning the IDE and not learning Swing. You can easily use a
GridLayout
for a 2D grid.Don’t use static variables. Your width, height, boardWidth and boardHeight variables are not needed. Each Swing component should be responsible for determining its own preferred size. 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. So outside the loop you create an single instance of a
Dimension
object to be shared by all labels.Don’t use magic numbers in the setBounds() method. In you last question you were given the solution without using magic numbers. In fact you should not even be using the setBounds() method. It is the job of the layout manager to set the size/location of the component.
Don’t use a Thread for animation. Animation should be done using a
Swing Timer
. All updates to Swing components should be done on the Event Dispatch Thread (EDT). The Swing Timer will execute on the EDT.Don’t create multiple instance of your
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.Same with the
LineBorder
. You only need a single instance.In the comments from your last question you were given a suggestion on how to write your
randomBarrier()
method using a single statement. The code you post here is completely unnecessary. The variable from the first 4 statement are not even used.
but the Jlabels do not show.
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. Read the Swing tutorial on Layout Manager for more information and working examples.
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. Also, as mentioned in your last question, it you ever do need to do custom painting you override the paintComponent()
method. 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. So you need to use:
label.setOpaque( true );
when you create each JLabel.