[英]Else if only displays the last panel
我已經建立了一個巨大的游戲項目。 我正在使用CardLayout
來顯示何時在JLabel
上釋放鼠標。 我讓它在其他類的JLabels
上工作,但是當我按下JLabel
時,它只顯示CardLayout
的最后一個JPanel
。 我希望它顯示我設置的特定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) {
}
}
}
發生了很多事情,嗯,充其量是有問題的,例如……
public ChooseGame() {
//...
addMouseListener(handler);
addMouseMotionListener(handler);
//...
}
public void buttons() {
game1.addMouseListener(handler);
game1.addMouseMotionListener(handler);
//...
}
現在, ChooseGame
和每個單獨的 label 都附加了一個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);
}
您正在將事件點與每個標簽位置進行比較,在我的測試中,每個 label 都為contains
檢查返回true
。
為什么不只比較事件的source
if (e.getSource() == game1) {...}
我什至不會問為什么你需要每秒重復檢查一次或者為什么你使用static
引用CardPanel
- 切換卡片不是ChooseGame
的責任,相反,它應該通知CardPanel
一些 state發生了變化, CardPanel
應該決定如何響應該變化。
但是,讓我們關注最初的問題。
我們可以專注於創建一個“處理程序”,而不是使用單個Handler
程序,它可以為每個單獨的 label 或最好是所需的結果進行自定義,例如......
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;
}
}
}
}
}
但是,這對使用標簽的決定提出了更多問題,為什么?
JLabels 有更多的風格選擇
真的,在哪些方面? 什么值得犧牲一個按鈕的核心功能,它的唯一職責就是在用戶選擇它時告訴你? 為什么要花費所有時間重新創建該功能?
例如,其中一個使用 label,另一個使用按鈕
你能說出區別嗎? 不要相信我,沒關系,我不會。 其中一張圖片是從上面的代碼生成的,另一張是從這段代碼生成的……
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;
}
}
}
}
static
不是您的朋友,在您嘗試使用它的上下文中,它不會幫助您。 相反,您想使用“依賴注入”的概念,也就是說,您向每個 class 傳遞完成其工作所需的信息,在這種情況下,這將是CardPanel
,但是,我會非常謹慎地傳遞一個復雜的 object,就像任何身體的一個組成部分,我的意思是,他們不應該弄亂內容。 在這種情況下,我們想要的是在某些 state 發生變化時得到通知。 這是“觀察者模式”的基礎(你已經用過了,Swing 稱它們為監聽器)
例如...
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());
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.