单击键盘上的某个键时如何删除JLabel?

所以我有一个GUI,一个Tile类和一个方法类。 我在我的Game类中创建了四个tile,它由Tiles组成,每个都包含一个字母和一个颜色。 我现在想要创建一种方法,当我单击键盘上的某个键到瓷砖上的特定字母时,它将删除Tile。 我该怎么办呢? 我是否在我的模型类中创建该方法并在我的游戏(GUI)类中调用它?


  • 您的游戏是“控制器”,它负责管理模型和视图之间的function和通信。
  • 您的视图应该是您的模型的表示
  • 您的模型(可能还有您的视图)应该提供控制器需要监视的事件通知支持,以便管理需求和逻辑。

首先,你的代码很乱。 你正在大量使用static ,它不会帮助你。

例如,我重新处理你的Tile类看起来更像这样。

 public class Tile extends JLabel { public static Font font = new Font("Serif", Font.BOLD, 39); private char _c; public Tile(char c, Color background) { setBackground(background); setOpaque(true); _c = c; setText(convert()); } public static char randomLetter() { Random r = new Random(); char randomChar = (char) (97 + r.nextInt(25)); return randomChar; } public char getChar() { return _c; } public String convert() { return String.valueOf(getChar()); } } 

而不是每当你调用getCharconvert时调用getChar ,你应该只在你真正需要一个新角色时使用它,否则你永远不会知道Tile的角色究竟是什么/是什么开始

接下来,我们需要某种模式的观察者契约,因此它可以告诉我们什么时候发生了变化。

 public interface ModelListener { public void tileWasRemoved(Tile tile); } 

这没有什么特别之处,但是这为Model提供了一种方法,可以在删除Tile并实际删除Tile时提供通知。

接下来,我更新了Model以便实际“模拟”某些东西。 Model现在维护一个Tile list ,并提供添加和删除它们的function。 它还为ModelListener和事件触发提供支持

 public class Model { private ArrayList list = new ArrayList(); private List listeners = new ArrayList<>(25); public Model() { } public void addModelListener(ModelListener listener) { listeners.add(listener); } public void removeModelListener(ModelListener listener) { listeners.remove(listener); } protected void fireTileRemoved(Tile tile) { for (ModelListener listener : listeners) { listener.tileWasRemoved(tile); } } public void removeByChar(char value) { Iterator iterator = list.iterator(); while (iterator.hasNext()) { Tile tile = iterator.next(); if (value == tile.getChar()) { fireTileRemoved(tile); iterator.remove(); } } } private void add(Tile tile) { list.add(tile); } private Iterable getTiles() { return Collections.unmodifiableList(list); } } 

接下来,我进入Game并更新它,以便将Tile添加到Model并使用Model数据来设置UI。 然后它注册KeyListenerModelListener

 public Game() { model = new Model(); model.add(new Tile(Tile.randomLetter(), Color.WHITE)); model.add(new Tile(Tile.randomLetter(), Color.RED)); model.add(new Tile(Tile.randomLetter(), Color.GREEN)); model.add(new Tile(Tile.randomLetter(), Color.YELLOW)); JFrame frame = new JFrame(); frame.getContentPane().setLayout(new GridLayout(4, 1)); frame.setSize(500, 800); frame.setVisible(true); for (Tile tile : model.getTiles()) { frame.add(tile); } model.addModelListener(new ModelListener() { @Override public void tileWasRemoved(Tile tile) { frame.remove(tile); frame.revalidate(); frame.repaint(); } }); frame.getContentPane().addKeyListener(this); frame.getContentPane().setFocusable(true); frame.getContentPane().requestFocusInWindow(); } 

最后, keyTyped事件现在要求Model移除给定键的Tile

 @Override public void keyTyped(KeyEvent e) { model.removeByChar(e.getKeyChar()); } 

作为概念certificate……

 import java.awt.Color; import java.awt.EventQueue; import java.awt.Font; import java.awt.GridLayout; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Random; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class Game implements KeyListener { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } new Game(); } }); } private Model model; public Game() { model = new Model(); model.add(new Tile(Tile.randomLetter(), Color.WHITE)); model.add(new Tile(Tile.randomLetter(), Color.RED)); model.add(new Tile(Tile.randomLetter(), Color.GREEN)); model.add(new Tile(Tile.randomLetter(), Color.YELLOW)); JFrame frame = new JFrame(); frame.getContentPane().setLayout(new GridLayout(4, 1)); frame.setSize(500, 800); frame.setVisible(true); for (Tile tile : model.getTiles()) { frame.add(tile); } model.addModelListener(new ModelListener() { @Override public void tileWasRemoved(Tile tile) { frame.remove(tile); frame.revalidate(); frame.repaint(); } }); frame.getContentPane().addKeyListener(this); frame.getContentPane().setFocusable(true); frame.getContentPane().requestFocusInWindow(); } @Override public void keyPressed(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) { } @Override public void keyTyped(KeyEvent e) { model.removeByChar(e.getKeyChar()); } public interface ModelListener { public void tileWasRemoved(Tile tile); } public class Model { private ArrayList list = new ArrayList(); private List listeners = new ArrayList<>(25); public Model() { } public void addModelListener(ModelListener listener) { listeners.add(listener); } public void removeModelListener(ModelListener listener) { listeners.remove(listener); } protected void fireTileRemoved(Tile tile) { for (ModelListener listener : listeners) { listener.tileWasRemoved(tile); } } public void removeByChar(char value) { Iterator iterator = list.iterator(); while (iterator.hasNext()) { Tile tile = iterator.next(); if (value == tile.getChar()) { fireTileRemoved(tile); iterator.remove(); } } } private void add(Tile tile) { list.add(tile); } private Iterable getTiles() { return Collections.unmodifiableList(list); } } public static class Tile extends JLabel { public static Font font = new Font("Serif", Font.BOLD, 39); private char _c; public Tile(char c, Color background) { setBackground(background); setOpaque(true); _c = c; setText(convert()); } public static char randomLetter() { Random r = new Random(); char randomChar = (char) (97 + r.nextInt(25)); return randomChar; } public char getChar() { return _c; } public String convert() { return String.valueOf(getChar()); } } } 

怎么样……

作为一般的经验法则, KeyListener很难处理,你应该使用键绑定API,例如

 import java.awt.AWTKeyStroke; import java.awt.Color; import java.awt.EventQueue; import java.awt.Font; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Random; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.KeyStroke; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class Game { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } new Game(); } }); } private Model model; public Game() { model = new Model(); model.add(new Tile(Tile.randomLetter(), Color.WHITE)); model.add(new Tile(Tile.randomLetter(), Color.RED)); model.add(new Tile(Tile.randomLetter(), Color.GREEN)); model.add(new Tile(Tile.randomLetter(), Color.YELLOW)); JFrame frame = new JFrame(); frame.getContentPane().setLayout(new GridLayout(4, 1)); frame.setSize(500, 800); frame.setVisible(true); for (Tile tile : model.getTiles()) { frame.add(tile); KeyStroke ks = KeyStroke.getKeyStroke(tile.getChar()); String name = "typed." + tile.getChar(); Action action = new TileAction(model, tile.getChar()); registerKeyBinding((JComponent)frame.getContentPane(), name, ks, action); } model.addModelListener(new ModelListener() { @Override public void tileWasRemoved(Tile tile) { frame.remove(tile); frame.revalidate(); frame.repaint(); } }); } public void registerKeyBinding(JComponent parent, String name, KeyStroke ks, Action action) { InputMap im = parent.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); ActionMap am = parent.getActionMap(); im.put(ks, name); am.put(name, action); } public class TileAction extends AbstractAction { private Model model; private char value; public TileAction(Model model, char value) { this.model = model; this.value = value; } @Override public void actionPerformed(ActionEvent e) { model.removeByChar(value); } } public interface ModelListener { public void tileWasRemoved(Tile tile); } public class Model { private ArrayList list = new ArrayList(); private List listeners = new ArrayList<>(25); public Model() { } public void addModelListener(ModelListener listener) { listeners.add(listener); } public void removeModelListener(ModelListener listener) { listeners.remove(listener); } protected void fireTileRemoved(Tile tile) { for (ModelListener listener : listeners) { listener.tileWasRemoved(tile); } } public void removeByChar(char value) { Iterator iterator = list.iterator(); while (iterator.hasNext()) { Tile tile = iterator.next(); if (value == tile.getChar()) { fireTileRemoved(tile); iterator.remove(); } } } private void add(Tile tile) { list.add(tile); } private Iterable getTiles() { return Collections.unmodifiableList(list); } } public static class Tile extends JLabel { public static Font font = new Font("Serif", Font.BOLD, 39); private char _c; public Tile(char c, Color background) { setBackground(background); setOpaque(true); _c = c; setText(convert()); } public static char randomLetter() { Random r = new Random(); char randomChar = (char) (97 + r.nextInt(25)); return randomChar; } public char getChar() { return _c; } public String convert() { return String.valueOf(getChar()); } } } 

有关更多详细信息,请参见如何使用键绑定 。