我已經建立了一個巨大的游戲專案。我使用CardLayout來顯示滑鼠在JLabel. 我讓它在其他課程上作業JLabels,但是當我按 aJLabel時,它只顯示最后JPanel一個CardLayout. 我希望它顯示JPanel我設定的具體內容。
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) {
}
}
}
uj5u.com熱心網友回復:
發生了很多事情,嗯,充其量是有問題的,例如......
public ChooseGame() {
//...
addMouseListener(handler);
addMouseMotionListener(handler);
//...
}
public void buttons() {
game1.addMouseListener(handler);
game1.addMouseMotionListener(handler);
//...
}
現在,theChooseGame和每個單獨的標簽都MouseListener附有一個,為什么?這可能導致事件的雙重觸發
然后...
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);
}
您正在將事件點與每個標簽位置進行比較,在我的測驗中,每個標簽都回傳true檢查contains??。
為什么不只是比較source事件的
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());
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/457794.html
下一篇:無法從罐子中打開擺動窗
