- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试编写一个程序来创建 JPanel,当用户按下 W、A、S 和 D 时,绘制的立方体将在窗口中导航(每次按下某个键时都会导航一定量) Pressed),我创建了 MoveCubeUp 类,并重写了其中的 PaintComponent 方法,以便在调用该方法时重新绘制立方体,但它不起作用。有人能解释一下为什么吗?
public MyPanel(){
…
MoveSquareUp m=new MoveSquareUp(squareX, squareY);
getInputMap().put(KeyStroke.getKeyStroke(("W"), "pressed"));
getActionMap().put("pressed", m)
}
class MoveSquareUp extends AbstractAction{
public int squareXX, squareYY;
public moveSquare(){
squareXX=squareX+5;
}
//I define the paintComponent method to draw the rectangle with its set height
//at squareXX, squareYY
//action method is null (I am still trying to figure out binding keys to
//actions but the paintComponent not working is preventing that
}
如果格式不正确,我深表歉意。第 1 篇文章:/Paint 方法是否需要在扩展 JFrame 的类中定义,如果是这样,我如何将它与 AbstractAction 类一起使用(或者如何完全避免使用 AbstractAction 类)?
最佳答案
问题的关键是您需要学会将模型与 View 和控制分开。这里的模型是你的 Sprite 的位置, View 是绘制这个位置的GUI,控件将保存包括你的AbstractAction在内的 Action ,如果可能的话,它们都应该彼此分开。
所以回答你的直接问题——任何paintComponent绝对不应该不位于AbstractAction内部,因为前者是 View 的关键部分,而后者是控件的关键部分。相反,让您的 View 反射(reflect)模型的状态,并且模型的状态将由控件(操作)更改。
关于您的其他问题,所有绘画方法都应该是 JFrame 的一部分吗:所有绘画方法都不应该位于扩展 JFrame 的类中,因为此类是一个复杂的类,它创建一个顶级窗口和几个子组件来显示您的GUI,如果您覆盖其绘制,则可能会以不良方式影响子组件的绘制。而是在扩展 JPanel 的类的 PaintComponent 方法中进行绘制,然后在 JFrame 中显示该对象。
例如:
package pkg3;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
public class GamePanel extends JPanel {
private static final int ANIMATION_DELAY = 15;
private final int HEIGHT = 400;
private final int WIDTH = 600;
private Square square;
private EnumMap<Direction, Boolean> dirMap = new EnumMap<>(Direction.class);
private Map<Integer, Direction> keyToDir = new HashMap<>();
// !! private Circle circle;
private Timer animationTimer;
public GamePanel() {
for (Direction dir : Direction.values()) {
dirMap.put(dir, Boolean.FALSE);
}
keyToDir.put(KeyEvent.VK_UP, Direction.UP);
keyToDir.put(KeyEvent.VK_DOWN, Direction.DOWN);
keyToDir.put(KeyEvent.VK_LEFT, Direction.LEFT);
keyToDir.put(KeyEvent.VK_RIGHT, Direction.RIGHT);
setKeyBindings();
setBackground(Color.white);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setFocusable(true);
square = new Square();
animationTimer = new Timer(ANIMATION_DELAY, new AnimationListener());
animationTimer.start();
}
private void setKeyBindings() {
int condition = WHEN_IN_FOCUSED_WINDOW;
final InputMap inputMap = getInputMap(condition);
final ActionMap actionMap = getActionMap();
boolean[] keyPressed = { true, false };
for (Integer keyCode : keyToDir.keySet()) {
Direction dir = keyToDir.get(keyCode);
for (boolean onKeyPress : keyPressed) {
boolean onKeyRelease = !onKeyPress; // to make it clear how
// bindings work
KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode, 0, onKeyRelease);
Object key = keyStroke.toString();
inputMap.put(keyStroke, key);
actionMap.put(key, new KeyBindingsAction(dir, onKeyPress));
}
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
square.display(g);
}
private class AnimationListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent evt) {
boolean repaint = false;
for (Direction dir : Direction.values()) {
if (dirMap.get(dir)) {
square.move(dir);
repaint = true;
}
}
if (repaint) {
repaint();
}
}
}
private class KeyBindingsAction extends AbstractAction {
private Direction dir;
boolean pressed;
public KeyBindingsAction(Direction dir, boolean pressed) {
this.dir = dir;
this.pressed = pressed;
}
@Override
public void actionPerformed(ActionEvent evt) {
dirMap.put(dir, pressed);
}
}
private static void createAndShowGUI() {
GamePanel gamePanel = new GamePanel();
JFrame frame = new JFrame("GamePanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(gamePanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
gamePanel.requestFocusInWindow();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
enum Direction {
UP(0, -1), DOWN(0, 1), LEFT(-1, 0), RIGHT(1, 0);
private int incrX;
private int incrY;
private Direction(int incrX, int incrY) {
this.incrX = incrX;
this.incrY = incrY;
}
public int getIncrX() {
return incrX;
}
public int getIncrY() {
return incrY;
}
}
class Square {
private int x = 0;
private int y = 0;
private int w = 20;
private int h = w;
private int step = 1;
private Color color = Color.red;
private Color fillColor = new Color(255, 150, 150);
private Stroke stroke = new BasicStroke(3f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
public void display(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(fillColor);
g2d.fillRect(x, y, w, h);
g2d.setStroke(stroke);
g2d.setColor(color);
g2d.drawRect(x, y, w, h);
g2d.dispose();
}
public void setStep(int step) {
this.step = step;
}
public void move(Direction dir) {
x += step * dir.getIncrX();
y += step * dir.getIncrY();
}
}
关于java - PaintComponent() 可以在 AbstractAction 类中使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40295610/
我想在运行时将一系列 Swing 操作加载到容器中,并通过常量名称访问它们,就像使用枚举一样。这样做的目的是限制可能的操作并提高可读性。 最初,我正在考虑一种动态枚举(请参阅 http://blog.
我的要求是添加两个图标到抽象操作示例:图标 + 操作名称 + 图标AbstractAction 有一个 super 构造函数来仅添加一个图标 最佳答案 通过将操作标签设置为 HTML 解决了此问题 关
我有一个 JMenuItem 绑定(bind)到一个 Action,我可以使用 item.getAction() 获取它。 Action 名称在构造 Action 时设置,例如使用匿名 new Abs
请原谅这个模糊的问题标题,但通常我不会做这样的事情。所以我有以下问题: 我正在为特定应用程序设计一个弹出菜单,其中每个菜单项都与特定操作相关联: public class CanvasMenu ext
我正在尝试使用子类 ColorAction 来扩展 AbstractAction 类。此类处理 ActionPerformed 方法的方法是获取用户的字符串格式输入,并将其与 colorKey 中的
这个问题在这里已经有了答案: event handling in java and the execution of actionPerformed method in java (5 个答案) 关
我试图通过使用 Action 对象将我的 GUI 应用程序中的功能与状态分开。我已经成功地使用它们来创建具有相同功能的菜单项和按钮。 我的问题是:我想对菜单中的“退出”项和框架的关闭按钮执行相同的操作
在主视图/详细 View 中,我有一系列文本字段(以及一个或两个其他控件),它们都与当前所选项目的详细信息有关。它们都共享相同的 DocumentListener,因此如果您更改其中任何一个,将启用一
在一个简单的计算器应用程序中,我使用抽象操作来处理用鼠标单击的按钮以及按下的相应数字键盘键(带有键绑定(bind))。我希望在使用键盘时发生某些外观更改,例如当我按下数字 1 键时更改 JButton
我正在尝试编写一个程序来创建 JPanel,当用户按下 W、A、S 和 D 时,绘制的立方体将在窗口中导航(每次按下某个键时都会导航一定量) Pressed),我创建了 MoveCubeUp 类,并重
我正在制作一款游戏,用户必须按键才能移动。我正在使用键绑定(bind),但它们不起作用。键绑定(bind)应该调用 Wp 类并打印“W按下”,但没有任何反应。代码如下: public class SO
类AbstractAction实现接口(interface)Action,但是在Action中,有一个方法actionPerformed(ActionEvent e),它继承自接口(interface
好的。我有一个大型项目,其中一个特定的 jtable 在启动时创建并且永远不会重建。根据各种用户操作刷新表格模型并重绘表格。 我添加了一个自定义的 TableCellListener 类以响应单元格更
我遇到了一个奇怪的问题。由于在 GUI 中按下按钮,我需要将一些文本导出到文件中。但是,我无法将 IOException 应用于事件调用的 AbstractAction 的 actionPerform
通用代码... 出于某种原因,我的 JMenuItem 没有执行操作。 我做了一个框架,一个JMenuBar和一个JMenuItem,一切都在它应该在的地方。我可以很好地单击 JMenuItem,它会
如果您创建 AbstractActivity 子类,则必须定义以下方法: @Override public void start(AcceptsOneWidget panel, EventBus ev
我正在创建一个ToolBar与一个JButton和一些JCheckBox隐藏或显示 JTable 中的列. JButton主要目的是一旦点击重置所有其他JCheckBox在 ToolBar全部选中或全
通常需要根据另一个 GUI 对象的状态来更改其他 GUI 对象的行为。例如。按下按钮时,标签应更改其名称。但是,当我使用像 JButton myButton = new JButton(myButto
我的 java swing 应用程序有一些在两个 JMenuItems 中使用的 AbstractActions和 JButton。我想将其中一些放入 JButton 内的 JToolbar 中,但是
当我尝试使用 table.setValueAt() 粘贴到 JTable 单元格时,我粘贴的单元格保持空白,但是 setValueAt() 似乎在工作。此外,当我尝试从一个单元格中剪切或复制时,当我想
我是一名优秀的程序员,十分优秀!