Java 动作事件_Java-paintComponent中的MouseListener动作事件

有关当前代码的一些建议:

>监视类命名方案,即testclass应该是TestClass或更好的Test(但是多数民众赞成在挑剔).所有班级名称均以大写字母开头,之后的每个新单词均以大写字母表示.

>不要不必要地扩展JFrame.

>不要在JFrame上调用setBounds,而是使用适当的LayoutManager和/或重写JPanel的getPreferredSize()并返回适合其内容的尺寸.

>始终在JFrame上调用pack(),然后再将其设置为可见(考虑以上内容).

>使用MouseAdapter和MouseListener

>不要在paintComponent中调用moveBall()而不是在您的Timer中调用它,它会重新绘制屏幕,??这不仅会改善设计,而且我们也不应该在paint方法中执行长时间运行的任务.

至于您的问题,我认为您的逻辑有点歪斜.

一种方法是将Rectangle(或Rectangle2D)替换为其自己的自定义类(这将使我们能够存储颜色等属性).您的球也将拥有自己的类,该类具有moveBall()方法及其属性(如x和y position等).在每个repaint()上,JPanel都会调用该方法来移动球,JPanel本身可以包装moveBall()在它自己的公共方法中,我们可以从重新绘制屏幕的计时器中调用它.

这是已实现上述修复的代码示例(请分析它,如果有任何问题让我知道):

import java.awt.*;

import java.awt.event.*;

import java.awt.geom.Ellipse2D;

import java.awt.geom.Rectangle2D;

import java.util.ArrayList;

import javax.swing.*;

public class Test {

private MyPanel p;

private Timer t;

public Test() {

JFrame frame = new JFrame();

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

initComponents();

frame.add(p);

frame.pack();

frame.setVisible(true);

t.start();

}

private void initComponents() {

final ActionListener action = new ActionListener() {

@Override

public void actionPerformed(ActionEvent evt) {

p.moveEntities();//moves ball etc

p.repaint();

}

};

t = new Timer(50, action);

p = new MyPanel();

p.addMouseListener(new MouseAdapter() {

@Override

public void mouseClicked(MouseEvent e) {

p.addEntity(e.getX(), e.getY(), 10, 50, Color.GREEN);

System.out.println("clicked");

}

});

p.setBackground(Color.WHITE);

}

public static void main(String args[]) {

SwingUtilities.invokeLater(new Runnable() {

@Override

public void run() {

new Test();

}

});

}

}

class MyPanel extends JPanel {

int width = 300, height = 300;

ArrayList entities = new ArrayList<>();

MyBall ball = new MyBall(10, 10, 25, 25, Color.RED, width, height);

void addEntity(int x, int y, int w, int h, Color c) {

entities.add(new MyRectangle(x, y, w, h, c));

}

void moveEntities() {

ball.moveBALL();

}

@Override

protected void paintComponent(Graphics grphcs) {

super.paintComponent(grphcs);

Graphics2D g2d = (Graphics2D) grphcs;

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

g2d.setColor(ball.getColor());

g2d.fillOval((int) ball.x, (int) ball.y, (int) ball.width, (int) ball.height);

for (MyRectangle entity : entities) {

g2d.setColor(entity.getColor());

g2d.fillRect((int) entity.x, (int) entity.y, (int) entity.width, (int) entity.height);

}

}

@Override

public Dimension getPreferredSize() {

return new Dimension(width, height);

}

}

class MyRectangle extends Rectangle2D.Double {

Color color;

public MyRectangle(double x, double y, double w, double h, Color c) {

super(x, y, w, h);

color = c;

}

public void setColor(Color color) {

this.color = color;

}

public Color getColor() {

return color;

}

}

class MyBall extends Ellipse2D.Double {

int xspeed = 1;

int yspeed = 1;

Color color;

private final int maxWidth;

private final int maxHeight;

public MyBall(double x, double y, double w, double h, Color c, int maxWidth, int maxHeight) {

super(x, y, w, h);

color = c;

this.width = w;//set width and height of Rectangle2D

this.height = h;

//set max width and height ball can move

this.maxWidth = maxWidth;

this.maxHeight = maxHeight;

}

public void setColor(Color color) {

this.color = color;

}

public Color getColor() {

return color;

}

void moveBALL() {

x = x + xspeed;

y = y + yspeed;

if (x < 0) {

x = 0;

xspeed = -xspeed;

} else if (x > maxWidth - ((int) getWidth() / 2)) {// i dont like hard coding values its not good oractice and resuaibilty is diminshed

x = maxWidth - ((int) getWidth() / 2);

xspeed = -xspeed;

}

if (y < 0) {

y = 0;

yspeed = -yspeed;

} else if (y > maxHeight - ((int) getHeight() / 2)) {

y = maxHeight - ((int) getHeight() / 2);

yspeed = -yspeed;

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值