public class MinesweeperMenu extends MinesweeperPanel{
private JPanel picture = new JPanel();
private JButton play = new JButton("Play");
private JButton highScores = new JButton("High Score and \nStatistics");
private JButton changeMap = new JButton("Create Custom \nor Change Map");
private JButton difficulty = new JButton("Custom or\nChange Difficulty");
private JButton user = new JButton("Change User");
Image img;
public MinesweeperMenu()
{
// Set Layout for the menu
LayoutManager menuLayout = new BoxLayout(menu, BoxLayout.Y_AXIS);
menu.setLayout(menuLayout);
// Set Layout for the window
LayoutManager windowLayout = new BorderLayout();
window.setLayout(windowLayout);
// Add buttons to the panels
menu.add(play);
menu.add(highScores);
menu.add(changeMap);
menu.add(difficulty);
menu.add(user);
// Add picture to the frame
try{
File input = new File("./setup/images/MineMenuPicture.jpg");
img = ImageIO.read(input);
}
catch(IOException ie)
{
System.out.println(ie.getMessage());
}
// Add action listeners
changeMap.addActionListener(new ChangeMapListener());
}
public void paintComponent(Graphics g)
{
// POSITION OF THE PICTURE
int x = 650;
int y = 585;
g.drawImage(img, x, y, null);
}
public void displayFrame()
{
// Display Frame
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
}
public static void main(String[] args)
{
MinesweeperMenu menu = new MinesweeperMenu();
window.pack();
menu.displayFrame();
window.repaint();
}
}
public class MinesweeperPanel extends JFrame{
public static final Color COLOR_KEY = new Color(220, 110, 0);
// Initialize all the objects
public static JFrame window = new JFrame("Minesweeper++");
public static JPanel menu = new JPanel();
// Close the current window
public static void close()
{
window.setVisible(false);
window.dispose();
}
}
I can't get my image to display in the frame. I've tried everything, but I'm getting the impression it's a mistake that I'm not realizing since I am new to Java Swing. Any help would be greatly appreciated.
You're making things difficult for yourself by having a very confusing program structure, and I suggest that you simplify things a lot.
For one, there's no need for your current MinesweeperMenu class to extend MinesweeperPanel, and for the latter class to extend JFrame. Then you have a static JFrame somewhere else -- that's too many JFrames, and to boot, you're trying to display your image in one JFrame but showing the other one that doesn't have the picture. Your program needs just one JFrame and it should probably be created, stuffed with its contents, packed and displayed in one place, not scattered here and there as you're doing.
You're trying to display the picture in a paintComponent override, but this method will never get called since your class extends JFrame (eventually) and JFrame doesn't have this method. You're using the right method, but the class should be extending JPanel, and you should have an #Override annotation above the paintComponent method block to be sure that you're actually overriding a parent method.
You should get rid of all static everything in this program. The only thing static here should be the main method and perhaps some constants, but that's it.
There are more errors here, and I have too little time to go over all of them. Consider starting from the beginning, starting small, getting small bits to work, and then adding them together.
For instance, first create a very small program that tries to read in an image into an Image object, place it in a ImageIcon, place the ImageIcon into a JLabel, and display the JLabel in a JOptionPane, that simple, just to see if you can read in images OK, for example, something like this:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
public class TestImages {
// *** your image path will be different *****
private static final String IMG_PATH = "src/images/image01.jpg";
public static void main(String[] args) {
try {
BufferedImage img = ImageIO.read(new File(IMG_PATH));
ImageIcon icon = new ImageIcon(img);
JLabel label = new JLabel(icon);
JOptionPane.showMessageDialog(null, label);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Then when you've done this, see if you can now create a JPanel that shows the same Image in its paintComponent method, and display this JPanel in a JOptionPane.
Then create a JFrame and display the image-holding JPanel in the JFrame.
Through successive iterations you'll be testing concepts, correcting mistakes and building your program.
File input = new File("./setup/images/MineMenuPicture.jpg");
If MineMenuPicture.jpg is an application resource, it should be in a Jar and accessed by URL obtained from Class.getResource(String).
Related
I want to put my background image at the very bottom in this frame, and the button on top. However the code I wrote below doesn't work. Can anyone see where the problems are?
Another thing is that even though I set the location for my button, it keep showing at the top center on the frame.
Please ignore the comment lines. (I was just guessing, and hoping them will work, but they don't apparently.)
public class Menu extends JFrame{
private JLayeredPane pane;
private JLayeredPane pane2;
public Menu(){
final JFrame f = new JFrame("Chinese Chess");
JButton play = new JButton("Play vs. AI");
f.setLayout(new FlowLayout());
f.setLocationRelativeTo(null);
f.setSize(800, 800);
f.setVisible(true);
f.setResizable(false);
//f.pack();
pane = new JLayeredPane();
pane2 = new JLayeredPane();
f.add(pane);
f.add(pane2);
//background image
JLabel background = new JLabel(new ImageIcon("res/img/background.png"));
background.setLocation(0, 0);
background.setSize(800, 800);
pane.add(background, JLayeredPane.FRAME_CONTENT_LAYER);
pane2.add(play, JLayeredPane.DEFAULT_LAYER);
//pane.moveToBack();
//button PlayAI
play.setLocation(500,500);
play.setPreferredSize(new Dimension(100,50));
//f.setLayout(new FlowLayout());
//frame menu
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//f.getContentPane().add(play);
play.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
new PlayAI();
}
});
}
public static void main(String[] args){
new Menu();
}
Problems/Solutions:
setLocation(...) and setBounds(...) types of calls are ignored by most layout managers. The only way to use them is to set the layout of the container to null via .setLayout(null);
But having said that, while null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
So in sum -- don't do this, don't use null layouts or setBounds, but rather nest JPanels, each using its own layout manager, and thereby create easy to maintain and decent GUI's.
If you want an image to be in the background, then draw it in a JPanel that you use as a container for your GUI components by drawing it in the JPanel's paintComponent(Graphics g) method as has been demonstrated in many many similar questions on this site -- I'll find you some of mine in a second.
If you add any JPanels on top of this image drawing JPanel, be sure that you can see through them by calling setOpaque(false) on these overlying JPanels. Otherwise you'll cover up the image.
Your code has two JFrames when only one is needed. Get rid of the one you don't use.
You call setVisible(true) too early on the JFrame, before components have been added to the GUI -- don't. Call it only after adding everything to the GUI so all display OK.
You're creating two JLayedPanes, and completely covering one by the other by adding them to the JFrame without understanding how the JFrame's BorderLayout handles added components.
I suggest that you not even use one JLayeredPane but instead draw in the JPanel as noted above, and use that as your container.
Your code looks to be opening a completely new GUI window when the play button is pressed, and if so, this can get annoying to the user fast. Consider swapping views instead with a CardLayout.
For example:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
// extend JPanel so you can draw to its background
#SuppressWarnings("serial")
public class Menu2 extends JPanel {
private BufferedImage bgImage = null; // our background image
private JButton playButton = new JButton(new PlayVsAiAction("Play Vs. AI", KeyEvent.VK_P));
public Menu2(BufferedImage bgImage) {
this.bgImage = bgImage;
setLayout(new GridBagLayout()); // center our button
add(playButton);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (bgImage != null) {
g.drawImage(bgImage, 0, 0, this);
}
}
// to size our GUI to match a constant or the image.
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
// if you want to size it based on the image
if (bgImage != null) {
int width = bgImage.getWidth();
int height = bgImage.getHeight();
return new Dimension(width, height);
} else {
return super.getPreferredSize();
}
// if you want to size the GUI with constants:
// return new Dimension(PREF_W, PREF_H);
}
private class PlayVsAiAction extends AbstractAction {
public PlayVsAiAction(String name, int mnemonic) {
super(name); // have our button display this name
putValue(MNEMONIC_KEY, mnemonic); // alt-key to press button
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO code to start program
}
}
private static void createAndShowGui() {
BufferedImage img = null;
String imagePath = "res/img/background.png";
try {
// TODO: fix this -- use class resources to get image, not File
img = ImageIO.read(new File(imagePath));
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
Menu2 mainPanel = new Menu2(img);
JFrame frame = new JFrame("Chinese Chess");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
Apart from the solution above... you should create and launch your swing application this way:
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
// Instantiate your JFrame and show it
}
I am new to Java. I am trying to make text appear on a JLabel after a virtual button is clicked. However, I can't seem to find a solution to this. When I use the if statement it won't work. How can I make the text appear after the button was pressed?
import java.awt.event.*;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JPanel;
import java.awt.Graphics;
public class autos extends JLabel implements ActionListener
{
private static final long serialVersionUID = 1L;
int now=0;
public autos(){
JLabel l=new JLabel("");
JFrame f=new JFrame("the title");
JPanel p=new JPanel();
JButton b=new JButton("click");
f.setBounds(400,500,400,500);
f.setVisible(true);
p.add(b);
f.add(p);
b.addActionListener(this);
p.setVisible(true);
p.add(l);
f.add(l);
if(now==1)
{
l.setText("hello");
l.setOpaque(true);
}
p.setBounds(200,200,200,200);
l.setBounds(100,100,100,100);
l.setOpaque(true);
f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawRect(200,300,89,90);
g.drawString("buv",80,80);
repaint();
}
public static void main(String[] args)
{
new autos();
}
#Override
public void actionPerformed(ActionEvent e) {
now=1;
System.out.println("worked");
System.out.println(now);
}
}
You are setting up your label in your constructor code, which executes before the event handler which sets the now variable to 1.
What you can do is to move this code:
l.setText("hello");
l.setOpaque(true);
To here:
#Override
public void actionPerformed(ActionEvent e) {
now=1;
System.out.println("worked");
System.out.println(now);
l.setText("hello");
l.setOpaque(true);
}
This is a minimally working example of updating the text on button click. See the comments in code for the variety of changes.
import java.awt.event.*;
import javax.swing.*;
/* There is no need to extend label here. */
// public class autos extends JLabel implements ActionListener
public class autos implements ActionListener {
private static final long serialVersionUID = 1L;
int now = 0;
// this is now a class attribute, accessible to any method of this class.
JLabel l;
public autos() {
// this no longer declares a local variable, but instead
// creates an instance of the class attribute.
l = new JLabel("");
JFrame f = new JFrame("the title");
JPanel p = new JPanel();
JButton b = new JButton("click");
f.setBounds(400, 500, 400, 500); // this needs fixing!
f.setVisible(true);
p.add(b);
f.add(p);
b.addActionListener(this);
p.setVisible(true);
p.add(l);
f.add(l);
p.setBounds(200, 200, 200, 200); // this needs fixing!
l.setBounds(100, 100, 100, 100); // this needs fixing!
l.setOpaque(true);
f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
}
/* I cannot tell what this was trying to achieve, but whatever it was,
this was the wrong way to go about it. Never call repaint() from within
the paintComponent method as this creates an infinite loop! */
/*
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(200, 300, 89, 90);
g.drawString("buv", 80, 80);
repaint();
}
*/
public static void main(String[] args) {
// Swing GUIs should be created and updated on the EDT
new autos();
}
#Override
public void actionPerformed(ActionEvent e) {
/* This logic is questionable, but it denpends on what you are trying
to achieve here, something I'm not clear on. */
now = 1;
if (now == 1) {
l.setText("hello");
l.setOpaque(true);
}
System.out.println("worked");
System.out.println(now);
}
}
Edit
You added two comments at the setBounds part saying this needs fixing!. There I tried to resize the JPanel and JLabel but it's obvious it doesn't work.
How should I proceed here?
Here are some 'copy/paste comments' I regularly use:
Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or combinations of them along with layout padding and borders for white space.
See Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? (Yes.)
Provide ASCII art or a simple drawing of the intended layout of the GUI at minimum size, and if resizable, with more width and height.
Now, to expand on those comments for this use-case:
That is advice I offer for people trying to make a null layout, but it also applies here.
This is relevant because there is one component (the custom painted one, if it exists) that needs to #Override the getPreferredSize(..) method to return a size as a suggestion to the layout managers or for packing the top level container.
The 3rd comment is because it is hard to advise how to code this GUI without knowing the end effect that is required.
Of course, I should point out: Each SO thread is expected to be a single, specific question. I really should have told you to start a new question on the other matters, but let it slide for this edit.
So I have 2 classes. One that creates a JPanel and a JFrame, and one that creates Buttons. Now I want to add those Buttons to my JPanel.
Where my JPanel and JFrame are created:
public class Surface extends JPanel implements KeyListener, ActionListener
{
private static final long serialVersionUID = 1L;
static JFrame jframe = new JFrame("TitleComingSoon");
Snake mySnake = new Snake(true);
int width;
int height;
#SuppressWarnings("deprecation")
public Surface(int width, int height)
{
this.width = width;
this.height = height;
// Create the JPanel
setLayout(null);
setBounds(0, 0, 400, 400);
setBackground(Color.DARK_GRAY);
// Create the JFrame
jframe.setSize(width, height);
jframe.setResizable(false);
jframe.setLayout(null);
jframe.add(this); // Add the JPanel to the JFrame
jframe.setVisible(true);
// Add the KeyListener
addKeyListener(this);
setFocusTraversalKeysEnabled(true);
setFocusable(true);
requestFocusInWindow();
show();
}
#Override
public void paintComponent(Graphics diamond)
{
super.paintComponent(diamond);
diamond.drawRect(60, 60, 100, 50);
diamond.setColor(Color.RED);
repaint();
}
}
And in my other class I'm doing this:
Surface.jframe.add(myButton);
My problem is, that the buttons is under the JPanel. So if I remove the JPanel, I can see the button.
Several things jump out...
Use of null layouts. While it might seem like you gain control, you increase your work load and lose flexibility between platforms.
Creating a frame from with another component, but more importantly, from within its constructor. The panel shouldn't be concerned with how it will be displayed and should be focused on doing the job it was designed for.
Use of KeyListener. KeyListener is fussy and troublesome, better to use the Key Bindings API
Use of static for cross object communication. Static is not how you provide access to fields across classes, there are plenty of other techniques which provide better support. The main problem is, if you create another instance of your pane, you'll create a new frame and change the reference to the static field...now which frame are you actually addressing?
So, what's the solution?
From your "main" entry class, create an instance of a JFrame, your Surface panel and button. Set the Surface panel as the content panel of the frame, then add the button to the frame.
Make use of appropriate layout managers
Use the key bindings API instead of KeyListener
You could create an instance of your ButtonHolderClass in Surface and retrieve the button by way of a public getter method:
public Surface(int width, int height)
{
...
ButtonHolderClass buttonHolder = new ButtonHolderClass();
JButton myButton = buttonHolder.getMyButton();
add(myButton); // Add myButton
jframe.add(this); // Add the JPanel to the JFrame
}
Surface.jframe.add(myButton);
You are adding the button to the JFrame. You said you wanted to add it to the JPanel.
Simply make it
Surface.add(myButton);
Surface.jframe.add(Surface);
That will add the JButton to the JPanel, then it will add the JPanel to the JFrame.
There is a slight problem in ordering things here. You are adding your Surface instance to the frame before the Surface constructor is done constructing it.
package test;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Surface extends JPanel {
static JFrame jframe;
static Surface surfaceInstance = new Surface();
public static Surface getInstance() {
return surfaceInstance;
}
public static void main(String argv[]) {
/* You need this to be a good friend of the Swing */
Runnable initiator = new Runnable() {
public void run() {
jframe = new JFrame("Whatever title you want");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // this will kill the application when you close the frame
jframe.setContentPane(Surface.getInstance());
jframe.pack();
jframe.setVisible(true);
}
};
/** You let the Swing run your initiator when Swing wishes to do so */
SwingUtilities.invokeLater(initiator);
Surface.getInstance().setPreferredSize(new Dimension(400,400));
/** then you can add other stuff to it **/
for (String buttonTitle: new String[] {"button1", "button2", "button3"}) {
Surface.getInstance().add(new JButton(buttonTitle));
}
}
}
I am currently learning Java, and I am stuck with something at the moment.
I was looking for a way to add an image to my JFrame.
I found this on the internet:
ImageIcon image = new ImageIcon("path & name & extension");
JLabel imageLabel = new JLabel(image);
And after implementing it to my own code, it looks like this (this is only the relevant part):
class Game1 extends JFrame
{
public static Display f = new Display();
public Game1()
{
Game1.f.setSize(1000, 750);
Game1.f.setResizable(false);
Game1.f.setVisible(true);
Game1.f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Game1.f.setTitle("Online First Person Shooter");
ImageIcon image = new ImageIcon("C:\\Users\\Meneer\\Pictures\\image.png");
JLabel imageLabel = new JLabel(image);
add(imageLabel);
}
}
class Display extends JFrame
{
}
When running this code, it doesn't give me any errors, but it also doesn't show the picture. I saw some questions and people having the same problem, but their code was completely different from mine, they used other ways to display the image.
You don't need to use another JFrame instance inside the Game JFrame:
Calling setVisible(flag) from the constructor is not preferable. Rather initialize your JFrame from outside and put your setVisible(true) inside event dispatch thread to maintain Swing's GUI rendering rules using SwingUtilities.invokeLater(Runnable)
Do not give size hint by setSize(Dimension) of the JFrame. Rather use proper layout with your component, call pack() after adding all of your relevant component to the JFrame.
Try using JScrollPane with JLabel for a better user experience with image larger than the label's size can be.
All of the above description is made in the following example:
class Game1 extends JFrame
{
public Game1()
{
// setSize(1000, 750); <---- do not do it
// setResizable(false); <----- do not do it either, unless any good reason
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Online First Person Shooter");
ImageIcon image = new ImageIcon("C:\\Users\\Meneer\\Pictures\\image.png");
JLabel label = new JLabel(image);
JScrollPane scrollPane = new JScrollPane(label);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
add(scrollPane, BorderLayout.CENTER);
pack();
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Game1().setVisible(true);
}
});
}
}
do this after creating Jlabel
imageLabel.setBounds(10, 10, 400, 400);
imageLabel.setVisible(true);
also set the layout to JFrame
Game.f.setLayout(new FlowLayout);
You are adding the label to the wrong JFrame. Also, move the setVisible() to the end.
import javax.swing.*;
class Game1 extends JFrame
{
public static Display f = new Display();
public Game1()
{
// ....
Game1.f.add(imageLabel);
Game1.f.setVisible(true);
}
}
Also try to use image from resources, and not from hardcoded path from your PC
You can look in here, where sombody asked similar question about images in Jframe:
How to add an ImageIcon to a JFrame?
Your problem in next you add your JLabel to Game1 but you display another Frame(Display f). Change add(imageLabel); to Game1.f.add(imageLabel);.
Recommendations:
1)according to your problem: Game1 extends JFrame seems that Display is also a frame, use only one frame to display content.
2) use pack() method instead of setSize(1000, 750);
3)call setVisible(true); at the end of construction.
4)use LayoutManager to layout components.
I'm a college student and this is my first time I have ever created a gui in Java. Right now I looked at this answer GUI in Java using Swing and followed the instructions and still nothing happens. Here is the code. I cut out all the irrelevant junk.
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Lab4Shell
{
// this holds the current game board
private char[][] gameBoard = new char[7][8];
private JButton[][] gameButtons = new JButton[7][8];
private ImageIcon red = new ImageIcon("Red.jpg");
private ImageIcon black = new ImageIcon("Black.jpg");
private ImageIcon empty = new ImageIcon("Empty.jpg");
private JPanel panel = new JPanel();
private int currentPlayer = 1;
private int numMoves = 0;
//Why do you want everything in constructor?
public Lab4Shell()
{
CreateWindow();
ResetGame();
// set layout
// loop through buttons array creating buttons, registering event handlers and adding buttons to panel
// add panel to frame
// do other initialization of applet
}
public static void CreateWindow()
{
//Sets window title and create window object.
JFrame aWindow = new JFrame("Connect Four");
//Set window position and size
aWindow.setBounds(500,100,400,400);
//What close button does.
aWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Make window visible.
aWindow.setVisible(true);
}
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Lab4Shell game = new Lab4Shell();
}
});
}
void ResetGame()
{
JLabel label = new JLabel();
label.setIcon(empty);
for(int r=0;r<gameBoard.length;r++)
{
java.util.Arrays.fill(gameBoard[r],0,gameBoard[r].length,'0');
//loop through board columns
for(int c=0;c<gameBoard[r].length;c++)
{
}
}
// loop through array setting char array back to ' ' and buttons array back to empty pic
// reset currentPlayer and numMoves variables
}
You have to add the created ImageIcons to the panel as Manos said, and being the images at the src folder of Eclipse project, do that:
java.net.URL url = getClass().getResource("red.JPEG");
ImageIcon red = new ImageIcon(url);
If the resources are embedded with the application (within in the jar), the you need to use Class#getResource to load them.
The preferred mechanism for loading images is through the ImageIO API. It supports more image formats (as well as providing a pluggable architecture) and guarantees an image that is ready to be displayed once the read method returns
BufferedImage redImage;
// ...
URL url = getClass().getResource("red.JPEG");
if (url != null) {
redImage = ImageIO.read(url);
} else {
throw new NullPointerException("Unable to locate red image resource");
}
You can try this
BufferedImage myPicture = ImageIO.read(new File("path-to-file"));
JLabel picLabel = new JLabel(new ImageIcon( myPicture ));
add( picLabel );
You've never adding anything to your frame - which is causing your problem. So in you createWindow method, you need to call:
aWindow.setContentPane(panel);
Then later on (like in your resetGame method), you'll add your content (like the JLabel) to the panel:
panel.add(empty);
Where it's added to your panel is determined by the LayoutManager of the panel (there are many of them - the default is BorderLayout)
Other helpful things:
Generally, when it makes sense, create/initialize your objects in the constructor and add/remove/update them in the runtime.
For troubleshooting, use the .setOpaque(true) and .setBackground(Color.blue) methods on what you want to see. If you don't see it then, either something is covering it up, or it was never added
Good luck.