当前位置: 首页 > 面试题库 >

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

包谭三
2023-03-14
问题内容

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


问题答案:
  • 您的游戏是“控制器”,它负责管理功能以及模型与视图之间的通信。
  • 您的视图应代表您的模型
  • 您的模型(可能还有您的视图)应该提供事件通知支持,控制器需要对其进行监视,以便管理需求和逻辑。

首先,您的代码混乱不堪。您正在充分利用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());
    }
}

而不是randomLetter每次调用getChar或时都调用convert它,只应在实际需要一个新字符时才使用它,否则您将永远不知道Tile字符的实际含义是/将要以什么开头。

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

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

没什么特别的,但这提供了一种方法,可以在删除a和实际删除Modela时提供通知。Tile``Tile

接下来,我对其进行了更新,Model以使其实际成为“模型”。在Model现在保持listTileS和用于添加和删除它们提供的功能。它还为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);
    }
}

接下来,我转到Game并对其进行了更新,以便将Tiles
添加到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());
}

作为概念证明…

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

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

}

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



 类似资料:
  • 问题内容: 我知道我可以使用KeyListener来检查是否按下DELETE ,但是如何在JTable中将keyListener添加到selectedRow? 编辑: 我已经尝试过了,但是没有用: 问题答案: KeyListeners的一个问题是,要侦听的组件 必须 具有焦点。解决此问题的一种方法是使用键绑定。 例如,

  • 问题内容: 如何禁用Android虚拟键盘中的某些键(例如数字/符号键)? 具体来说,当用户将焦点放在标准android EditText小部件上时,当虚拟键盘显示时,我希望用户不能输入双引号(“)字符。 问题答案: 如何禁用Android虚拟键盘中的某些键(例如数字/符号键)? 你不能,对不起。毕竟,输入法编辑器可能首先没有“键”。 具体来说,当用户将焦点放在标准android EditText

  • > 我已经尝试了所有的文本区功能,比如type=“email”等等,我无法让它在所有Android版本上都工作。 我已经安装了cordova插件ionic键盘,它显示的键盘没有任何建议(图A)。但当我轻触ion文本区域时,本机键盘会显示出来(图B)。 我如何解决这个问题,或者禁用本机键盘上的建议,或者让Cordova插件替换我的ion textarea的本机键盘,或者其他什么?谢谢 图像A 图像B

  • 我动态创建的PopupWindow包含EditText属性: 使用强制键盘显示: 显示键盘,但没有从键盘接收任何输入(即按下键不添加文本到文本编辑器)和文本编辑器被选中,因为我可以看到光标闪烁。 我已将Focusable设置为false,因为我不希望在弹出窗口外单击时关闭它。我怎样才能让键盘工作?

  • 问题内容: 我想检测用户是否按下了jQuery。 这怎么可能?需要插件吗? 编辑:看来我需要使用该方法。 我想知道是否有人知道该命令是否存在浏览器问题-就像我应该知道的浏览器兼容性问题一样? 问题答案: jQuery的全部要点是,您不必担心浏览器的差异。我很确定您可以放心在所有浏览器中都为13。因此,请记住这一点:

  • 在我的JPA POJO的中,我遇到了删除一些JSONObject键的问题。我只是不想让它们显示在中,同时将它们保存在POJO中,这样我就可以使用它们了。我可以设法在父实体中删除它们,但在子实体中无法这样做。下面是我在父实体中的实现。 我试图在我所有的子实体中做同样的事情。当我调用toString()时,仅在父实体中消失。它们仍然存在于儿童中。如何删除子实体中的一些键?谢谢你。