java - 单击按钮时移动卡住
问题描述
创建了一个类似于绘图的程序,其中有一个矩形,其在屏幕内的移动可以通过“w、a、s、d”键控制,并使用鼠标上的滚动条增加或减小其大小。还有几个不同颜色的按钮,按下时会用各自的颜色填充矩形。现在的问题是在单击任何颜色按钮后停止移动,即。矩形不动。您可以增加和减少它的大小,但不能使用“w,a,s,d”键移动。请帮帮我。
而且作为一个可选请求,我也在尝试用这个矩形进行绘画,即。当我按下空格键时,我想填充在指定区域选择的颜色。现在即使我能做到。我做的下一个动作,即。按“w、a、s、d”键或滚动条,颜色会消失。现在我知道颜色或 fillRect() 必须以某种方式保存,以便下一个操作不会影响它,但我尝试了几种方法但没有发生。我已经评论了下面这幅画的代码。
我的第一个请求是我的主要请求,如果您无法理解我的意思或不知道解决方案,请留下第二个请求。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Animation extends Frame implements KeyListener,MouseWheelListener,ActionListener {
int x,y,a,b;
char choice1;
int draw=1;
int n=0;
int color1,color2,color3;
Button button1,button2,button3,button4,button5,button6,button7,button8,button9,button10;
Animation() {
setSize(1000, 1000);
setVisible(true);
x = 500;
y = 500;
a = 20;
b = 50;
addKeyListener(this);
addMouseWheelListener(this);
JFrame frame = new JFrame();
frame.getContentPane().setLayout(null);
button1 = new Button("Black");
button2 = new Button("Blue");
button3 = new Button("Green");
button4 = new Button("Orange");
button5 = new Button("Red");
button6 = new Button("Yellow");
button7 = new Button("Gray");
button8 = new Button("Cyan");
button9 = new Button("Magenta");
button10 = new Button("Pink");
add(button1);add(button2);add(button3);add(button4);add(button5);
add(button6);add(button7);add(button8);add(button9);add(button10);
button1.setBounds(50,680,50,20); button2.setBounds(120,680,50,20);
button3.setBounds(190,680,50,20); button4.setBounds(260,680,50,20);
button5.setBounds(330,680,50,20); button6.setBounds(400,680,50,20);
button7.setBounds(470,680,50,20); button8.setBounds(540,680,50,20);
button9.setBounds(610,680,50,20); button10.setBounds(680,680,50,20);
button1.addActionListener(this);button2.addActionListener(this);
button3.addActionListener(this);button4.addActionListener(this);
button5.addActionListener(this);button6.addActionListener(this);
button7.addActionListener(this);button8.addActionListener(this);
button9.addActionListener(this);button10.addActionListener(this);
addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
});
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
choice1 = e.getKeyChar();
if (choice1 == 'w') {
y = y - 10;
}
if (choice1 == 's') {
y = y + 10;
}
if (choice1 == 'a') {
x = x - 10;
}
if (choice1 == 'd') {
x = x + 10;
}
if(choice1 == ' '){
draw=2;
}
repaint();
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
double p = e.getPreciseWheelRotation();
if(p>0){
a=a+5;
b=b+5;
} else{
a=a-5;
b=b-5;
}
repaint();
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("Black")){
color1 = 0;
color2 = 0;
color3 = 0;
}
if(e.getActionCommand().equals("Blue")){
color1 = 0;
color2 = 0;
color3 = 255;
}
if(e.getActionCommand().equals("Green")){
color1 = 0;
color2 = 255;
color3 = 0;
}
if(e.getActionCommand().equals("Orange")){
color1 = 255;
color2 = 165;
color3 = 0;
}
if(e.getActionCommand().equals("Red")){
color1 = 255;
color2 = 0;
color3 = 0;
}
if(e.getActionCommand().equals("Yellow")){
color1 = 255;
color2 = 255;
color3 = 0;
}
if(e.getActionCommand().equals("Gray")){
color1 = 169;
color2 = 169;
color3 = 169;
}
if(e.getActionCommand().equals("Cyan")){
color1 = 0;
color2 = 255;
color3 = 255;
}
if(e.getActionCommand().equals("Magenta")){
color1 = 255;
color2 = 0;
color3 = 255;
}
if(e.getActionCommand().equals("Pink")){
color1 = 255;
color2 = 192;
color3 = 203;
}
repaint();
}
public void paint(Graphics g) {
if(draw==1) {
g.drawRect(x, y, a, b);
g.setColor(new Color(color1,color2,color3));
g.fillRect(x,y,a,b);
}
// if(draw==2){
// fillColor(g);
// draw=1;
// }
}
// public void fillColor(Graphics g){
// g.setColor(Color.red);
// int[] temp1 = new int[50];
// temp1[n] = x;
// int[] temp2 = new int[50];
// temp2[n] = y;
// int[] temp3 = new int[50];
// temp3[n] = a;
// int[] temp4 = new int[50];
// temp4[n] = b;
//
//
// n++;
// for (int i=0;i<n;i++){
// System.out.println("abcd");
// g.fillRect(temp1[n],temp2[n],temp3[n],temp4[n]);
// }
//
// }
public static void main(String[] args) {
Animation animation = new Animation();
}
}
解决方案
首先是基本的设计问题:
不要扩展框架。无需扩展任何类。
不要在 Swing 应用程序中使用 AWT 组件。
JFrame
是摇摆。“按钮”是 AWT。对于 Swing,您应该使用JButton
.不要对整个框架使用空布局。保留默认的 BorderLayout。阅读 Swing 教程中有关如何使用 BorderLayout的部分。
对于按钮,您应该创建一个 JPanel(默认情况下使用 FlowLayout)并将您的按钮添加到此面板。
然后使用以下方法将此面板添加到框架中:
frame.add(buttonPanel, BorderLayout.PAGE_END);
- 自定义绘画是通过扩展完成的
JPanel
,然后您覆盖该paintComponent(...)
方法。所以你需要创建一个DrawingPanel
来绘制你的矩形。阅读有关自定义绘画的 Swing 教程以获取工作示例,以帮助您更好地构建代码。
然后使用以下命令将绘图面板添加到框架:
frame.add(drawingPanel, BorderLayout.CENTER):
- 不要使用 WindowListener 来关闭框架。
创建框架时,您可以设置 close 属性:
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- 使用多个嵌套的 if 语句,就像您在 ActionListner 中所做的那样是糟糕的设计。随着您继续支持更多颜色,代码只会不断增长。另一种方法可能是:
a) 创建一个 HashMap 作为实例变量来包含按钮和颜色:
private HashMap<JButton, Color> buttonColors = new HashMap<>();
private Color rectangleColor = Color.BLACK;
b)现在,当您创建每个按钮时,您可以更新哈希图:
buttonColors.put(button1, Color.BLACK);
c) 现在您的 ActionListener 中的代码变为:
JButton button = (JButton)e.getSource();
Color color = buttonColors.get(button);
rectangleColor = color;
repaint();
d) 并且您的 paintComponent() 方法中的代码变为:
//g.setColor(new Color(color1,color2,color3));
g.setColor( rectangleColor );
- 不要通过蛮力创建按钮。创建一个方法。
调用方法的代码
buttonsPanel.add( createButton("Black", Color.BLACK) );
buttonsPanel.add( createButton("Blue", Color.BLUE) );
该createButton(..)
方法看起来像:
public JButton (String text, Color color)
{
JButton button = new JButton( text );
button.addActionListener(this);
buttonColors.put(button, color);
return button;
}
这里有很多建议。代码在未经测试的情况下发布,因此请了解每个概念并一次更改一个并进行测试以确保您正确实施每个步骤。
现在的问题是在单击任何颜色按钮后停止移动,即。矩形不动。
KeyEvent 仅传递给具有焦点的组件。当您单击按钮时,绘画面板失去焦点并且不再响应事件。
更好的解决方案是使用Key Bindings
. 即使组件没有焦点,键绑定也会起作用。有关更多信息和工作示例,请参阅:使用键盘进行运动。
推荐阅读
- excel - 使用 msxmlhttp60 设置“表变量”中的 Excel vba 问题
- python - 当我单击提交按钮时,我的数据库中没有任何显示
- environment - Xcode 12:面板中的环境覆盖设置未反映在模拟器上
- java - 如何让我的用户界面自我适应 JPanel 的显示和隐藏?
- python - 为什么python web应用程序的前端会抛出异常?
- python - Tweepy:你如何检查一条推文是否被收藏?
- scala - 如何使用 sbt-native-packager 设置 Docker Registry
- node.js - 不捕获快速启动异常
- python-3.x - 使用 numpy 使用 python 进行数据分析。使用 Matplotlib 绘制图形
- python - 如何删除答案(正文中的代码)?