|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Oct 2007
Messaggi: 364
|
[ Applet Java ] Scorrimento Immagini - Genymus
Salve, avrei bisogno di una applet java che faccia scorrere orrizzontalmente verso destra una serie di immagini in continuazione ripartendo dalla prima quando le ha visualizzate tutte.
Grazie Genymus
__________________
Genymus!!! "Che cosa vorreste far incidere sulla vostra tomba?". "Torno fra 5 minuti." "Lucido" è quando credi soltanto a metà di ciò che ti dicono. "Brillante" è quando sai a quale metà credere. "Pensa, ogni volta che respiro muore un uomo." "Hai provato a fare qualcosa per l'alito?" Aforismieaforismi.it |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Si tratta semplicemente di usare un offset per spostare l'origine degli assi tra un'invocazione e l'altra di:
Codice:
for(int i = 0; i < maxFramesPerPage; i++) { g.drawImage(frames[i], offsetX, 0, null); } L'offset varia da 0 a -frames[0].getWidth() (supponendo che frames sia un array di BufferedImage). Quando l'offset raggiunge -frames[0].getWidth() fai scorrere il vettore a sinistra e aggiungi tante immagini quante sono necessarie a riempire nuovamente lo schermo. Nulla di particolarmente esotico. |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Oct 2007
Messaggi: 364
|
penso di aver capito...
può postarmi il codice completo?
__________________
Genymus!!! "Che cosa vorreste far incidere sulla vostra tomba?". "Torno fra 5 minuti." "Lucido" è quando credi soltanto a metà di ciò che ti dicono. "Brillante" è quando sai a quale metà credere. "Pensa, ogni volta che respiro muore un uomo." "Hai provato a fare qualcosa per l'alito?" Aforismieaforismi.it |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Come no, eccolo qua.
Codice:
import java.util.concurrent.*; import java.util.concurrent.atomic.*; import javax.imageio.*; import java.io.*; import java.net.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import javax.swing.*; import java.util.*; public class SlideApplet extends JApplet { private final Screen SCREEN = new ScreenImpl(); private void initializeUI() { add(SCREEN.getComponent()); String speedValue = getParameter("speed"); if(speedValue != null) { try { SCREEN.setSpeed(Float.parseFloat(speedValue)); } catch(NumberFormatException ex) { System.err.println("speed property " + speedValue + " not a float. Using default."); } } try { URL list = new URL(getCodeBase() + "/" + getParameter("imagelist")); SCREEN.setImages(list); SCREEN.start(); System.out.println("screen on line"); } catch(MalformedURLException ex) { System.err.println("whops, wrong url!"); ex.printStackTrace(); } } public void init() { EventQueue.invokeLater(new Runnable() { public void run() { initializeUI(); } }); } public void stop() { SCREEN.stop(); } } interface Screen { void setSpeed(float value); void setImages(URL pathListUrl); void start(); void stop(); JComponent getComponent(); } class Ticker { private long then; private long tick; public void start() { then = System.nanoTime(); } public void update() { long now = System.nanoTime(); tick = (now - then) / 1000000; then = now; } public long getTick() { return tick; } } class ScreenImpl extends JPanel implements Screen { private final ActionListener LOOP = new ActionListener() { public void actionPerformed(ActionEvent e) { slide(); } }; private final javax.swing.Timer ANIMATOR = new javax.swing.Timer(5, LOOP); private final CopyOnWriteArrayList<String> IMAGES = new CopyOnWriteArrayList<String>(); private final ImageLoader IMAGE_LOADER = new ImageLoaderImpl(); private final AtomicInteger OFFSET_X = new AtomicInteger(); private final AtomicInteger NEXT_IMAGE = new AtomicInteger(); private final AtomicBoolean WAITING_LOAD = new AtomicBoolean(); private volatile float speed = 0.05f; /** edt fields */ private final Ticker TICKER = new Ticker(); private final LinkedList<BufferedImage> FRAMES = new LinkedList<BufferedImage>(); public void setSpeed(float value) { if(value < 0.01f) { System.err.println(value + " too low"); } else { speed = value; } } public void setImages(final URL pathListUrl) { if(pathListUrl == null) { System.err.println("ScreenImpl, method setImages, url is null"); return; } Thread runner = new Thread() { public void run() { try { LinkedList<String> list = new LinkedList<String>(); Scanner in = new Scanner(pathListUrl.openStream()); while(in.hasNextLine()) { list.add(in.nextLine()); } setImages(list); } catch(IOException ex) { return; } } }; runner.setDaemon(true); runner.start(); } public void setImages(Collection<String> paths) { stop(); IMAGES.clear(); IMAGES.addAll(paths); OFFSET_X.set(0); NEXT_IMAGE.set(0); start(); } public JComponent getComponent() { return this; } private void slide() { TICKER.update(); int paintSize = OFFSET_X.get() - getWidth(); for(int i = 0; i < FRAMES.size(); i++) { paintSize += FRAMES.get(i).getWidth(); } if(paintSize <= getWidth()) { loadNextFrame(); } else { int delta = -(int)Math.round(speed * TICKER.getTick()); if(OFFSET_X.addAndGet(delta) + FRAMES.get(0).getWidth() <= 0) { OFFSET_X.set(0); FRAMES.remove(0); } repaint(); } } private void loadNextFrame() { if(IMAGES.size() == 0) { return; } if(WAITING_LOAD.get()) { return; } WAITING_LOAD.set(true); URL address = getClass().getResource(IMAGES.get(NEXT_IMAGE.get())); IMAGE_LOADER.submit(new LoadImage(address, getGraphicsConfiguration()) { public void run() { FRAMES.add(getImage()); WAITING_LOAD.set(false); } }); if(address != null) { if(NEXT_IMAGE.incrementAndGet() == IMAGES.size()) { NEXT_IMAGE.set(0); } } } protected void paintComponent(Graphics graphics) { super.paintComponent(graphics); Graphics2D g = (Graphics2D)graphics; graphics.translate(OFFSET_X.get(), 0); int x = 0; for(BufferedImage image : FRAMES) { int y = getHeight() / 2 - image.getHeight() / 2; graphics.drawImage(image, x, y, null); x += image.getWidth(); } } public void start() { TICKER.start(); ANIMATOR.start(); } public void stop() { IMAGE_LOADER.stop(); ANIMATOR.stop(); } } abstract class LoadImage implements Runnable { private final URL ADDRESS; private final GraphicsConfiguration GC; private BufferedImage image; LoadImage(URL address, GraphicsConfiguration gc) { ADDRESS = address; GC = gc; } URL getAddress() { return ADDRESS; } GraphicsConfiguration getGC() { return GC; } synchronized void setImage(BufferedImage image) { this.image = image; } synchronized BufferedImage getImage() { return image; } } interface ImageLoader { void submit(LoadImage task); void stop(); } class ImageLoaderImpl implements ImageLoader{ private LinkedBlockingQueue<LoadImage> TASK_QUEUE = new LinkedBlockingQueue<LoadImage>(); private final AtomicBoolean RUN = new AtomicBoolean(false); private Thread runner; private synchronized void setRunner(Thread t) { runner = t; } private synchronized Thread getRunner() { return runner; } public void stop() { Thread t = getRunner(); if(t != null) { t.interrupt(); } RUN.set(false); } public void submit(LoadImage task) { if(RUN.get() == false) { RUN.set(true); setRunner(new Thread() { public void run() { loop(); } }); getRunner().start(); } for(LoadImage i : TASK_QUEUE) { if(i.getAddress().equals(task.getAddress())) return; } TASK_QUEUE.offer(task); } private void loop() { while(RUN.get()) { try { execute(TASK_QUEUE.take()); } catch(InterruptedException ex) { return; } } } private void execute(LoadImage task) { try { System.out.println("loading " + task.getAddress()); BufferedImage image = ImageIO.read(task.getAddress()); task.setImage(optImage(image, task.getGC())); EventQueue.invokeLater(task); } catch(IOException ex) { ex.printStackTrace(); } } private BufferedImage optImage(BufferedImage source, GraphicsConfiguration gc) { if(gc == null) { return source; } else { BufferedImage opt = gc.createCompatibleImage(source.getWidth(), source.getHeight(), source.getTransparency()); Graphics2D g = opt.createGraphics(); g.drawImage(source, 0, 0, null); g.dispose(); source.flush(); return opt; } } } |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Oct 2007
Messaggi: 364
|
Salve, la compilazione funziona alla perfezione...
mi può dire anche il codice html per i parametri? Grazie
__________________
Genymus!!! "Che cosa vorreste far incidere sulla vostra tomba?". "Torno fra 5 minuti." "Lucido" è quando credi soltanto a metà di ciò che ti dicono. "Brillante" è quando sai a quale metà credere. "Pensa, ogni volta che respiro muore un uomo." "Hai provato a fare qualcosa per l'alito?" Aforismieaforismi.it |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
l'applet richiede due parametri, uno è speed l'altro è imagelist.
Il valore di speed è numerico ed esprime la velocità dello scorrimento delle immagini in pixel al millisecondo. Il valore di imagelist è il percorso relativo di un file di testo. Questo file di testo contiene un elenco di percorsi relativi di file immagini (png, jpg, gif, bmp per la piattaforma standard Java SE 5+). Ogni linea di testo nel file contiene un percorso di immagine. Ad esempio il file potrebbe essere: Codice:
/immagini/thumb001.png /immagini/thumb002.png /immagini/thum003.png /immagini/thum004.png Codice:
<applet code="SlideApplet.class" width="400" height="400"> <param name="speed" value="0.05"> <param name="magelist" value="/list.txt"> </applet> |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Ho testato l'applet in linea, il caricamento delle immagini è ok ma c'è una valutazione ottimistica della banda in dowload del client
![]() Il codice del metodo slide() al momento attende il caricamento dell'immagine necessaria ad assicurare il riempimento dello schermo prima di procedere con l'animazione il che causa interruzione dello scorrimento. Sostituendo il metodo slide con questa versione: Codice:
private void slide() { TICKER.update(); int paintSize = OFFSET_X.get() - getWidth(); for(int i = 0; i < FRAMES.size(); i++) { paintSize += FRAMES.get(i).getWidth(); } if(paintSize <= getWidth()) { loadNextFrame(); } if(FRAMES.size() == 0) return; int delta = -(int)Math.round(speed * TICKER.getTick()); if(OFFSET_X.addAndGet(delta) + FRAMES.get(0).getWidth() <= 0) { OFFSET_X.set(0); FRAMES.remove(0); } repaint(); } Qui è roba da alchimisti. Non si può proiettare un'immagine che non c'è e non si può caricare l'immagine più rapidamente di quanto permetta la connessione del client. Una soluzione potrebbe essere la ripetizione di un'immagine scelta a caso tra quelle tolte dal buffer ma ancora memorizzate. La trama si complica ![]() |
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Oct 2007
Messaggi: 364
|
Grazie
Funziona tutto alla perfezione. Ps:Mi ha salvato la vita. Genymus
__________________
Genymus!!! "Che cosa vorreste far incidere sulla vostra tomba?". "Torno fra 5 minuti." "Lucido" è quando credi soltanto a metà di ciò che ti dicono. "Brillante" è quando sai a quale metà credere. "Pensa, ogni volta che respiro muore un uomo." "Hai provato a fare qualcosa per l'alito?" Aforismieaforismi.it |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 17:52.