单击键盘上的某个键时如何删除JLabel? [英] How to remove a JLabel when I click a certain key on the keyboard?

查看:101
本文介绍了单击键盘上的某个键时如何删除JLabel?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So I have a GUI, a Tile class and a method class. I created four tiles in my Game class which consists of Tiles that has contains a letter and a color in each of them. I now want to create a method where when I click a key on my keyboard to that specific letter on the tile, it will remove the Tile . How would I go about that? Do I create that method in my model class and call it in my Game(GUI) class?

推荐答案


  • 您的游戏是控制器,它负责管理模型和视图之间的功能和通信。

  • 您的视图应该是模型的表示

  • 您的模型(可能还有您的视图)应该提供控制器需要监视的事件通知支持,以便管理需求和逻辑。 / li>

    • Your game is the "controller", it's responsible for managing the functionality and communication between the model and view.
    • Your view should be a representation of your model
    • Your model (and possibly your view) should be providing event notification support, to which you controller will need to monitor, in order to manage the requirements and logic.
    • 首先,你的代码很乱。你正在大量使用 static 而且它不会帮助你。

      To start with, you code is in mess. You are making to much use of static and it's not going to help you.

      例如,我重新使用 Tile 类看起来更像这样。

      For example, I re-worked your Tile class to look more like this.

      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());
          }
      }
      

      而不是调用 randomLetter 每次调用 getChar 转换时,您应该只在实际需要时使用它一个新角色,否则你永远不会知道 Tile 的角色实际上是/是以

      Rather then calling randomLetter each time you called getChar or convert, you should only be using it when you actually need a new character, otherwise you'll never know what the Tile's character actually is/was to begin with

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

      Next, we need some kind of observer contract for the mode, so it can tell us when things have changed, for example.

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

      这没什么特别的,但这为模型在删除 Tile 并且实际删除 Tile 时提供通知。

      It's nothing special, but this provides a means for the Model to provide notification when a Tile is removed and which Tile was actually removed.

      接下来,我更新了模型,以便实际模拟某些东西。 模型现在维护一个列表 Tile s并提供添加和删​​除它们的功能。它还支持 ModelListener 和事件触发

      Next, I updated the Model so that it actual "models" something. The Model now maintains a list of Tiles and provides functionality for adding and removing them. It also provides support for the ModelListener and event triggering

      public class Model {
      
          private ArrayList<Tile> list = new ArrayList<Tile>();
          private List<ModelListener> 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<Tile> 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<Tile> getTiles() {
              return Collections.unmodifiableList(list);
          }
      }
      

      接下来,我去了游戏并更新它,以便将 Tile 添加到模型并使用模型用于设置UI的数据。然后注册 KeyListener ModelListener

      Next, I went to the Game and updated it so it adds Tiles to the Model and uses the Model data to setup the UI. It then registers the KeyListener and ModelListener

      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 事件现在要求模型删除给定密钥的 Tile ...

      And finally, the keyTyped event now asks the Model to remove a Tile of the given key...

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

      作为概念证明......

      As a proof of concept...

      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<Tile> list = new ArrayList<Tile>();
              private List<ModelListener> 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<Tile> 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<Tile> 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,例如

      How ever...

      As a general rule of thumb, KeyListener is a pain to work with and you should be making use of the key bindings API instead, for example

      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<Tile> list = new ArrayList<Tile>();
              private List<ModelListener> 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<Tile> 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<Tile> 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());
              }
          }
      
      }
      

      参见< a href =http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html\"rel =nofollow>如何使用密钥绑定以获取更多详细信息。

      See How to Use Key Bindings for more details.

      这篇关于单击键盘上的某个键时如何删除JLabel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆