小编典典

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

java

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



阅读 263

收藏
2020-11-30

共1个答案

小编典典

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

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

}

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

2020-11-30