所以我有一个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和实际删除Model
a时提供通知。Tile``Tile
接下来,我对其进行了更新,Model
以使其实际成为“模型”。在Model
现在保持list
的Tile
S和用于添加和删除它们提供的功能。它还为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
并对其进行了更新,以便将Tile
s
添加到Model
并使用Model
数据来设置UI。然后注册KeyListener
和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
事件现在要求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());
}
}
}
有关更多详细信息,请参见如何使用键绑定。
Windows上 只给某一个键盘 改键 的 软件或方案 购买某个可编程键盘,使用自带的软件可以实现.但是需要花钱. 搜索过类似的软件,但目前没有找到可以只给一个键盘改键的功能,都是全局键盘修改 linux上可以实现这一点,但是我需要在Windows上实现这一点.目前正在思考套娃的可能性
问题内容: 我知道我可以使用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。因此,请记住这一点: