Im having this problem where my Label2 which is assigned to be a text doesn't appear on the Jframe, even though I added it. Im assuming the other Labels which I set as images are overlaping it? If that is the problem how would I go upon fixing it?
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class Generator extends JFrame {
private static final long serialVersionUID = 1L;
/**
* Launch the application.
*/
public static void main(final String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
final Generator frame = new Generator();
frame.setVisible(true);
} catch (final Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Generator() {
/*
* #Images/Text
*/
final ImageIcon icon = new ImageIcon("data/hover_a.png");
final JLabel label = new JLabel(icon);
final ImageIcon icon1 = new ImageIcon("data/background.png");
final JLabel label1 = new JLabel(icon1);
final ImageIcon img = new ImageIcon("data/icon.png");
final JLabel label2 = new JLabel("Test Text");
/*
* #Image/Text Bounds
*/
label.setBounds(24, 266, 240, 40);
label1.setBounds(0, 0, 289, 330);
label2.setBounds(0, 0, 80, 15);
/*
* #Image Hovers
*/
label.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(final MouseEvent evt) {
label.setIcon(new ImageIcon("data/hover_b.png"));
}
#Override
public void mouseExited(final MouseEvent evt) {
label.setIcon(new ImageIcon("data/hover_a.png"));
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(295, 358));
setTitle("test");
getContentPane().setLayout(null);
setResizable(false);
setVisible(true);
setIconImage(img.getImage());
getContentPane().add(label);
getContentPane().add(label1);
getContentPane().add(label2);
pack();
}
}
You're calling setVisible(true) before adding all your components. Don't do this. The orde is:
add your components
call pack()
call setVisible(true)
if later you make changes then call revalidate() on the container, then repaint()
From reading your code, it appears that you are trying to layer images on top of each other. This would be much better achieved through the use of customer panels with custom painting
Have a look at the Performing Custom Painting lesson & 2D Graphics Trail
Without know precisely what you want to achieve, I would create a background panel that paints the background and then I would use a layout manager to layout the two other icons (personally, I used a GridBagLayout, but it might be a little over kill for you needs)
I would also familiarise your self with the painting order of components
Related
I'm learning how to create application in Java.
I'm having trouble getting the JLabel to have a background color whilst the JPanel is white, behind it. Also, is there a way to resize the JPanel to half of what the JFrame is?
Any help would be very much appreciated. Thank you.
package PracticeOne;
import java.awt.BorderLayout;
public class PracticeOne {
public static void main(String[] args) {
Frame container = new Frame();
Panel box = new Panel();
Label txt = new Label();
box.add(txt);
container.add(box, BorderLayout.CENTER);
}
}
package PracticeOne;
import javax.swing.JFrame;
public class Frame extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
Frame(){
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(500, 500);
this.setVisible(true);
this.setLocationRelativeTo(null);
this.setTitle("Testing this out");
}
}
package PracticeOne;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JPanel;
public class Panel extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
public Dimension d = new Dimension(100,100);
Panel(){
this.setSize(d);
this.setAlignmentX(CENTER_ALIGNMENT);
this.setBackground(Color.WHITE);
}
}
package PracticeOne;
import java.awt.Color;
import javax.swing.JLabel;
public class Label extends JLabel {
/**
*
*/
private static final long serialVersionUID = 1L;
Label(){
this.setSize(50, 50);
this.setText("ya boy is working here");
this.setForeground(Color.BLACK);
this.setBackground(Color.ORANGE);
}
}
I'm having trouble getting the JLabel to have a background color whilst the JPanel is white
You need to call setOpaque(true); in your JLabel
Also, is there a way to resize the JPanel to half of what the JFrame is?
You could use a GridLayout, and place 2 JPanels in it, that way, you're going to have 2 JPanels using half the size of your JFrame each.
Also, rename your classes, Panel belongs to the name of a class in AWT, same for Frame and Label, this might confuse your (and whoever reads your code).
Never extend JFrame, instead build your GUI based on JPanels. See extends JFrame vs creating it inside of class and The use of multiple JFrames, Good / Bad practice? The general consensus says it's bad.
Also you should also check Should I avoid the use of setPreferred|Maximum|MinimumSize() in Swing? Again, yes, you should and instead override the getPreferredSize() method.
Don't forget to place your program on the Event Dispatch Thread (EDT) by changing your main() method as follows:
public static void main(String[] args) {
//Java 8 with lambda expressions
SwingUtilities.invokeLater(() ->
//Your code here
);
//Java 7 and below (Or 8 without lambda expressions)
SwingUtilities.invokeLater(new Runnable() {
//Your code here
});
}
Now, with all the above recommendations, your code should now look like this:
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class HalfSizePanelWithLabelInDifferentColor {
private JFrame frame;
private Container contentPane;
private JPanel pane;
private JPanel pane2;
private JLabel label;
private static final Dimension dim = new Dimension(100, 100);
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new HalfSizePanelWithLabelInDifferentColor().createAndShowGui());
}
public void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
contentPane = frame.getContentPane();
pane = new JPanel() {
#Override
public Dimension getPreferredSize() {
return dim;
}
};
pane2 = new JPanel();
pane.setOpaque(false);
pane2.setOpaque(false);
pane.setBorder(BorderFactory.createLineBorder(Color.RED));
pane2.setBorder(BorderFactory.createLineBorder(Color.BLUE));
label = new JLabel("Hello World!");
label.setBackground(Color.GREEN);
label.setOpaque(true);
contentPane.setLayout(new GridLayout(2, 1));
pane.add(label);
contentPane.add(pane);
contentPane.add(pane2);
contentPane.setBackground(Color.WHITE);
frame.setContentPane(contentPane);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
And your output would be like this:
Note that I added some colored borders to show where a pane starts and ends and where the other one starts and ends
look at this simple code:
Main.java :
package CarManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Main extends JFrame {
private static final long serialVersionUID = 1L;
static int width = 400;
static int height = width / 16 * 9;
static String title = "Car Manager";
JButton viewTables = new JButton("View tables");
JButton clients = new JButton("Clients");
JButton search = new JButton("Search");
JButton viewCars = new JButton("View all");
JButton viewRent = new JButton("Rent a car");
JButton viewBuy = new JButton("Buy a car");
JButton viewAccessory = new JButton("Accessory");
public Main() {
setLayout(null);
setLocationRelativeTo(null);
setTitle(title);
setSize(width, height);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
JLabel background = new JLabel(new ImageIcon("res\\background2.jpg"));
add(background);
background.setSize(width, height);
add(viewTables);
add(clients);
add(search);
viewTables.setBounds(20, 20, 110, 30);
clients.setBounds(20, 70, 110, 30);
search.setBounds(20, 120, 110, 30);
viewTables.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
add(viewCars);
viewCars.setBounds(260, 20, 110, 20);
add(viewRent);
viewRent.setBounds(260, 50, 110, 20);
add(viewBuy);
viewBuy.setBounds(260, 80, 110, 20);
add(viewAccessory);
viewAccessory.setBounds(260, 110, 110, 20);
}
});
viewCars.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
View view = new View();
view.addWindowListener(new WindowPlug(Main.this));
setVisible(false);
}
});
}
public static void main(String args[]) {
new Main();
}
}
View.java:
package CarManager;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class View extends JFrame {
private static final long serialVersionUID = 1L;
int width = 400;
int height = width / 16 * 9;
String title = "View all Cars";
public View() {
setLayout(null);
setLocationRelativeTo(null);
setTitle(title);
setSize(width, height);
setResizable(false);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setVisible(true);
JLabel background = new JLabel(new ImageIcon("res\\background2.jpg"));
add(background);
background.setSize(width, height);
}
}
and WindowPlug.java:
package CarManager;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class WindowPlug extends WindowAdapter {
private Main mainFrame;
public WindowPlug(Main mainFrame) { // when creating an instance of this
// WindowAdapter, tell it with which
// Main Window you are working with
this.mainFrame = mainFrame;
}
public void windowClosing(WindowEvent e) {
mainFrame.setVisible(true);
mainFrame.revalidate();
}
}
when i click view tables and then view all (those are the buttons that work for now)
and the first window hides and a new window appears, now when i close the second window the first one appears visible but the buttons are not visible, i have to hover over with the mouse for them to be visible again. ive tried mainFrame.revalidate(); and
mainFrame.repaint();
but no result
im using windows 8.1 pro
One problem with your code, and I'm not sure if this is the main problem since your code works fine on my system, is that you're calling setVisible(true) on your main window before you've added all your components. It should only be called after all components have been added.
Other problems unrelated to your main question:
You should avoid using null layout. While using null layout may seem to a newbie the better way to create complex GUI's, it's a fallacy, and more you create Swing GUI's the more you learn to respect and use the layout managers and see that these creatures help immensely in creating flexible, beautiful and if need be, complex GUI's. Then you can let them size them selves appropriately by calling pack() prior to setting them visible.
It appears that you really want to use a CardLayout to swap views on one GUI rather than spitting multiple GUI's at the user.
If you absolutely must display a dialog window, then you should use a JDialog, not a JFrame. If you used a modal JDialog, you wouldn't be needing a WindowListener.
Edit
OK, a big problem I see is that you're using null layout and adding a JLabel that covers the whole contentPane, and then adding components to the same contentPane.
Instead, make the JLabel your contentPane, and then add your JButtons, etc to it.
But make sure that the JLabel's opaque property is set to true first.
Edit 2
If you need to use an image as a background image you can:
Put the Image in an ImageIcon, put the Icon in a JLabel, and again use the JLabel as your contentPane. Again, you will need to make the JLabel opaque by calling setOpaque(true) on it. This works well if you don't want to change the size of the image or the window.
If you do need to change the size of the image, better to have a JPanel draw the image in its paintComponent(Graphics g) method, and then use this JPanel as your contentPane.
Once you've created your contentPane, then set its layout and add your components to it.
Then call setContentPane(newContentPane) on your top level window and pass in the new contentPane.
JButton and JLabel disappears when adding custom background. I don't see any problems in my program, but maybe you guys find an solution! I think it's only a little thing I forgot, but I can't figure it out.
Here's the code:
GameWindow.java:
setContentPane(new StartImagePanel(RollrackLogo));
out.println("adding JLWelcome");
JLWelcome.setText("Welcome to Rollrack, " + namewindow.name);
add(JLWelcome);
JLWelcome.setVisible(true);
out.println("JLWelcome added");
out.println("adding JBRandom");
JBRandom.setText("Random");
add(JBRandom);
JBRandom.setVisible(true);
out.println("added JBRandom");
The background appears perfect, but not the JButton and JLabel!
Code to the StartImagePanel.java:
public class StartImagePanel extends JComponent{
private Image image;
public StartImagePanel(Image image) {
this.image = image;
}
#Override
protected void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, null);
}
}
Your button and label are added to your GameWindow frame while they should be added to its contentPane, setContentPane(new StartImagePanel(RollrackLogo)); instead. That's why they are not showing, they are added to the frame.
Make a variable of the StartImagePanel and add the button and label to it and they should show up.
StartImagePanel contentPanel = new StartImagePanel(RollrackLogo);
setContentPane(contentPanel);
...
out.println("adding JLWelcome");
JLWelcome.setText("Welcome to Rollrack, " + namewindow.name);
contentPanel.add(JLWelcome);
JLWelcome.setVisible(true);
out.println("JLWelcome added");
out.println("adding JBRandom");
JBRandom.setText("Random");
contentPanel.add(JBRandom);
JBRandom.setVisible(true);
out.println("added JBRandom");
Answer dispute
The claims in the first paragraph are plain wrong. Here is source that proves it.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class AddToCustomContentPane {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
// the GUI as seen by the user (without frame)
JPanel gui = new JPanel(new FlowLayout());
gui.setBorder(new EmptyBorder(2, 3, 2, 3));
gui.setBackground(Color.RED);
JFrame f = new JFrame("Demo");
f.setContentPane(gui);
// Acid test. Can we add buttons direct to the frame?
f.add(new JButton("Button 1"));
f.add(new JButton("Button 2"));
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See http://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}
Edit after the custom panel code was given
Here's a snippet that works to show both button and label on a black image background, I removed that was not needed (listeners).
public static void main(String[] v) {
class StartImagePanel extends JPanel {
private Image image;
public StartImagePanel(Image image) {
this.image = image;
}
#Override
protected void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, null);
}
}
class GameWindow extends JFrame{
public GameWindow() {
BufferedImage RollrackLogo;
RollrackLogo = new BufferedImage(400,200,BufferedImage.TYPE_INT_RGB);
final JButton JBRandom = new JButton();
final JLabel JLWelcome = new JLabel();
setDefaultCloseOperation(EXIT_ON_CLOSE);
StartImagePanel panel = new StartImagePanel(RollrackLogo);
setContentPane(panel);
setExtendedState(MAXIMIZED_BOTH);
setVisible(true);
JLWelcome.setText("Welcome to Rollrack");
panel.add(JLWelcome);
JLWelcome.setVisible(true);
JBRandom.setText("Random");
panel.add(JBRandom);
JBRandom.setVisible(true);
}
}
GameWindow window = new GameWindow();
window.pack();
window.setVisible(true);
}
I rather use an instance of a JFrame, instead of extending it, as #Andrew Thompson suggested in another question.
However, if you're extending it, it might be a good practice to call super() in the constructor.
Additionally, we may need to know what is going on in your StartImagePanel.
It seems, to me, to be the problem.
Ensure both your GameWindow and StartImagePanel extend properly their superclasses (call super();).
Ensure your StartImagePanel has a proper Layout.
Add your components before you set your frame visible. This also means you won't need JLWelcome.setVisible(true);.
Ensure that your code is executed in the EDT (Event-Dispatch Thread).
Example:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class GameWindow extends JFrame{
BufferedImage rollrackLogo;
JButton jbRandom;
JLabel jlWelcome;
public GameWindow() {
super();
jbRandom = new JButton("Random");
jlWelcome = new JLabel("Welcome to Rollrack, " +
namewindow.name);
rollrackLogo = new BufferedImage(400, 200,
BufferedImage.TYPE_INT_RGB);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setContentPane(new StartImagePanel(rollrackLogo));
// Add your components.
add(jlWelcome);
add(jbRandom);
addKeyListener(new KeyListener() {
#SuppressWarnings("static-access")
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == e.VK_ESCAPE){
System.exit(7);
}
}
#Override
public void keyReleased(KeyEvent arg0) {}
#Override
public void keyTyped(KeyEvent arg0) {}
});
// Pack, or otherwise set fullscreen.
pack();
// Now, set frame visible.
setVisible(true);
}
}
Edit: Now that you've posted the code for your StartImagePanel, I see that you're extending JComponent. Follow my previous advice, (call super), set a Layout, and extend JPanel instead.
When adding two components to a JFrame, where one sits inside another, If I add them in the order, Fullscreen Object, then JPanel, the JPanel displays correctly, but is essentially invisible, i.e it's action listener won't work and the clicks register on the fullscreen object. If I add them the other way round The JPanel works as it should, but doesn't display correctly (It has transparent areas).
This is the code for the Frame I am adding the components to.
gameOBJ = new gameClass(width, height);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(0);
frame.add(gameOBJ.UIPanel);
frame.add(gameOBJ);
frame.validate();
frame.setUndecorated(true);
frame.setBounds(0, 0, width, height);
frame.setResizable(false);
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent we)
{
new exitWindow("Don't forget to save your game! \n Are you sure you want to Exit?", true);
}
});
frame.setVisible(true);
gameOBJ.start();
Here is the code for the JPanel (Stripped down for simplicity's sake)
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
public class UserInterface extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private Image image;
private int xBound = 800;
private int yBound = 177;
private JButton mainMenuButton = new JButton(new ImageIcon("res/images/MainMenuButton.gif"));
private int buttonWidth = 179;
private int buttonHeight = 52;
public UserInterface()
{
this.setLayout(null);
this.image = new ImageIcon("res/images/UIPanelImage.gif").getImage();
this.setOpaque(false);
this.setSize(this.xBound, this.yBound);
mainThreeButtons(); //ONLY ONE SHOWN FOR SIMPLICITY
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 0, 0, this); //IMAGE CONTAINS TRANSPARENCY
}
#Override
public void actionPerformed(ActionEvent event)
{
else if (event.getSource() == mainMenuButton)
{
new mainMenuWindow();
}
}
private void mainThreeButtons()
{
this.add(mainMenuButton);
mainMenuButton.addActionListener(this);
//mainMenuButton.setOpaque(false);
mainMenuButton.setBorderPainted(false);
mainMenuButton.setContentAreaFilled(false);
mainMenuButton.setBounds(617, 6, buttonWidth, buttonHeight);
}
}
I would show an image but I'm not allowed to, The area which is meant to be transparent isn't showing the frame, because it is grey, whatever I set as the Frame's background, OR the panel's background, as again it is grey whatever I set the panel's background colour as.
You probably want to use JLabel instead of JPanel. I know it sounds a bit unintuitive, but I'm not sure JPanel is suited to the purpose you are using it for. Also, JLabel can have a native ImageIcon set, so try using that.
public UserInterface() { // extends JLabel
this.setImageIcon(new ImageIcon("res/images/UIPanelImage.gif"));
// or super(~imageicon~)
}
Unlikely, but it could be that the image is not yet loaded when it gets drawn. You should use MediaTracker to manage that more carefully (although I'm not sure ImageIcon if takes care of this for you).
final static protected MediaTracker mediatracker = new MediaTracker(new Canvas());
static protected void checkImageIsReady(Image i) {
mediatracker.addImage(i, 1);
try {
mediatracker.waitForAll();
} catch (InterruptedException e) { }
mediatracker.removeImage(i);
}
Good day!
Is it possible to add a JPanel on top of a JLabel?
I would like my JFrame to have a background image and in order to this, i used this code (based from past stackoverflow answers):
setLocation(150,50);
setSize(700,650);
setVisible(true);
JLabel contentPane = new JLabel();
contentPane.setIcon(new ImageIcon("pics/b1.jpg"));
contentPane.setLayout( new BorderLayout());
setContentPane( contentPane );
Now my problem is, I cannot put a panel on my JFrame because of the JLabel background.
Please help.
Thanks.
To create a background image for a JFrame, I recommend that you draw the image in the paintComponent method of a JPanel, and then add this JPanel to the contentPane BorderLayout.CENTER which has it fill the contentPane. You may even want to set the JPanel's preferredSize to be that of the Image. Then you can add any components you'd like to the image panel, and don't have to worry about trying to add comopnents to a JLabel which seems bass ackwards to me.
For example here's a program that does this but slightly different. It creates an ImagePanel object, a JPanel that draws an image and sizes itself to the image and then places it in a JScrollPane which is then added to the contentPane, but you can just get rid of the JScrollPane and put your image JPanel directly in the contentPane instead:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class BigDukeImage {
public static final String IMAGE_PATH = "http://" + "duke.kenai.com/nyanya/NyaNya.jpg";
private static final Dimension SCROLLPANE_SIZE = new Dimension(900, 700);
private static void createAndShowUI() {
Image image = null;
try {
URL url = new URL(IMAGE_PATH);
image = ImageIO.read(url);
// JLabel label = new JLabel(new ImageIcon(image));
ImagePanelA imagePanel = new ImagePanelA(image);
JScrollPane scrollpane = new JScrollPane();
// scrollpane.getViewport().add(label);
scrollpane.getViewport().add(imagePanel);
scrollpane.setPreferredSize(SCROLLPANE_SIZE);
JFrame frame = new JFrame("Big Duke Image");
frame.getContentPane().add(scrollpane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
JScrollBar vertSBar = scrollpane.getVerticalScrollBar();
JScrollBar horzSBar = scrollpane.getHorizontalScrollBar();
vertSBar.setValue((vertSBar.getMaximum() - vertSBar.getVisibleAmount()) / 2);
horzSBar.setValue((horzSBar.getMaximum() - horzSBar.getVisibleAmount()) / 2);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
#SuppressWarnings("serial")
class ImagePanelA extends JPanel {
private Image image;
public ImagePanelA(Image image) {
this.image = image;
setPreferredSize(new Dimension(image.getWidth(null), image.getHeight(null)));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
g.drawImage(image, 0, 0, null);
}
}
}
You could use a JLayeredPane. This lets you add components to different layers and have them ontop of one another.
I cannot put a panel on my JFrame because of the JLabel background
Thats because a panel is opague so it paints over top of the label. You need to use:
panel.setOpaque( false );
sure..you can....Use NetBEans IDE to simplify tedious tasks like this by drag and drop and write the actual programming..