Aggiornamento di un’immagine contenuta in una JLabel – problemi

La parte dell’applicazione che attualmente sto riscontrando con difficoltà a raggiungere il lavoro è la possibilità di scorrere e visualizzare un elenco di immagini, una alla volta. Sto ricevendo una directory dall’utente, spooling attraverso tutti i file in quella directory, e quindi caricando un array di solo i jpeg e pngs. Successivamente, voglio aggiornare una JLabel con la prima immagine e fornire i pulsanti precedente e successivo per scorrere e visualizzare ciascuna immagine a turno. Quando provo a visualizzare la seconda immagine, non viene aggiornata … Ecco cosa ho ottenuto finora:

public class CreateGallery { private JLabel swingImage; 

Il metodo che sto usando per aggiornare l’immagine:

 protected void updateImage(String name) { BufferedImage image = null; Image scaledImage = null; JLabel tempImage; try { image = ImageIO.read(new File(name)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // getScaledImage returns an Image that's been resized proportionally to my thumbnail constraints scaledImage = getScaledImage(image, THUMB_SIZE_X, THUMB_SIZE_Y); tempImage = new JLabel(new ImageIcon(scaledImage)); swingImage = tempImage; } 

Quindi nel mio metodo createAndShowGUI che inserisce swingImage in …

 private void createAndShowGUI() { //Create and set up the window. final JFrame frame = new JFrame(); // Miscellaneous code in here - removed for brevity // Create the Image Thumbnail swingImage and start up with a default image swingImage = new JLabel(); String rootPath = new java.io.File("").getAbsolutePath(); updateImage(rootPath + "/images/default.jpg"); // Miscellaneous code in here - removed for brevity rightPane.add(swingImage, BorderLayout.PAGE_START); frame.add(rightPane, BorderLayout.LINE_END); 
 public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { UIManager.put("swing.boldMetal", Boolean.FALSE); new CreateGalleryXML().createAndShowGUI(); } }); } 

Se sei arrivato così lontano, la prima immagine è la mia default.jpg, e una volta che ottengo la directory e identifico la prima immagine in quella directory, è lì che fallisce quando provo ad aggiornare la swingImage. Ora, ho provato a swingImage.setVisible () e swingImage.revalidate () per provare a forzarlo a ricaricare. Sto indovinando che è il mio tempImage = new JLabel che è la causa principale. Ma non sono sicuro di come convertire BufferedImage o Image in una JLabel per aggiornare semplicemente swingImage.

Invece di creare una New Instance di JLabel per ogni Image , usa semplicemente il metodo JLabel # setIcon (…) di JLabel per cambiare l’immagine.

Un piccolo programma di esempio:

 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SlideShow extends JPanel { private int i = 0; private Timer timer; private JLabel images = new JLabel(); private Icon[] icons = {UIManager.getIcon("OptionPane.informationIcon"), UIManager.getIcon("OptionPane.errorIcon"), UIManager.getIcon("OptionPane.warningIcon")}; private ImageIcon pictures1, pictures2, pictures3, pictures4; private ActionListener action = new ActionListener() { public void actionPerformsd(ActionEvent ae) { i++; System.out.println(i); if(i == 1) { pictures1 = new ImageIcon("image/caIcon.png"); images.setIcon(icons[i - 1]); System.out.println("picture 1 should be displayed here"); } if(i == 2) { pictures2 = new ImageIcon("image/Keyboard.png"); images.setIcon(icons[i - 1]); System.out.println("picture 2 should be displayed here"); } if(i == 3) { pictures3 = new ImageIcon("image/ukIcon.png"); images.setIcon(icons[i - 1]); System.out.println("picture 3 should be displayed here"); } if(i == 4) { pictures4 = new ImageIcon("image/Mouse.png"); images.setIcon(icons[0]); System.out.println("picture 4 should be displayed here"); } if(i == 5) { timer.stop(); System.exit(0); } revalidate(); repaint(); } }; public SlideShow() { JFrame frame = new JFrame("SLIDE SHOW"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocationByPlatform(true); frame.getContentPane().add(this); add(images); frame.setSize(300, 300); frame.setVisible(true); timer = new Timer(2000, action); timer.start(); } public static void main(String... args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new SlideShow(); } }); } } 

Da quando lo fai con ImageIO, ecco un buon esempio relativo a quella JLabel che usa ImageIO

Informazioni relative al tuo caso, a ciò che sta accadendo:

All’interno del tuo metodo createAndShowGUI() stai inizializzando la tua JLabel (swingImage), e l’hai aggiunta al tuo JPanel in virtù di quale indirettamente al JFrame .

Ma ora, all’interno del tuo metodo updateImage() , stai inizializzando una nuova JLabel , ora risiede in un’altra posizione di memoria, scrivendo tempImage = new JLabel(new ImageIcon(scaledImage)); e dopo ciò si punta la propria swingImage(JLabel) per puntare a questa JLabel appena creata, ma questa JLabel appena creata non è mai stata aggiunta a JPanel , in nessun punto. Quindi non sarà visibile, anche se provi revalidate()/repaint()/setVisible(...) . Quindi o si modifica il codice per il updateImage(...) a questo:

 protected void updateImage(String name) { BufferedImage image = null; Image scaledImage = null; JLabel tempImage; try { image = ImageIO.read(new File(name)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // getScaledImage returns an Image that's been resized // proportionally to my thumbnail constraints scaledImage = getScaledImage(image, THUMB_SIZE_X, THUMB_SIZE_Y); tempImage = new JLabel(new ImageIcon(scaledImage)); rightPane.remove(swingImage); swingImage = tempImage; rightPane.add(swingImage, BorderLayout.PAGE_START); rightPane.revalidate(); rightPane.repaint(); // required sometimes } 

Oppure usa JLabel.setIcon(...) come accennato in precedenza 🙂

AGGIORNATO LA RISPOSTA

Qui vedi come una New JLabel è posizionata nella posizione di quella vecchia,

 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SlideShow extends JPanel { private int i = 0; private Timer timer; private JLabel images = new JLabel(); private Icon[] icons = {UIManager.getIcon("OptionPane.informationIcon"), UIManager.getIcon("OptionPane.errorIcon"), UIManager.getIcon("OptionPane.warningIcon")}; private ActionListener action = new ActionListener() { public void actionPerformsd(ActionEvent ae) { i++; System.out.println(i); if(i == 4) { timer.stop(); System.exit(0); } remove(images); JLabel temp = new JLabel(icons[i - 1]); images = temp; add(images); revalidate(); repaint(); } }; private void createAndDisplayGUI() { JFrame frame = new JFrame("SLIDE SHOW"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocationByPlatform(true); this.setLayout(new FlowLayout(FlowLayout.LEFT)); add(images); frame.getContentPane().add(this, BorderLayout.CENTER); frame.setSize(300, 300); frame.setVisible(true); timer = new Timer(2000, action); timer.start(); } public static void main(String... args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new SlideShow().createAndDisplayGUI(); } }); } } 

E per la tua domanda: delle due opzioni che ho provato, è una migliore dell’altra?

setIcon(...) ha un vantaggio sull’altro senso, nel senso che non devi preoccuparti di revalidate () / repaint () thingy dopo aver aggiunto / rimosso JLabel . Inoltre, non è necessario ricordare il posizionamento di JLabel ogni volta, lo aggiungi. Rimane nella sua posizione e tu chiami semplicemente l’unico metodo per cambiare l’immagine, senza stringhe e il lavoro è fatto, senza grattacapi.

E per la domanda 2: ho avuto un po ‘di dubbio su cosa sia Array of Records ?