Usypianie wyświetlania obrazka

0

Witam!
Mam za zadanie napisać program, który będzie wyświetlał obrazek z danego katalogu i po pięciu sekundach będzie wyświetlał kolejny. Generalnie wszystko spoko tylko najwidoczniej źle używam usypiania i nie działa poprawnie.
Oto kod:

import java.awt.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;;

public class Zadanie_3 extends JPanel{
	
	Image img;
	String directory;
	
	public void paintComponent(Graphics g){
        super.paintComponent(g);
        File[] plikObrazka = {new File("C:/Users/dell/Downloads/PJWSTK/pjwstk.jpg"), 
        		new File("C:/Users/dell/Downloads/PJWSTK/panda3.jpg"), 
        		new File("C:/Users/dell/Downloads/PJWSTK/java.jpg")};
        try{
        	for(int i = 0 ; i < plikObrazka.length ; i++){
        		img = ImageIO.read(plikObrazka[i]);
        		g.drawImage(img, 0, 0, getWidth(), getHeight(), null);
        	}
    		try{
    			Thread.sleep(500);
    		} catch (Exception e){}
        } catch (IOException e) {
        	System.err.println("Blad odczytu obrazka");
        	e.printStackTrace();
        }
		repaint(500);
	}
	
	public Dimension getPreferredSize(){
        return new Dimension(300, 300);
    }
	
	public static void main(String[] args){
		
		JFrame frame = new JFrame("Rysowanie ");//utworzenie okna ramowego
        Zadanie_3 graph  = new Zadanie_3(); //utworzenie panelu do rysowania
        frame.getContentPane().add(graph); //dodanie panelu do okna ramowego
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //obsługa zamkniecia okna
        frame.setLocation(300, 300);
        frame.pack(); //upakowanie okna
        frame.show(); //wyswietlenie okna na ekranie
		
	}
}

Zdaję sobie sprawę ze da się zrobić to na kilka innych sposobów żeby było lepiej.

0

Repaint wywoływane z paintComponent jest zawsze złym pomysłem. Bardzo złym pomysłem jest też czytanie obrazków w metodzie paintComponent. Najprostsze rozwiązanie to Timer, który co pół sekundy podmienia obrazek i wywołuje repaint. W metodzie paintComponent powinny zostać dwie instrukcje:

super.paintComponent(g);
if(img != null)
{
     g.drawImage(img,0,0,getWidth(),getHeight(),null);
}

Nie używaj też (przestarzałej od Javy 1.1) metody show, zastąp przez setVisible(true).

0

Wcześniej nie używałem Timer'a i pewnie źle to zrobiłem...

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;;

public class Zadanie_3 extends JPanel{
	
	Image img;
	String directory;
	
	public void wczytajObrazek(){
		int delay = 500; 
		  ActionListener taskPerformer = new ActionListener() {
		      public void actionPerformed(ActionEvent evt) {
		    	  File[] plikObrazka = {new File("C:/Users/dell/Downloads/PJWSTK/pjwstk.jpg"), 
		          		new File("C:/Users/dell/Downloads/PJWSTK/panda3.jpg"), 
		          		new File("C:/Users/dell/Downloads/PJWSTK/java.jpg")};
		          try{
		          	for(int i = 0 ; i < plikObrazka.length ; i++){
		          		img = ImageIO.read(plikObrazka[i]);
		          		repaint();
		          	}
		          } catch (IOException e) {
		          	System.err.println("Blad odczytu obrazka");
		          	e.printStackTrace();
		          }
		      }
		  };
		  new Timer(delay, taskPerformer).start();
		  repaint();
		  
	}
	
	public void paintComponent(Graphics g){
        super.paintComponent(g);
        wczytajObrazek();
		g.drawImage(img, 0, 0, getWidth(), getHeight(), null);  
	}
	
	public Dimension getPreferredSize(){
        return new Dimension(300, 300);
    }
	
	public static void main(String[] args){
		
		JFrame frame = new JFrame("Rysowanie ");//utworzenie okna ramowego
        Zadanie_3 graph  = new Zadanie_3(); //utworzenie panelu do rysowania
        frame.getContentPane().add(graph); //dodanie panelu do okna ramowego
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //obsługa zamkniecia okna
        frame.setLocation(300, 300);
        frame.pack(); //upakowanie okna
        frame.setVisible(true); //wyswietlenie okna na ekranie
		
	}
}

jakaś pomoc?

0

Nadal czytasz (pośrednio) obrazki w metodzie paintComponent.
Wewnątrz actionPerformed nie może być czytania obrazków, musi być natomiast repaint().

1

Przykładowy kod, (rysunki wyświetlane są w kółko):

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;;
 
public class Zadanie3 extends JPanel
{ 
    Image[] images;
    Image img;
    String[] fileNames = {"C:/Users/dell/Downloads/PJWSTK/pjwstk.jpg", 
                          "C:/Users/dell/Downloads/PJWSTK/panda3.jpg", 
                          "C:/Users/dell/Downloads/PJWSTK/java.jpg"};                      
    int whichImage = 0;

    public Zadanie3()
    {
        setPreferredSize(new Dimension(300,300));
        wczytajObrazki();
        ActionListener taskPerformer = new ActionListener() 
        {
            public void actionPerformed(ActionEvent evt) 
            {
                img = images[whichImage];
                whichImage = (whichImage+1)%images.length;
                repaint();
            }
        };
        int delay = 500; 
        new Timer(delay, taskPerformer).start();        
    }
    private void wczytajObrazki()
    {
        images = new Image[fileNames.length];
        for(int i=0;i<fileNames.length;i++)
        {
            try
            {
                images[i] = ImageIO.read(new File(fileNames[i]));
            }
            catch(Exception e)
            {
                System.out.println(e+" "+fileNames[i]);
            }
        }
    }    
 
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.drawImage(img, 0, 0, getWidth(), getHeight(), null);
    }
 
    public static void main(String[] args)
    {
 
        JFrame frame = new JFrame("Rysowanie ");//utworzenie okna ramowego
        Zadanie3 graph  = new Zadanie3(); //utworzenie panelu do rysowania
        frame.add(graph); //dodanie panelu do okna ramowego
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //obsługa zamkniecia okna
        frame.setLocationRelativeTo(null);
        frame.pack(); //upakowanie okna
        frame.setVisible(true); //wyswietlenie okna na ekranie
 
    }
}
0

I teraz wszystko super dzięki wiekie.
Jedno pytanie ten fragment

img = images[whichImage];
                whichImage = (whichImage + 1) % 3;

dokładnie % 3
zabezpieczenie przed wyjątkiem ponieważ są 3 obrazki w katalogu dlatego dzielone % 3?
dobrze rozumiem?

0

W tym wierszu była mała usterka, powinno być raczej

whichImage = (whichImage+1)%images.length;

Rozumiesz prawie dobrze, % to reszta z dzielenia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1