Java 如何在不使用新JFrame的情况下更改JPanel中的图像(Repaint()不起作用!)

Java 如何在不使用新JFrame的情况下更改JPanel中的图像(Repaint()不起作用!),java,swing,jframe,jpanel,repaint,Java,Swing,Jframe,Jpanel,Repaint,我一直在为学校做一个饮酒游戏项目 //这就是游戏//http://sotallytober.com/games/verbal/mexican/ 无论如何,我使用以下代码在JPanel中绘制了一个图像(它是一个扩展JPanel的类) 现在在我的另一个类中,我在我的JPanel上声明了布局和所有组件,如下所示: private JPanel pnDrinkPlayerBW; 然后,在同一类中名为MakeComponents的方法中,我将JPanel设置为: pnDrinkPlayerBW = ne

我一直在为学校做一个饮酒游戏项目

//这就是游戏//http://sotallytober.com/games/verbal/mexican/

无论如何,我使用以下代码在JPanel中绘制了一个图像(它是一个扩展JPanel的类)

现在在我的另一个类中,我在我的JPanel上声明了布局和所有组件,如下所示:

private JPanel pnDrinkPlayerBW;
然后,在同一类中名为MakeComponents的方法中,我将JPanel设置为:

pnDrinkPlayerBW = new iconPanel("img/glass.jpg");
pnDrinkPlayerBW.setPreferredSize(new Dimension(183,61));
之后,我将它添加到面板中它必须出现的位置,并将该面板添加到方法makeLayout()中的框架中(我认为它不是有用的代码,因此如果您想查看它,请询问我)

然后,如果按下按钮,我想将glass.jpg图像更改为另一个图像,例如beerGlass0.png,因此在另一个方法actionEvents()中的actionlistener中,我执行以下操作:

pnDrinkPlayerBW = new iconPanel("img/beerGlass.png");
pnDrinkPlayerBW.setPreferredSize(new Dimension(183,61));
pnDrinkPlayerBW.repaint();
如果人们需要的话,我也会把这个类的构造函数放在这里:

public SpelScreen(){
    makeComponents();
    makeLayout();
    actionEvents();
} // note : this is'nt the full constructor, just the call for the methods I talked          about, SpelScreen extends JFrame..
所以我想做的是,在SpelsScreen类中为iconPanel设置一个新图像,并使用SpelsScreen的相同实例重新绘制它

我对Java非常陌生,所以不要指望我能快速理解复杂的代码:)


谢谢

首先,您忘记在
paintComponent
方法中调用
super.paintComponent
。另外,
paintComponent
应该受到
保护
而不是
公共

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(..);
} 
其次,我认为您不想创建一个新的
iconPanel
,并立即调用repaint。那可能没什么用

相反,为您的
pic
设置一个
setter
,然后只需
repaint()在该方法中

public void setPic(Image pic) {
    this.pic = pic;
    repaint();
}
然后,您可以从中创建
iconPanel
的类中调用
setPic
。比如说

iconPanel panel = new iconPanel("...");
... // then in some listener
public void actionPerformed(ActionEvent e) {
    Image pic = null;
    try {
        pic = ImageIO.read(...);
        panel.setPic(pic);
    } catch ...
}

另一种选择是只在
iconPanel
中初始化一组图像。然后,在侦听器中,如果图像数组调用repaint,则只需更改索引即可。像这样的

Image[] images = new Image[5];
int imageIndex = 0;
// fill the array with images

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(images[imageIndex], ...);
}
然后您只需更改
imageIndex
repaint()


旁注

您应该使用Java命名约定。类名用大写字母表示,即
iconPanel
→ <代码>图标面板


更新

使用
ImageIcon

public void setImage(ImageIcon img) {
    pic = img.getImage();
    repaint();
}

你忘了在你的
paintComponent
方法中调用
super.paintComponent
。你的意思是这样的?public void paintComponent(Graphics g){super.paintComponent(g);g.drawImage(pic,0,0,getWidth(),getHeight(),this);非常感谢!但仍然没有什么问题。首先,ImageIO.read(URL)不起作用,所以我使用ImageIcon image=new ImageIcon(URL);但是,Panel.setImage(image)给出了一个错误“方法未定义”很抱歉,修复起来可能很容易。如果您想这样做,那么
setImage
方法应该使用
ImageIcon
而不是
Image
作为参数,然后您需要使用
pic=
Image.getImage()`在方法中。你明白了吗?请参阅底部的mt UPDATE;是的,但我认为它无法从IconPanel访问该方法..错误:“方法setImage(ImageIcon)对于类型JPanel是未定义的”(我已将setImage的方法设置为ImageIcon,然后我将其制作成一个图像,所以这不是问题)您不能执行此操作
JPanel panel=new iconPanel
。它必须是
iconPanel panel=new iconPanel
。执行第一个操作时,您仅限于
JPanel
的方法,而不是
iconPanel
public void setImage(ImageIcon img) {
    pic = img.getImage();
    repaint();
}