gpt4 book ai didi

Java - PaintComponent 中的 MouseListener Action 事件

转载 作者:行者123 更新时间:2023-12-04 05:17:34 25 4
gpt4 key购买 nike

这里我有一个代码,它使用paintComponent在mouseClicked位置绘制一个矩形。我可以获得输出消息,但任何与图形和.draw()相关的东西都不起作用。

代码:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public final class testclass extends JFrame {

static JPanel p;
Timer t;
int x = 1;
int y = 1;
int xspeed = 1;
int yspeed = 1;

public testclass() {
initComponents();
this.setBounds(100, 300, 500, 500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
t.start();
this.add(p);
}

public void initComponents() {
final ActionListener action = new ActionListener() {

public void actionPerformed(ActionEvent evt) {
System.out.println("Hello!");
p.repaint();
}
};

t = new Timer(50, action);
p = new JPanel() {

public void paintComponent(Graphics g) {
super.paintComponent(g);
final Graphics2D gD = (Graphics2D) g;
moveBALL();
gD.drawOval(x, y, 25, 25);

p.addMouseListener(new MouseListener() {

@Override
public void mouseReleased(MouseEvent e) {
System.out.println("a");
}

@Override
public void mousePressed(MouseEvent e) {
System.out.println("b");
}

@Override
public void mouseExited(MouseEvent e) {
System.out.println("c");
}

@Override
public void mouseEntered(MouseEvent e) {
System.out.println("d");
}

@Override
public void mouseClicked(MouseEvent e) {
gD.drawRect(e.getX(), e.getY(), 10, 60);
gD.setColor(Color.green);
System.out.println("clicked");
}
});
}

void moveBALL() {
x = x + xspeed;
y = y + yspeed;
if (x < 0) {
x = 0;
xspeed = -xspeed;
} else if (x > p.getWidth() - 20) {
x = p.getWidth() - 20;
xspeed = -xspeed;
}
if (y < 0) {
y = 0;
yspeed = -yspeed;
} else if (y > p.getHeight() - 20) {
y = p.getHeight() - 20;
yspeed = -yspeed;
}
}
};
}

public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new testclass().setVisible(true);
p.setBackground(Color.WHITE);
}
});
}
}

在这个程序中实现 mouseListener() 的正确方法是什么?
谢谢。

最佳答案

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

  • 观察类命名方案,即 testclass应该是 TestClass甚至更好Test (但那是挑剔)。所有类名都以大写字母开头,之后的每个新词都大写。
  • 不要扩展JFrame不必要的。
  • 不要调用setBoundsJFrame而是使用适当的LayoutManager和/或覆盖 getPreferredSize()JPanel并返回适合其内容的尺寸。
  • 随时调用pack()JFrame在将其设置为可见之前(考虑到上述情况)。
  • 使用MouseAdapter对比 MouseListener
  • 不要调用moveBall()paintComponent而是在您的 Timer 中调用它重新绘制屏幕,​​不仅设计稍微好一点,而且我们也不应该在绘制方法中执行可能长时间运行的任务。

  • 至于你的问题,我认为你的逻辑有点歪曲。

    一种方法是看到 Rectangle (或 Rectangle2D )被它自己的自定义类替换(这将允许我们存储颜色等属性)。你的球也会有自己的类,它有方法 moveBall()。及其属性如 xy位置等。在每个 repaint()您的 JPanel会调用方法来移动球, JPanel本身可以包装 moveBall()在它自己的公共(public)方法中,我们可以从重绘屏幕的计时器中调用它。

    这是一个实现了上述修复的代码示例(请分析它,如果您有任何问题,请告诉我):

    enter image description here
    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<MyRectangle> 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;
    }
    }
    }

    关于Java - PaintComponent 中的 MouseListener Action 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14068472/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com