Java 如何使用鼠标事件切换图像?
我正在处理一个任务,当用户点击图像时,它会改变,一旦它通过timer类再次移动,图像就会切换回原始图像。到现在为止,我可以单击图像来更改它,但当再次移动时,它不会再更改。它移动后有没有办法换回来 这是我的密码 主要内容: 专家组:Java 如何使用鼠标事件切换图像?,java,image,swing,paintcomponent,mouselistener,Java,Image,Swing,Paintcomponent,Mouselistener,我正在处理一个任务,当用户点击图像时,它会改变,一旦它通过timer类再次移动,图像就会切换回原始图像。到现在为止,我可以单击图像来更改它,但当再次移动时,它不会再更改。它移动后有没有办法换回来 这是我的密码 主要内容: 专家组: import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Creature extends JPanel
{
private static final int DELAY=900;
private Random generator = new Random();
private ImageIcon image, image1;
private Timer timer;
private int x, y;
private int catchCount=0;
public Creature()
{
image = new ImageIcon ("pikachu.png");
image1 = new ImageIcon ("pokeball.png");
timer = new Timer(DELAY, new MoveListener());
x = generator.nextInt( 1900 );
y = generator.nextInt(1000);
addMouseListener (new MouseClickedListener());
setBackground (Color.green);
setPreferredSize(new Dimension(1900,1000));
timer.start();
}
//Draws the image.
public void paintComponent(Graphics page)
{
super.paintComponent(page);
image.paintIcon (this, page, x, y);
page.drawString("Pikachus Captured: " + catchCount, 10, 35);
setFont(new Font("Arial", Font.BOLD,35));
}
//Method for moving the image.
public void move()
{
timer.start();
x = generator.nextInt( 1900 );
y = generator.nextInt(1000);
if (timer.isRunning())
{
x = generator.nextInt( 1900 );
y = generator.nextInt(1000);
}
repaint();
}
//Method for getting the number of times caught.
public int getCatchCount()
{
return catchCount;
}
//Makes the image move
private class MoveListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
move();
repaint();
}
}
//Records when the user clicks the image.
private class MouseClickedListener extends MouseAdapter
{
public void mouseClicked(MouseEvent event)
{
if((event.getButton() == MouseEvent.BUTTON1) && between(event.getX(), x, x + image.getIconWidth()) && between(event.getY(), y, y + image.getIconHeight()))
{
System.out.println("CAUGHT ONE!");
catchCount++;
move();
image=image1;
}
}
}
private static boolean between(int x, int lower, int upper)
{
return (x >= lower) && (x <= upper);
}
}
import java.awt.*;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.util.Random;
导入javax.swing.ImageIcon;
导入javax.swing.JPanel;
导入javax.swing.Timer;
公共类生物扩展JPanel
{
专用静态最终整数延迟=900;
专用随机生成器=新随机();
私有图像图标图像,图像1;
私人定时器;
私有整数x,y;
私有int catchCount=0;
公共生物()
{
image=新的图像图标(“pikachu.png”);
image1=新的ImageIcon(“pokeball.png”);
定时器=新定时器(延迟,new MoveListener());
x=发电机。nextInt(1900);
y=发电机下一个(1000);
addMouseListener(新的MouseClickedListener());
挫折背景(颜色:绿色);
设置首选尺寸(新尺寸(19001000));
timer.start();
}
//绘制图像。
公共组件(图形页)
{
super.paintComponent(第页);
image.paintIcon(此,第页,x,y);
第页。拉丝(“捕获的皮卡丘斯:”+catchCount,10,35);
setFont(新字体(“Arial”,字体粗体,35));
}
//移动图像的方法。
公开作废动议()
{
timer.start();
x=发电机。nextInt(1900);
y=发电机下一个(1000);
if(timer.isRunning())
{
x=发电机。nextInt(1900);
y=发电机下一个(1000);
}
重新油漆();
}
//获取捕获次数的方法。
public int getCatchCount()
{
返回捕获计数;
}
//使图像移动
私有类MoveListener实现ActionListener
{
已执行的公共无效操作(操作事件)
{
move();
重新油漆();
}
}
//当用户单击图像时记录。
私有类MouseClickedListener扩展了MouseAdapter
{
公共void mouseClicked(MouseEvent事件)
{
if((event.getButton()==MouseEvent.BUTTON1)&&between(event.getX(),x,x+image.getIconWidth())&&between(event.getY(),y,y+image.getIconHeight())
{
System.out.println(“抓到一个!”);
catchCount++;
move();
图像=图像1;
}
}
}
私有静态布尔值介于(整数x、整数下限、整数上限)之间
{
return(x>=lower)&&(x我希望我能理解您试图实现的目标。首先,您需要3张图像:
private ImageIcon imageToDraw, image1, image2;
这个生物现在看起来像这样:
public Creature()
{
image1 = new ImageIcon ("pikachu.png");
image2 = new ImageIcon ("pokeball.png");
imageToDraw = image1;
...
}
在move()中,应将图像设置为image1:
public void move()
{
imageToDraw = image1;
timer.start();
x = generator.nextInt( 1900 );
...
}
不要忘记将图像更改为imageToDraw in paint():
从onclick事件中删除move();并在单击操作中将图像更改为imageToDrwa:
public void mouseClicked(MouseEvent event)
{
if((event.getButton() == MouseEvent.BUTTON1) && between(event.getX(), x, x + image.getIconWidth()) && between(event.getY(), y, y + image.getIconHeight()))
{
System.out.println("CAUGHT ONE!");
catchCount++;
//move(); should be removed
imageToDraw=image1;
}
}
编辑:move();已从onclick事件中删除。您需要一种方法来绘制任一图像。现在您只需将Image
指定给image1
,执行此操作时,来自“pikachu.png”
的图像将消失
无需进行太多重构,您只需制作一个要绘制的标志:
/* as a field */
private boolean justCaptured;
现在你必须稍微改变一下你的绘画逻辑:
if (justCaptured) {
image1.paintIcon (this, page, x, y);
} else {
image.paintIcon (this, page, x, y);
}
现在,您要做的第一件事不是重新分配图像
,而是将标志设置为true:
System.out.println("CAUGHT ONE!");
catchCount++;
justCaptured = true;
move();
最后需要做的一件事是在下一次绘制时将标志设置回false。有一些不同的方法可以实现这一点,但我认为在不重构的情况下,最简单的方法是将其排队等待以后:
System.out.println("CAUGHT ONE!");
catchCount++;
justCaptured = true;
move();
SwingUtilities.invokeLater(new Runnable() {
@Override public void run() {
justCaptured = false;
}
});
使用invokeLater将在EventQueue结束时将其排队,并且在先前排队的任务完成后将对其进行更改。因此,在鼠标事件退出后,以及在您刚刚在移动中请求的重新绘制之后
“我把所有这些都贴出来,以防有人想就其他事情或一般性问题提供建议。”
- 您正在调用
timer。在move
中启动,这似乎不是必需的。默认情况下,计时器会重复
move
生成x
和y
两次。由于在构造函数中调用timer.start
,timer.isRunning
将始终为真
MoveListener
在调用move
之后调用repaint
,但是move
也调用repaint
“如果人们愿意,也可以自己测试。”
我们无法运行它,因为我们没有您的图像。如果您想发布它,我们可以运行它,请更改代码,使其在没有图像的情况下工作。否则,我们必须自行更改。下面是一个返回空白图像图标的静态方法:
public static ImageIcon createBlankIcon(int w, int h, Color color) {
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
g2d.setColor(color);
g2d.fillRect(0, 0, w, h);
g2d.dispose();
return new ImageIcon(img);
}
你可以用类似的东西来代替内容,例如:image=getBlankIcon(50,50,Color.RED);
而不是发布你所有的代码(以及你声称有效的大量代码),为什么不发布你试图做你解释过的事情的代码呢?你说它不会变回来是什么意思?你是说取消移动吗?既然我是一个noob,我还是会发布所有的代码,以防有人想就其他事情提供建议。如果人们愿意的话,也可以自己测试。这是一个移动的pika随机移动的pikachu,当用户单击它时,会显示pokeball的图像,但只有在它再次移动之前才会显示。单击它时,还会记录它被捕获的次数。当它再次移动时,pikachu将显示,直到再次单击为止。那么,你有什么问题吗?非常感谢Johnny!我这样做并采取了移动();在点击事件之外,它工作得很好。现在,pickachu在一个pokeball中被捕获(它现在显示这个以及输出amou)
System.out.println("CAUGHT ONE!");
catchCount++;
justCaptured = true;
move();
SwingUtilities.invokeLater(new Runnable() {
@Override public void run() {
justCaptured = false;
}
});
public static ImageIcon createBlankIcon(int w, int h, Color color) {
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
g2d.setColor(color);
g2d.fillRect(0, 0, w, h);
g2d.dispose();
return new ImageIcon(img);
}