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

互联网人!

我一直在为学校制作饮酒游戏程序。

//没有相关信息,仅适用于lulz:
//学校建议了游戏,我没有;)这是游戏// http://sotallytober.com/games/verbal/mexican/

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

public class iconPanel extends JPanel {

ImageIcon image;
Image pic;
public iconPanel(String startScreenImage) {
      image = new ImageIcon(startScreenImage);
      pic = image.getImage();
      this.setBackground(new Color(0, true));
}

@Override

public void paintComponent(Graphics g) {
    //Paint background first
    g.drawImage (pic, 0, 0, getWidth (), getHeight (), this);
}

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

private JPanel pnDrinkPlayerBW;

然后在同一个名为MakeComponents的类中的方法中,将JPanel设置为:

pnDrinkPlayerBW = new iconPanel("img/glass.jpg");
pnDrinkPlayerBW.setPreferredSize(new Dimension(183,61));

之后,我将其添加到必须到达的面板中,并将该面板添加到方法makeLayout()中的框架上(我认为这不是有用的代码,因此如果要查看它,请问我)

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

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..

因此,我想做的是在SpelScreen类中为iconPanel设置一个新图像,并使用spelscreen的相同实例对其进行重新绘制。

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

谢谢!

参考方案

首先,您忘记了在super.paintComponent方法中调用paintComponent。另外paintComponent应该是protected而不是public

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(..);
} 

其次,我认为您不想创建新的iconPanel并立即对其调用repaint。那可能什么都不做。

而是为您的setter输入一个pic,然后在该方法中添加repaint();

public void setPic(Image pic) {
    this.pic = pic;
    repaint();
}

然后,您可以从创建setPic的类中调用iconPanel。例如

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], ...);
}

然后,您可以更改imageIndexrepaint()
旁注

您应该使用Java命名约定。类名以大写字母表示,即iconPanelIconPanel
更新

使用ImageIcon

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

通过ExecutorService执行线程时Thread.join()不起作用 - java

这是我的代码:public static void main(String[] args) { System.out.println("program started"); ExecutorService executor = Executors.newCachedThreadPool(); Thread thread = new Thr…

Java:正则表达式模式匹配器是否有大小限制? - java

我的模式类似于OR:“word1 | word2 | word3”我大约有800个字。可能有问题吗? 参考方案 您仅受记忆和理智的限制。 :)

Java:线程池如何将线程映射到可运行对象 - java

试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …

JAVA:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…