Java 帧刷新问题

Java 帧刷新问题,java,swing,Java,Swing,我正在尝试创建一个带有更改图片的面板。 这是我的小组: public class AdvertisementPanel extends JPanel { private BufferedImage image; private ArrayList<String> pictures; private int index = 0; public AdvertisementPanel(String... pics) { pictures = new ArrayList<Strin

我正在尝试创建一个带有更改图片的面板。 这是我的小组:

public class AdvertisementPanel extends JPanel {
private BufferedImage image;

private ArrayList<String> pictures;
private int index = 0;

public AdvertisementPanel(String... pics) {
pictures = new ArrayList<String>(Arrays.asList(pics));
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
 new Runnable() {
  @Override
  public void run() {
   changeImage();
  }
}, 0, 5, TimeUnit.SECONDS);

}

public void paint(Graphics g) {
 g.drawImage(image, 0, 0, null);
}

private void changeImage() {
 String name = pictures.get(index);
try {
 File input = new File(name);
 image = ImageIO.read(input);
 index++;
 index %= pictures.size();
} catch (IOException ie) {
 Logger.getLogger().log(Level.SEVERE,
  "No adds found in given path: " + name);
}
}
公共类广告面板扩展了JPanel{
私有缓冲图像;
私人ArrayList图片;
私有整数指数=0;
公共广告面板(字符串…图片){
pictures=newarraylist(Arrays.asList(pics));
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
新的Runnable(){
@凌驾
公开募捐{
changeImage();
}
},0,5,时间单位为秒);
}
公共空间涂料(图g){
g、 drawImage(image,0,0,null);
}
私有void changeImage(){
字符串名称=pictures.get(索引);
试一试{
文件输入=新文件(名称);
图像=图像IO.read(输入);
索引++;
index%=pictures.size();
}捕获(IOIE){
Logger.getLogger().log(Level.SEVERE,
“在给定路径中未找到添加项:”+名称);
}
}
我有一个固定面板的框架,但没有显示任何图片。 试图周期性地从帧中重新绘制-导致了一些有趣但不想要的结果。。。
知道为什么吗?我做错了什么?我应该如何刷新框架的组件?

每次更改图像时都需要重新绘制

哦,这应该由swing事件处理线程完成:

Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
 new Runnable() {
  @Override
  public void run() {
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        changeImage();
        repaint();
       }
    };
  }
}, 0, 5, TimeUnit.SECONDS);
更新以更正其他一些问题

public class AdvertisementPanel extends JPanel {
    private BufferedImage image;
    private ArrayList<String> pictures;
    private int index = 0;

    public AdvertisementPanel(String... pics) {
        pictures = new ArrayList<String>(Arrays.asList(pics));
        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
            new Runnable() {
                @Override
                public void run() {
                    changeImage();
                }
            }, 0, 5, TimeUnit.SECONDS);
    }

    private void changeImage() {
        final BufferedImage img = nextImage();
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                image = img;
                repaint();
            }
        });
    }

    public void paint(Graphics g) {
        if (image != null) {
            g.drawImage(image, 0, 0, null);
        }
    }

    private BufferedImage nextImage() {
        String name = pictures.get(index);
        try {
            index++;
            index %= pictures.size();
            File input = new File(name);
            return ImageIO.read(input);
        } catch (IOException ie) {
            Logger.getLogger("").log(Level.SEVERE,
                    "No adds found in given path: " + name);
            return null;
        }
    }
}
公共类广告面板扩展了JPanel{
私有缓冲图像;
私人ArrayList图片;
私有整数指数=0;
公共广告面板(字符串…图片){
pictures=newarraylist(Arrays.asList(pics));
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
新的Runnable(){
@凌驾
公开募捐{
changeImage();
}
},0,5,时间单位为秒);
}
私有void changeImage(){
最终缓冲区图像img=nextImage();
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
图像=img;
重新油漆();
}
});
}
公共空间涂料(图g){
如果(图像!=null){
g、 drawImage(image,0,0,null);
}
}
私有缓冲区映像下一个映像(){
字符串名称=pictures.get(索引);
试一试{
索引++;
index%=pictures.size();
文件输入=新文件(名称);
返回图像读取(输入);
}捕获(IOIE){
Logger.getLogger(“”.log(Level.SEVERE,
“在给定路径中未找到添加项:”+名称);
返回null;
}
}
}

如何操作?我没有图形对象。它对于帧是恒定的吗?或者可能会偶尔更改?您可能不想在EDT上执行文件I/O。感谢各位的评论。Maurice-我使用了您的代码,它开始得很好,但在5秒后(在第二次迭代中…)画框被重新粉刷过,弄得乱七八糟…为什么?没关系-发现了问题..超级。画图(g)缺少..谢谢大家,非常有用的
repaint
可能就是答案。但我只想指出,您应该覆盖
paintComponent
而不是
paint
。此外,您还可以扩展
JComponent
而不是
JPanel
(有些僵尸会扩展
JPanel
,因为它为您调用
setOpaque(true);
(想想这项工作吧!),只有
JPanel
不会(如果您觉得有冒险精神,可以查看源代码或API文档),但是一些PL&Fs可能会。而且
image
应该是
易失的
,或者很好地将其传递给EDT。