I'm trying to make a simple connect four GUI by using a grid of JPanels each of which paints a colored disk when the button below them is pressed and the panels under it are full. Before adding the game rules I'm trying to just make sure the buttons and display work properly. But it is not working - only the top left panel displays a disk (after pressing button 1 6 times). here is my code:
public class ConnectFourFrame extends JFrame {
private final JPanel gamePanelsPanel; // panel to hold the game panels
private final GamePanel[][] gamePanels; // a 2D array to hold the grid of panels to display the game disks
private final JPanel buttonsPanel; // panel to hold the buttons panels
private final JPanel gameButtonsPanel; // panel to hold the game buttons to add disk to a column
private final JButton[] gameButtons; // an array to hold the game buttons
private final JPanel clearButtonPanel; // panel to hold the clear button
private final JButton clearButton; // button to clear the game grid from disks
private enum Turn {RED_PLAYER, BLUE_PLAYER}; // keeps track of which players turn it is
private Turn turn;
// no argument constructor
public ConnectFourFrame() {
super("Connect Four");
this.setLayout(new BorderLayout());
//add panels to hold the game panel and the buttons
gamePanelsPanel = new JPanel();
add(gamePanelsPanel, BorderLayout.CENTER);
buttonsPanel = new JPanel();
buttonsPanel.setLayout(new BorderLayout());
add(buttonsPanel, BorderLayout.SOUTH);
//set up game panels
gamePanelsPanel.setLayout(new GridLayout(6,7,3,3));
gamePanelsPanel.setBackground(Color.BLACK);
gamePanels = new GamePanel[6][7];
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
gamePanels[i][j] = new GamePanel(false, Color.WHITE);
gamePanelsPanel.add(gamePanels[i][j]);
}
}
//set up game and clear buttons
gameButtonsPanel = new JPanel();
gameButtonsPanel.setLayout(new GridLayout(1,7));
clearButtonPanel = new JPanel();
gameButtons = new JButton[7];
for (int i = 0; i < 7; i++) {
gameButtons[i] = new JButton("" + (i+1));
gameButtonsPanel.add(gameButtons[i]);
}
clearButton = new JButton("CLEAR");
clearButtonPanel.add(clearButton);
buttonsPanel.add(gameButtonsPanel, BorderLayout.NORTH);
buttonsPanel.add(clearButtonPanel, BorderLayout.SOUTH);
add(buttonsPanel, BorderLayout.SOUTH);
// register event handlers
ClearButtonHandler clearButtonHandler = new ClearButtonHandler();
clearButton.addActionListener(clearButtonHandler);
GameButtonHandler gameButtonHandler = new GameButtonHandler();
for (int i = 0; i < 7; i++) {
gameButtons[i].addActionListener(gameButtonHandler);
}
turn = Turn.RED_PLAYER; //set first turn to player1
}
// inner class for game button event handling
private class GameButtonHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// get the number of the pressed button
int pressedButtonNum = Integer.parseInt(((JButton) e.getSource()).getActionCommand());
// display disk in top empty panel of the column
for (int i = 5; i >= 0; i--) {
if (!gamePanels[i][pressedButtonNum - 1].isFull()) {
if (turn == Turn.RED_PLAYER) {
gamePanels[i][pressedButtonNum - 1].setDiskColor(Color.RED);
turn = Turn.BLUE_PLAYER;
}
else {
gamePanels[i][pressedButtonNum - 1].setDiskColor(Color.BLUE);
turn = Turn.RED_PLAYER;
}
gamePanels[i][pressedButtonNum - 1].setFull(true);
gamePanels[i][pressedButtonNum - 1].repaint();
return;
}
}
// if column is full display message to try again
JOptionPane.showMessageDialog(gamePanelsPanel, "Column " + pressedButtonNum + " is full. Try again.");
}
}
public class GamePanel extends JPanel{
private boolean isFull; // true if the panel has a disk in it. default is empty (false).
private Color diskColor; //color of disks. default is white (same as background)
public GamePanel(boolean isFull, Color diskColor) {
super();
this.isFull = isFull;
this.diskColor = diskColor;
}
public Color getDiskColor() {
return diskColor;
}
public void setDiskColor(Color diskColor) {
this.diskColor = diskColor;
}
public boolean isFull() {
return isFull;
}
public void setFull(boolean isFull) {
this.isFull = isFull;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.WHITE);
g.setColor(diskColor);
g.fillOval(this.getX() + this.getWidth()/4 , this.getY() + this.getHeight()/4, this.getWidth()/2, this.getHeight()/2);
}
}
The problem is right here...
g.fillOval(this.getX() + this.getWidth()/4 , this.getY() + this.getHeight()/4, this.getWidth()/2, this.getHeight()/2);
The Graphics context passed to your paintComponent method has already been translated by the components x/y position, meaning that the top/left corner of the component is always 0x0
g.fillOval(this.getWidth()/4 , this.getHeight()/4, this.getWidth()/2, this.getHeight()/2);
will probably work better
Also, calling this.setBackground(Color.WHITE); inside paintComponent is unadvisable, as it will setup a situation where by a new paint cycle will be scheduled, over and over again. Don't change the state of the UI from within a paint method
I am trying to do a simple Minesweeper game using JFrame, however I am having troubles with the creation of objects. I am creating 96 buttons, some of which get the property of being wrong ("F") and right ("R"):
public class GUIBase extends JFrame {
private JButton button;
private JButton fButton;
public GUIBase() {
super("Minesweeper");
setLayout(new FlowLayout());
//Fields
int position;
for (int i = 0; i < 96; i++) {
position = (int) (Math.random() * 100);
if (position < 80) {
button = new JButton("R");
button.setToolTipText("Is this the correct one?");
add(button);
} else {
fButton = new JButton("F");
fButton.setToolTipText("Is this the correct one?");
add(fButton);
}
}
I then use ActionListener in order to check whether or not the button is correct. If the button is correct, it will get .setEnabled(false), otherwise the game ends:
//Action
Action action = new Action();
button.addActionListener(action);
fButton.addActionListener(action);
}
private class Action implements ActionListener {
public void actionPerformed(ActionEvent event) {
System.out.println("Somethin");
if (event.getSource() == button) {
button.setEnabled(false);
} else if (event.getSource() == fButton) {
JOptionPane.showMessageDialog(null, "You lost!");
System.exit(0);
} else {
JOptionPane.showMessageDialog(null, "An error ocurred");
System.exit(0);
}
}
}
Everything in the game turns out as planned, however only the last correct button ("R") and last wrong one ("F") are connected to the ActionListener. The rest of the buttons do not do anything when pressed.
How can I fix this?
The problem is that you only have two variables (attributes of the class GUIBase, specifically), and your are assigning to it each time you create a new button. Hence, you only have a reference to the last buttons.
You need an array of buttons. Let's see:
public class GUIBase extends JFrame {
public final int MAX_BUTTONS = 96;
private JButton[] buttons;
// ...
}
The next step is to create the array itself at the beginning:
public GUIBase() {
super("Minesweeper");
setLayout(new FlowLayout());
this.buttons = new JButton[MAX_BUTTONS];
//Fields
int position;
for (int i = 0; i < buttons.length; i++) {
position = (int) (Math.random() * 100);
this.buttons[ i ] = new JButton("R");
this.buttons[ i ].setToolTipText("Is this the correct one?");
this.add(this.buttons[ i ]);
Action action = new Action();
this.buttons[ i ].addActionListener(action);
}
}
You'll probably need more depth in arrays in order to completely understand the code. Basically, an array is a continuous collection of variables, which you can index by its position, from 0 to n-1, being n the number of positions.
Then you'll probably be able to fill the gaps yourself.
Hope this helps.
One part of your problems is coming from your action listener.
Of course, one part is that your code probably needs a list/array to keep track of all created buttons; but at least right now, you can rework your code without using arrays/list:
private class Action implements ActionListener {
public void actionPerformed(ActionEvent event) {
System.out.println("Somethin");
if (event.getSource() instanceofJButton) {
JBUtton clickedButton = (JButton) event.getSource();
String buttonText = clickedButton.getText();
if (buttonText.equals("R") ...
else if (buttonText.equals("F")
You see, the whole point here is: as of now, you just need to know what kind of button was created. And your ActionListener knows which button it was clicked on ...
Code with near-identical blocks like this makes me cringe. Plus it adds up to where you have a thousand lines of code where half that would suffice. Surely there is a way to make a loop to make it all happen and not have code that looks so unsophisticated and brainless.
Offhand it seems like to do so would be adding as much code as I seek to reduce: loop to make 5 buttons, array of labels for the buttons, array of backgrounds... maybe more. Even if that turned out to be acceptable, how would I make a loop to handle the listeners? I can't have an array of methods, can I? I guess such a loop it would have to include a switch. Yes? I'd probably do that if I didn't want to seek a better solution. So I'm asking...
What would code look like that would listen to the entire group of buttons and take action based on which one was pressed? To which component would I assign the single listener? And how?
(There's a chance that the answer to that question will make me cringe even more than the repetitive nature of the code, if I realize that I already know how to do so and needn't have even asked in the first place, but I'm asking anyway. I'm at one of those I've-had-it-for-today points where the brain just wants out.)
private void makeScoremasterBonuses(){
pnlBonuses = new JPanel(new GridLayout(1, 6));
pnlBonuses.setSize(6,1);
JButton t1 = (new JButton("3W"));
t1.setToolTipText("This is a triple-word cell.");
t1.setBackground(TRIPLE_WORD);
t1.setHorizontalAlignment(JButton.CENTER);
t1.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
Highlighter.shadeSymmetric(currentCell,TRIPLE_WORD);
}});
JButton t2 = (new JButton("3L"));
t2.setToolTipText("This is a triple-letter cell");
t2.setBackground(TRIPLE_LETTER);
t2.setHorizontalAlignment(JButton.CENTER);
t2.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
Highlighter.shadeSymmetric(currentCell,TRIPLE_LETTER);
}});
JButton t3 = (new JButton("2W"));
t3.setToolTipText("This is a double-word cell");
t3.setBackground(DOUBLE_WORD);
t3.setHorizontalAlignment(JButton.CENTER);
t3.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
Highlighter.shadeSymmetric(currentCell,DOUBLE_WORD);
}});
JButton t4 = (new JButton("2L"));
t4.setToolTipText("This is a double-letter cell");
t4.setBackground(DOUBLE_LETTER);
t4.setHorizontalAlignment(JButton.CENTER);
t4.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
Highlighter.shadeSymmetric(currentCell,DOUBLE_LETTER);
}});
JButton t5 = (new JButton(""));
t5.setToolTipText("No bonus");
t5.setBackground(WHITE);
t5.setHorizontalAlignment(JButton.CENTER);
t5.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
Highlighter.shadeSymmetric(currentCell,B_NORMAL);
}});
pnlBonuses.add(new JLabel("Legend: "));
pnlBonuses.add(t1);
pnlBonuses.add(t2);
pnlBonuses.add(t3);
pnlBonuses.add(t4);
pnlBonuses.add(t5);
}
I'm not asking anyone to write the code; I wouldn't even want that (but I couldn't ignore it!).
Here's what the code above does:
Generally any time you have repeated functionality like that, you want to extract that code out into a helper method like this:
private JButton makeJButton(String label, String toolTip, Color bgColor, final Color highlight) {
JButton button = new JButton(label);
button.setToolTipText(toolTip);
button.setBackground(bgColor);
button.setHorizontalAlignment(JButton.CENTER);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Highlighter.shadeSymmetric(currentCell, highlight);
}
});
return button;
}
Then your makeScoremasterBonuses() method becomes much simpler:
private void makeScoremasterBonuses() {
pnlBonuses = new JPanel(new GridLayout(1, 6));
pnlBonuses.setSize(6, 1);
pnlBonuses.add(new JLabel("Legend: "));
pnlBonuses.add(makeJButton("3W", "This is a triple-word cell.", TRIPLE_WORD, TRIPLE_WORD));
pnlBonuses.add(makeJButton("3L", "This is a triple-letter cell.", TRIPLE_LETTER, TRIPLE_LETTER));
pnlBonuses.add(makeJButton("2W", "This is a double-word cell.", DOUBLE_WORD, DOUBLE_WORD));
pnlBonuses.add(makeJButton("3L", "This is a double-letter cell.", DOUBLE_LETTER, DOUBLE_LETTER));
pnlBonuses.add(makeJButton("", "No bonus.", WHITE, B_NORMAL));
}
Identify the aspects that vary, collect them, and iterate over the collection.
Something like this (untested):
pnlBonuses = new JPanel(new GridLayout(1, 6));
pnlBonuses.setSize(6,1);
pnlBonuses.add(new JLabel("Legend: "));
// Create class "CellInfo" with constructor and getters for desired properties.
CellInfo cellInfos[] = {
new CellInfo("3W", "This is a triple-word cell.", TRIPLE_WORD),
new CellInfo("3L", "This is a triple-letter cell.", TRIPLE_LETTER),
// ...
};
// Add a button for each item described by the cellInfos.
for (CellInfo cellInfo : cellInfos) {
Button b = new JButton(cellInfo.getLabel());
b.setToolTipText(cellInfo.getToolTipText());
b.setBackground(cellInfo.getBackground());
b.setHorizontalAlignment(JButton.CENTER);
b.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
Highlighter.shadeSymmetric(currentCell, cellInfo.getBackground());
}});
pnlBonuses.add(b);
}
Note that you might need to create some "final" variables for placeholders for use in the inner anonymous class but the idea should work.
An enum could be your friend here. It's almost an array of methods:
static enum Btn {
TripleWord("3W", "This is a triple word cell.", TRIPLE_WORD),
TripleLetter("3L", "This is a triple letter cell.", TRIPLE_LETTER),
DoubleWord("2W", "This is a double word cell.", DOUBLE_WORD),
DoubleLetter("2L", "This is a double letter cell.", DOUBLE_LETTER),
NoBonus("", "No bonus.", WHITE, B_NORMAL);
final String label;
final String tooltip;
final Color color;
final Color shade;
Btn(String label, String tooltip, Color color, Color shade) {
this.label = label;
this.tooltip = tooltip;
this.color = color;
this.shade = shade;
}
Btn(String label, String tooltip, Color color) {
this(label, tooltip, color, color);
}
public JButton asJButton() {
JButton btn = (new JButton(label));
btn.setToolTipText(tooltip);
btn.setBackground(color);
btn.setHorizontalAlignment(JButton.CENTER);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Highlighter.shadeSymmetric(currentCell, shade);
}
});
return btn;
}
}
private void makeScoremasterBonuses() {
int nBtns = Btn.values().length;
JPanel pnlBonuses = new JPanel(new GridLayout(1, nBtns + 1));
pnlBonuses.setSize(nBtns + 1, 1);
pnlBonuses.add(new JLabel("Legend: "));
for (Btn btn : Btn.values()) {
pnlBonuses.add(btn.asJButton());
}
}
(I know I could have edited my previous answer, but this one's so different...)
Thanks to #OldCurmudgeon, I have come up with what I think is pretty good.
Here's "proof" (I may just leave each label and tooltip as is):
public enum Colors {
TRIPLE_WORD (255, 220, 50),
TRIPLE_LETTER (255, 255, 150),
DOUBLE_WORD ( 0, 255, 0),
DOUBLE_LETTER (214, 245, 214),
NOT_A_BONUS (255, 255, 255);
private final int red, green, blue;
Colors(int r, int g, int b){
this.red = r;
this.green = g;
this.blue = b;
}
public java.awt.Color background(Colors c){
return new java.awt.Color(c.red, c.green, c.blue);
}
}
private void makeScoremasterBonuses(){
Colors c;
Colors all [] = Colors.values();
String labels[] = new String[all.length];
String abbrs [] = new String[all.length];
JButton but;
pnlBonuses = new JPanel();
pnlBonuses.add(new JLabel("Legend:"));
for (int i = 0; i < all.length; i++) {
labels[i] = all[i].name().replace("_", " ").toLowerCase();
abbrs [i] = abbreviate(all[i].name());
c = Colors.values()[i];
but = new JButton(abbrs[i]);
but.setToolTipText(labels[i]);
but.setBackground(c.background(c));
but.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
but.setActionCommand("" + i);
but.addActionListener(this);
pnlBonuses.add(but);
}
}
=== THIS IS A MAJOR EDIT OF WHAT I POSTED AN HOUR AGO ===
I wanted to see if I could implement my own naive method. Here it is:
public class Game implements ActionListener{
public Color [] backgrounds = {TRIPLE_WORD, TRIPLE_LETTER,
DOUBLE_WORD, DOUBLE_LETTER, B_NORMAL};
private void makeScoremasterBonuses(){
String[] labels = {"3W", "3L", "2W", "2L", " "};
JButton but;
pnlBonuses = new JPanel();
pnlBonuses.add(new JLabel("Legend:"));
for (int i = 0; i < labels.length; i++) {
char wt = labels[i].charAt(0);
char tp = labels[i].charAt(1);
but = new JButton(labels[i]);//("" + i);
but.setBackground(backgrounds[i]);
but.setHorizontalAlignment(SwingConstants.CENTER);
but.setActionCommand("" + i);
but.addActionListener(this);
but.setToolTipText("This is a "
+ (i == labels.length - 1 ? "non-bonus" :
(wt == '3' ? "triple" : "double")
+ " " + (tp == 'L' ? "letter" : "word"))
+ " cell.");
pnlBonuses.add(but);
}
}
public void actionPerformed(ActionEvent evt) {
int i = Integer.parseInt(evt.getActionCommand());
Highlighter.shadeSymmetric(currentCell,backgrounds[i]);
}
This has NOW (after edits) EVEN MORE SO been the best thread I've initiated, in terms of quality of responses and all that I've learned because of them. THANK YOU ALL.
BUT I STILL haven't managed to appropriately use setActionCommand. Whatever I did to TRY to use it wound up being so much longer code-wise that I gave up and went for the short and easy but inappropriate.
Any thoughts about how to use set... and getActionCommand the right way (i.e., as Actions) without adding a ton of code to do so?
Having some problems updating a JTextField in a different class after reading a String from another JTextField. Here's the method in question:
public JTextField buyVowel(playerPlate player)
{
String get = input.getText();
String[] vowels = new String[]{"a","e","i","o","u"};
for(int i =0; i<vowels.length; i++)
{
if(get.equals(vowels[i]))
{
player.pMoney =- 250;
player.playerMoney.setText("$"+player.pMoney);
}
}
return player.playerMoney;
}
playerPlate is a separate class.
I'm using this method to determine what player the program should be modifying:
public playerPlate getCurrentPlayer()
{
if(currentPlayer == 1)
{
return player1;
}
else if(currentPlayer == 2)
{
return player2;
}
else
{
return player3;
}
}
player(s) 1, 2, and 3 are instances of playerPlate.
I want it to be modifying instance variables in this class:
package wheelOfFortune;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class playerPlate extends JPanel
implements ActionListener
{
public String pName;
public int pMoney = 500;
public int currentPlayer;
public JTextField playerMoney;
public playerPlate(String player, Color color, int currentPlayer)
{
setBorder(BorderFactory.createLineBorder(Color.BLACK,2));
setBackground(color);
pName = player;
JTextField playerNames = new JTextField(pName);
playerNames.setBorder(BorderFactory.createLineBorder(Color.BLACK,2));
playerNames.setEditable(false);
playerNames.setFont(new Font("Impact", Font.PLAIN, 24));
playerNames.setHorizontalAlignment(JTextField.CENTER);
playerNames.setBackground(Color.WHITE);
JTextField playerMoney = new JTextField("$"+pMoney);
playerMoney.setBorder(BorderFactory.createLineBorder(Color.BLACK,2));
playerMoney.setEditable(false);
playerMoney.setFont(new Font("Impact", Font.BOLD, 32));
playerMoney.setHorizontalAlignment(JTextField.CENTER);
playerMoney.setBackground(Color.WHITE);
Box b1 = Box.createVerticalBox();
b1.add(playerNames);
b1.add(Box.createVerticalStrut(5));
Box b2 = Box.createHorizontalBox();
b2.add(Box.createHorizontalStrut(60));
Box b3 = Box.createVerticalBox();
b3.add(playerMoney);
b3.add(Box.createVerticalStrut(8));
b2.add(b3);
b1.add(b2);
b1.add(Box.createVerticalStrut(5));
add(b1);
}
public void actionPerformed(ActionEvent e)
{
}
}
Here is the actionPerformed method within the main class:
public void actionPerformed(ActionEvent e)
{
JButton b = (JButton)e.getSource();
if(b==spin)
{
spinWheel(wheelStuff);
repaint();
}
if(b==next)
{
updatePlayer();
repaint();
}
if(b==reset)
{
letterBoard.reset();
updateCat();
repaint();
}
if(b==buyVowel)
{
buyVowel(getCurrentPlayer());
repaint();
}
}
The gist of what I want to happen, is when the user types a vowel into JTextField input, and clicks JButton buyVowel it subtracts $250 from their total money (pMoney). And displays the change on the GUI. After tinkering with this for a couple hours, I honestly have no idea why this isn't working. I keep receiving nullPointerExceptions when trying to use it. Thanks for your help.
Note: everything except for class playerPlate is in the same class. playerPlate is in a separate class.
You're shadowing the variable playerMoney in the constructor of playerPlate. The method buyVowel relies on playerPlate being instantiated when invoking setText, otherwise a NullPointerException will be thrown. Replace
JTextField playerMoney = new JTextField("$"+pMoney);
with
playerMoney = new JTextField("$"+pMoney);
Aside: Java naming conventions indicate that class names start with uppcase letters so use class names such as PlayerPlate.
I have the following code:
public class Test extends JFrame implements ActionListener{
private static final Color TRANSP_WHITE = new Color(new Float(1), new Float(1), new Float(1), new Float(0.5));
private static final Color TRANSP_RED = new Color(new Float(1), new Float(0), new Float(0), new Float(0.1));
private static final Color[] COLORS = new Color[]{ TRANSP_RED, TRANSP_WHITE};
private int index = 0;
private JLabel label;
private JButton button;
public Test(){
super();
setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
label = new JLabel("hello world");
label.setOpaque(true);
label.setBackground(TRANSP_WHITE);
getContentPane().add(label);
button = new JButton("Click Me");
button.addActionListener(this);
getContentPane().add(button);
pack();
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(button)){
label.setBackground(COLORS[index % (COLORS.length - 1)]);
index++;
}
}
public static void main(String[] args) {
new Test();
}
}
When I run it I get the label with the TRANSP_WHITE background and then when I click the button this color changes to TRANSP_RED but when I click it again I see no change in color. Does anyone know why?
Thanks
Well, what were you expecting to happen?
label.setBackground(COLORS[index % (COLORS.length - 1)]);
The index variable is hard coded to 0. and COLORS.length -1 is essentially a constant. So every time you click your setting the background to COLORS[0];
If you change your action method to the following you'll get the results you are looking for:
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(button)){
label.setBackground(COLORS[index % COLORS.length]);
index++;
}
}
First: The modulo operator will always return a value between 0 and one less than the value passed to it. So
index % COLORS.length
Will always return a value between 0 and COLORS.length -1.
Second: You were forgetting to increment index after every call.
Hey! You forgot to increment index. In this expression:
label.setBackground(COLORS[index % (COLORS.length - 1)]);
index % (COLORS.length - 1) is always 0.
BTW. you don't have to use new Float(1) when creating Color. 1F should work too.
Here is the code you have to use
label.setBackground(COLORS[index % (COLORS.length)]);
index++;
You are doing it wrong. It should be done like that
label = new JLabel("hello world"){
public void paintComponent(Graphics g)
{
//draw background
Color old=g.getColor();
g.setColor(getBackground());
g.fillRect(0,0,getWidth(),getHeight());
g.setColor(old);
super.paintComponent(g);
}
};
label.setOpaque(false); // your component is not opaque!