Вопрос

Here is what I'm trying to do - making long story short: Building a window (will call him MainWindow) with buttons at top and a picture on the center of it. I want to give the user the options to chose what to do (the buttons) while changing the center picture every couple of sec. Part of the options given to the user is 'pause' and 'resume' - controlling the sequence. Basically trying to update GUI (MainWindow) by a Thread. This Thread will RUN WHILE boolean 'playSequence' will be true.

Can someone explain why can't I get it to work..

Here is the Code:

package SpecializedControls;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import DataEntities.SgiImage;

public class SgiImagePanel extends JPanel implements Runnable {
private List<SgiImage> seqImageList;
private JLabel lastImage;
private boolean playSequence;

public SgiImagePanel (){}

public SgiImagePanel (List<SgiImage> sequenceList)
{
seqImageList = sequenceList ;
}


@Override
public void run() {
    // TODO Auto-generated method stub

    while(playSequence)
    {
        for (SgiImage image : seqImageList) 
        {
            display(image);
            try {
                Thread.sleep(3000);
                } 
            catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                }
        }
    }       
}

public void display(SgiImage image)
{
    reset();
    JLabel picLabel = new JLabel(new ImageIcon(image.getImage())); 
    add(picLabel); 
    lastImage = picLabel;
}

public void display(List<SgiImage> sequenceList)
{   
    if(sequenceList==null)
        return;

    playSequence = true;
    SgiImagePanel seq = new SgiImagePanel(sequenceList);        
    Thread thread = new Thread(seq);
    thread.start();

}

public void reset(){
    if (lastImage != null)
    {
        remove(lastImage);
        lastImage = null;
    }
}

public void pause() {
    playSequence = false;
}

public void resume(){
    playSequence = true;
}


}
Это было полезно?

Решение

  1. Don't directly use Threads for this. There's no need, and it carries risk if you call code in a background thread that changes Swing state without care.
  2. Use a Swing Timer for your animation loop.
  3. Display your images as ImageIcons in a JLabel.
  4. One of the main problems with your code is that you keep creating a bunch of new JLabels needlessly and dangerously. One JLabel is all you need and all you want. So instead, create the image displaying JLabel just once and then swap icons via its setIcon(...) method.
  5. Read in your image Icon just once, and save it in a variable or collection.
  6. You can easily pause a Swing Timer by simply calling its stop() method, and can restart it just as easily by calling start().

Другие советы

Try to load the image with this code:

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class ImagePanel extends JPanel{

    private BufferedImage image;

    public ImagePanel() {
       try {                
          image = ImageIO.read(new File("image name and path"));
       } catch (IOException ex) {
            // handle exception...
       }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image, 0, 0, null); // see javadoc for more info on the parameters            
    }

}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top