'Else if only displays the last panel
I have set up a huge game project. I'm using the CardLayout to show when the mouse is released on the JLabel. I have it working on other classes' JLabels, but when I press a JLabel it only shows the last JPanel of the CardLayout. I want it to show the specific JPanel that I have it set to.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Timer;
import java.util.TimerTask;
class ChooseGame extends JPanel {
Icon imgIcon = new ImageIcon(this.getClass().getResource("gameOne.gif"));
Icon imgIcon2 = new ImageIcon(this.getClass().getResource("gameTwo.gif"));
Icon imgIcon3 = new ImageIcon(this.getClass().getResource("gameThree.gif"));
Icon imgIcon4 = new ImageIcon(this.getClass().getResource("gameFour.gif"));
JLabel game1 = new JLabel(imgIcon);
JLabel game2 = new JLabel(imgIcon2);
JLabel game3 = new JLabel(imgIcon3);
JLabel game4 = new JLabel(imgIcon4);
JLabel game5 = new JLabel(imgIcon);
JLabel game6 = new JLabel(imgIcon2);
JLabel game7 = new JLabel(imgIcon);
JLabel game8 = new JLabel(imgIcon2);
JLabel game9 = new JLabel(imgIcon);
Handler handler = new Handler();
public ChooseGame() {
setVisible(true);
setBackground(Color.RED);
setForeground(Color.BLACK);
setLayout(new GridLayout(3, 3));
addMouseListener(handler);
addMouseMotionListener(handler);
buttons();
add(game1);
add(game2);
add(game3);
add(game4);
add(game5);
add(game6);
add(game7);
add(game8);
add(game9);
}
public void buttons() {
game1.addMouseListener(handler);
game1.addMouseMotionListener(handler);
game1.setVisible(true);
game2.addMouseListener(handler);
game2.addMouseMotionListener(handler);
game2.setVisible(true);
game3.addMouseListener(handler);
game3.addMouseMotionListener(handler);
game3.setVisible(true);
game4.addMouseListener(handler);
game4.addMouseMotionListener(handler);
game4.setVisible(true);
game5.addMouseListener(handler);
game5.addMouseMotionListener(handler);
game5.setVisible(true);
game6.addMouseListener(handler);
game6.addMouseMotionListener(handler);
game6.setVisible(true);
game7.addMouseListener(handler);
game7.addMouseMotionListener(handler);
game7.setVisible(true);
game8.addMouseListener(handler);
game8.addMouseMotionListener(handler);
game8.setVisible(true);
game9.addMouseListener(handler);
game9.addMouseMotionListener(handler);
game9.setVisible(true);
}
private class Handler implements MouseListener, MouseMotionListener {
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
time(e);
}
public void time(MouseEvent e) {
Timer timer = new Timer();
// adds new Timer
TimerTask task = new TimerTask() {
// sets new task for said timer
@Override
public void run() {
if (game1.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "one");
} else if (game2.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "two");
} else if (game3.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "three");
} else if (game4.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "four");
} else if (game5.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "five");
} else if (game6.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "six");
} else if (game7.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "seven");
} else if (game8.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "eight");
} else if (game9.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "nine");
}
}
};
timer.scheduleAtFixedRate(task, 0, 1000);
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseDragged(MouseEvent e) {
System.out.println("Dragged");
}
@Override
public void mouseMoved(MouseEvent e) {
}
}
}
Solution 1:[1]
There's a lot going on which is, well, questionable at best, for example...
public ChooseGame() {
//...
addMouseListener(handler);
addMouseMotionListener(handler);
//...
}
public void buttons() {
game1.addMouseListener(handler);
game1.addMouseMotionListener(handler);
//...
}
Now, both the ChooseGame and each individual label has a the MouseListener attached to them, why? This could cause a double trigger of events
Then...
public void time(MouseEvent e) {
Timer timer = new Timer();
// adds new Timer
TimerTask task = new TimerTask() {
// sets new task for said timer
@Override
public void run() {
if (game1.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "one");
} else if (game2.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "two");
} else if (game3.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "three");
} else if (game4.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "four");
} else if (game5.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "five");
} else if (game6.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "six");
} else if (game7.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "seven");
} else if (game8.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "eight");
} else if (game9.contains(e.getX(), e.getY())) {
CardPanel.layout.show(CardPanel.cardPanel, "nine");
}
}
};
timer.scheduleAtFixedRate(task, 0, 1000);
}
you're comparing the point of the event against the each labels location, which in my testing, had each label return true for the contains check ?.
Why not just compare the source of the event
if (e.getSource() == game1) {...}
I'm not even going to ask why you need to check this repeatedly every second or why you're using a static reference to CardPanel - it's not ChooseGame's responsibility to switching the cards, instead, it should be informing CardPanel that some state has changed and CardPanel should be making the decisions on how to respond to that change.
But, let's focus on the initial issue.
Instead of using a single Handler, we can focus on creating a "handler" which can be customised for each individual label, or preferably, the desired result, for example...
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new ChooseGame());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
protected BufferedImage makeImage(String text) {
int size = 50;
BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.setColor(Color.LIGHT_GRAY);
Shape baseShape = new RoundRectangle2D.Double(0, 0, size - 1, size - 1, 10, 10);
g2d.fill(baseShape);
g2d.setColor(Color.DARK_GRAY);
g2d.draw(baseShape);
FontMetrics fm = g2d.getFontMetrics();
int x = (size - fm.stringWidth(text)) / 2;
int y = (size - fm.getHeight()) / 2;
g2d.setColor(Color.BLACK);
g2d.drawString(text, x, y + fm.getAscent());
g2d.dispose();
return img;
}
class ChooseGame extends JPanel {
private ImageIcon[] icons = new ImageIcon[]{
new ImageIcon(makeImage("1")),
new ImageIcon(makeImage("2")),
new ImageIcon(makeImage("3")),
new ImageIcon(makeImage("4"))
};
private JLabel[] labels = new JLabel[9];
public ChooseGame() {
setBackground(Color.RED);
setForeground(Color.BLACK);
setLayout(new GridLayout(3, 3));
createActions();
for (JLabel label : labels) {
add(label);
}
}
public void createActions() {
for (int index = 0; index < labels.length; index++) {
ImageIcon icon = null;
ActionHandler.Action action = ActionHandler.Action.from(index);
if (index == 0 || index == 4 || index == 6 || index == 8) {
icon = icons[0];
} else if (index == 1 || index == 5 || index == 7) {
icon = icons[1];
} else if (index == 2) {
icon = icons[2];
} else if (index == 3) {
icon = icons[3];
}
JLabel label = new JLabel(icon);
if (action != null) {
ActionHandler actionHandler = new ActionHandler(action);
label.addMouseListener(actionHandler);
label.addMouseMotionListener(actionHandler);
}
labels[index] = label;
}
}
protected class ActionHandler extends MouseAdapter {
enum Action {
ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE;
static Action from(int index) {
switch (index) {
case 0:
return ONE;
case 1:
return TWO;
case 2:
return THREE;
case 3:
return FOUR;
case 4:
return FIVE;
case 5:
return SIX;
case 6:
return SEVEN;
case 7:
return EIGHT;
case 8:
return NINE;
}
return null;
}
}
private Action action;
public ActionHandler(Action action) {
this.action = action;
}
public Action getAction() {
return action;
}
@Override
public void mouseClicked(MouseEvent e) {
switch (getAction()) {
case ONE:
System.out.println("Show one");
break;
case TWO:
System.out.println("Show two");
break;
case THREE:
System.out.println("Show three");
break;
case FOUR:
System.out.println("Show four");
break;
case FIVE:
System.out.println("Show five");
break;
case SIX:
System.out.println("Show six");
break;
case SEVEN:
System.out.println("Show seven");
break;
case EIGHT:
System.out.println("Show eight");
break;
case NINE:
System.out.println("Show nine");
break;
}
}
}
}
}
But, this raises more questions over the decision to use labels, why?
JLabels have more stylistic choices
Really, in what ways? What is worth sacrificing the core functionality of a button, whose sole responsibility is to tell you when the user selects it? Why spend all this time recreating that functionality?
For example, one of these is using label the other is using buttons
Can you tell the difference? Don't believe me, it's okay, I wouldn't ?. One of those images is generated from the code above, the other from this code...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.setLayout(new GridBagLayout());
frame.add(new ChooseGame());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface CardPresentable {
enum Card {
ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE;
}
public void showCard(Card card);
}
public class CardPane extends JPanel implements CardPresentable {
private JLabel label;
public CardPane() {
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new BorderLayout());
label = new JLabel("Nothing");
add(label);
}
@Override
public void showCard(Card card) {
label.setText(card.name());
}
}
protected BufferedImage makeImage(String text) {
int size = 50;
BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.setColor(Color.LIGHT_GRAY);
Shape baseShape = new RoundRectangle2D.Double(0, 0, size - 1, size - 1, 10, 10);
g2d.fill(baseShape);
g2d.setColor(Color.DARK_GRAY);
g2d.draw(baseShape);
FontMetrics fm = g2d.getFontMetrics();
int x = (size - fm.stringWidth(text)) / 2;
int y = (size - fm.getHeight()) / 2;
g2d.setColor(Color.BLACK);
g2d.drawString(text, x, y + fm.getAscent());
g2d.dispose();
return img;
}
class ChooseGame extends JPanel {
private ImageIcon[] icons = new ImageIcon[]{
new ImageIcon(makeImage("1")),
new ImageIcon(makeImage("2")),
new ImageIcon(makeImage("3")),
new ImageIcon(makeImage("4"))
};
private JButton[] buttons = new JButton[9];
public ChooseGame() {
setBackground(Color.RED);
setForeground(Color.BLACK);
setLayout(new GridLayout(3, 3));
createActions();
for (JButton button : buttons) {
add(button);
}
}
public void createActions() {
CardPresentable.Card cards[] = new CardPresentable.Card[] {
CardPresentable.Card.ONE,
CardPresentable.Card.TWO,
CardPresentable.Card.THREE,
CardPresentable.Card.FOUR,
CardPresentable.Card.FIVE,
CardPresentable.Card.SIX,
CardPresentable.Card.SEVEN,
CardPresentable.Card.EIGHT,
CardPresentable.Card.NINE
};
for (int index = 0; index < buttons.length; index++) {
ImageIcon icon = null;
if (index == 0 || index == 4 || index == 6 || index == 8) {
icon = icons[0];
} else if (index == 1 || index == 5 || index == 7) {
icon = icons[1];
} else if (index == 2) {
icon = icons[2];
} else if (index == 3) {
icon = icons[3];
}
JButton button = new JButton(icon);
button.setFocusPainted(false);
button.setContentAreaFilled(false);
button.setBorderPainted(false);
button.setBorder(null);
buttons[index] = button;
}
}
}
}
And one last thing...
static isn't your friend and, in the context you're trying to use it, isn't going to help you. Instead, you want to use a concept of "dependency injection", this is, you pass each class the information it needs to do it's job, in this case, that would be the CardPanel, BUT, I would be very cautious about passing a complex object, like a component to any body, I mean, they shouldn't be messing with the contents. In this case, what we want is to be notified when some state has changed. This is the bases for the "observer pattern" (you've already used this, Swing calls them listeners)
For example...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.setLayout(new GridBagLayout());
CardPane cardPane = new CardPane();
frame.add(new ChooseGame(cardPane));
frame.add(cardPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface CardPresentable {
enum Card {
ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE;
}
public void showCard(Card card);
}
public class CardPane extends JPanel implements CardPresentable {
private JLabel label;
public CardPane() {
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new BorderLayout());
label = new JLabel("Nothing");
add(label);
}
@Override
public void showCard(Card card) {
label.setText(card.name());
}
}
protected BufferedImage makeImage(String text) {
int size = 50;
BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.setColor(Color.LIGHT_GRAY);
Shape baseShape = new RoundRectangle2D.Double(0, 0, size - 1, size - 1, 10, 10);
g2d.fill(baseShape);
g2d.setColor(Color.DARK_GRAY);
g2d.draw(baseShape);
FontMetrics fm = g2d.getFontMetrics();
int x = (size - fm.stringWidth(text)) / 2;
int y = (size - fm.getHeight()) / 2;
g2d.setColor(Color.BLACK);
g2d.drawString(text, x, y + fm.getAscent());
g2d.dispose();
return img;
}
class ChooseGame extends JPanel {
private ImageIcon[] icons = new ImageIcon[]{
new ImageIcon(makeImage("1")),
new ImageIcon(makeImage("2")),
new ImageIcon(makeImage("3")),
new ImageIcon(makeImage("4"))
};
private JButton[] buttons = new JButton[9];
private CardPresentable cardPresentable;
public ChooseGame(CardPresentable cardPresentable) {
this.cardPresentable = cardPresentable;
setBackground(Color.RED);
setForeground(Color.BLACK);
setLayout(new GridLayout(3, 3));
createActions();
for (JButton button : buttons) {
add(button);
}
}
public CardPresentable getCardPresentable() {
return cardPresentable;
}
public void createActions() {
CardPresentable.Card cards[] = new CardPresentable.Card[]{
CardPresentable.Card.ONE,
CardPresentable.Card.TWO,
CardPresentable.Card.THREE,
CardPresentable.Card.FOUR,
CardPresentable.Card.FIVE,
CardPresentable.Card.SIX,
CardPresentable.Card.SEVEN,
CardPresentable.Card.EIGHT,
CardPresentable.Card.NINE
};
for (int index = 0; index < buttons.length; index++) {
ImageIcon icon = null;
if (index == 0 || index == 4 || index == 6 || index == 8) {
icon = icons[0];
} else if (index == 1 || index == 5 || index == 7) {
icon = icons[1];
} else if (index == 2) {
icon = icons[2];
} else if (index == 3) {
icon = icons[3];
}
JButton button = new JButton(icon);
button.setFocusPainted(false);
button.setContentAreaFilled(false);
button.setBorderPainted(false);
button.setBorder(null);
CardPresentable.Card card = cards[index];
button.addActionListener(new ActionHandler(getCardPresentable(), card));
buttons[index] = button;
}
}
protected class ActionHandler implements ActionListener {
private CardPresentable.Card card;
private CardPresentable cardPresentable;
public ActionHandler(CardPresentable cardPresentable, CardPresentable.Card card) {
this.card = card;
this.cardPresentable = cardPresentable;
}
public CardPresentable.Card getCard() {
return card;
}
public CardPresentable getCardPresentable() {
return cardPresentable;
}
@Override
public void actionPerformed(ActionEvent e) {
getCardPresentable().showCard(getCard());
}
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | MadProgrammer |



