简体   繁体   English

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

[英]How to remove a JLabel when I click a certain key on the keyboard?

So I have a GUI, a Tile class and a method class. 因此,我有一个GUI,一个Tile类和一个方法类。 I created four tiles in my Game class which consists of Tiles that has contains a letter and a color in each of them. 我在Game类中创建了四个图块,这些图块由图块组成,每个图块中都包含一个字母和一个颜色。 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 . 现在,我想创建一个方法,当我单击键盘上的某个键到图块上该特定字母时,它将删除Tile。 How would I go about that? 我将如何处理? Do I create that method in my model class and call it in my Game(GUI) class? 是否在模型类中创建该方法并在Game(GUI)类中调用它?


  • 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. 您的模型(可能还有您的视图)应该提供事件通知支持,您的控制器将需要对其进行监视,以便管理需求和逻辑。

To start with, you code is in mess. 首先,您的代码混乱不堪。 You are making to much use of static and it's not going to help you. 您正在大量使用static ,它不会帮助您。

For example, I re-worked your Tile class to look more like this. 例如,我重新设计了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());
    }
}

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 相反然后调用randomLetter每次调用时getCharconvert ,你应该只使用它时,你确实需要一个新的角色,否则你永远不知道什么Tile的性格实际上是/是开始

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

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. 没什么特别的,但是这提供了一种手段Model时提供通知Tile被除去, Tile实际上已被删除。

Next, I updated the Model so that it actual "models" something. 接下来,我更新了Model ,以使其实际成为“模型”。 The Model now maintains a list of Tile s and provides functionality for adding and removing them. 现在, Model维护了Tilelist ,并提供了添加和删除它们的功能。 It also provides support for the ModelListener and event triggering 它还提供对ModelListener和事件触发的支持

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

Next, I went to the Game and updated it so it adds Tile s to the Model and uses the Model data to setup the UI. 接下来,我进入Game并对其进行了更新,以便将Tile添加到Model并使用Model数据来设置UI。 It then registers the KeyListener and ModelListener 然后,它注册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();
}

And finally, the keyTyped event now asks the Model to remove a Tile of the given key... 最后, keyTyped事件现在要求Model删除给定键的Tile ...

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

}

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 根据一般经验, 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<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());
        }
    }

}

See How to Use Key Bindings for more details. 有关更多详细信息,请参见如何使用键绑定

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM