View Full Version : [Java] Problema visualizzazione anteprima immagini
divincodin
23-03-2009, 21:34
Ciao a tutti,come da titolo ho qualche problemino nella visualizzazione delle anteprime di immagini.Una parte dell'applicazione che sto creando dà la possibilità all'utente di selezionare cartelle contenente delle immagini e visualizzarne le anteprime nella parte sinistra del pannello.
Prendendo spunto da un codice che tempo fa è stato postato in questo sito,sono riuscito solo in parte perchè le immagini vengono caricate ma quando sono parecchie non è possibile vederle tutte.
Ho provato ad utilizzare un JScrollPane,ma non va!
Questa è la parte di codice che carica le anteprime
import javax.swing.event.*;
import javax.swing.filechooser.*;
import javax.imageio.*;
import javax.swing.border.*;
import javax.swing.filechooser.FileFilter;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.color.*;
import java.io.*;
import java.beans.*;
import java.lang.Object;
import java.awt.image.ImageObserver;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.*;
public class Applicazione
{
public static void main(String [] args)
{
Frame frame=new Frame();
frame.show();
}
}
class Frame extends JFrame implements ActionListener
{
pannelloa a=new pannelloa();
pannellob b=new pannellob();
JMenuItem apriCartella,apriVideo;
File f;
String pathfile;
public Frame()
{
setTitle("Analizzatore Video Medicali");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setExtendedState(MAXIMIZED_BOTH);
JMenuBar barra=new JMenuBar();
JMenu menu=new JMenu("File");
apriVideo=new JMenuItem("Apri Video");
apriCartella=new JMenuItem("Apri Cartella Immagini");
barra.add(menu);
menu.add(apriVideo);
menu.add(apriCartella);
apriVideo.addActionListener(this);
apriCartella.addActionListener(this);
this.setJMenuBar(barra);
//creo uno JScrollPane all'interno del quale inserirò il pannello "a"
/* 1a OPZIONE
JScrollPane scroll=new JScrollPane();
scroll.getViewport().add(a);
*/
//a.setLayout(new BoxLayout(a, BoxLayout.Y_AXIS));
JScrollPane scroll=new JScrollPane(a,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
Container pane=getContentPane();
pane.setLayout(new GridLayout(1,2));
pane.add(scroll);
pane.add(b);
}
public void actionPerformed(ActionEvent e)
{
Object source=e.getSource();
if(source==apriVideo)
{
JFileChooser finestra_1 = new JFileChooser();
finestra_1.setDialogTitle("Apri video");
finestra_1.setAcceptAllFileFilterUsed(false);
finestra_1.setFileFilter(new aviFilter());
finestra_1.showOpenDialog(new JFrame());
File file = finestra_1.getSelectedFile();
pathfile=file.getAbsolutePath();
//richiamo il metodo "Grab()" della classe "VideoGrabbing"
VideoGrabbing.grab(pathfile);
//System.exit(0);
}
if(source==apriCartella)
{
JFileChooser finestra_2=new JFileChooser();
finestra_2.setDialogTitle("Apri cartella immagini");
finestra_2.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if(finestra_2.showOpenDialog(a)==JFileChooser.APPROVE_OPTION)
//richiamo il metodo azione passando la cartella selezionata
azione(finestra_2.getSelectedFile());
}
}
public void azione(File dir)
{
if(a.getComponentCount()!=0)
{
a.removeAll();
a.updateUI();
}
File f[]=dir.listFiles();
ImageIcon icons[]=new ImageIcon[f.length];
//a.setLayout(new GridBagLayout());
a.setLayout(new GridLayout(f.length/3,3));
//a.setBounds(0,0,110,110);
for(int i=0; i<f.length;i++)
{
icons[i]=new ImageIcon(f[i].getAbsolutePath(),f[i].getName());
ImageIcon adactIcon=new ImageIcon(getScaledImage(icons[i].getImage(),100,100));
JButton thumbButton=new JButton(f[i].getName(),adactIcon);
thumbButton.setVerticalTextPosition(AbstractButton.BOTTOM);
thumbButton.setHorizontalTextPosition(AbstractButton.CENTER);
a.add(thumbButton);
a.revalidate();
}
}
private Image getScaledImage(Image srcImg,int w,int h)
{
BufferedImage resizedImg = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = resizedImg.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(srcImg,0,0,w,h,null);
g2.dispose();
return resizedImg;
}
}
class pannelloa extends JPanel
{
public pannelloa()
{
//Toolkit tool = Toolkit.getDefaultToolkit();
//Dimension dim =tool.getScreenSize();
//setPreferredSize(new Dimension(dim.width/2,dim.height));
}
}
class pannellob extends JPanel
{
public pannellob()
{
setBackground(Color.green);
}
}
class aviFilter extends FileFilter
{
public boolean accept(File f)
{
String nome = f.getName().toLowerCase();
if (nome.endsWith("avi")||f.isDirectory())
return true;
else
return false;
}
public String getDescription ()
{
return "File (*.avi)";
}
}
Spero che qualcuno di voi possa aiutarmi a risolvere questo problema.Ciao
Vado a tentoni perchè "non va" è un pelo generico :D.
Usa un JScrollPane. Gli infili dentro il pannello che dovrebbe contenere le immagini. Se cambi il contenuto del pannello devi dire al JScrollPane di aggiornare la sua "vista". Quindi dopo aver cambiato il contenuto del pannello p dirai:
scrollpane.setViewportView(p);
Il tuo main non è corretto. Per ragioni di concorrenza la forma dovrebbe essere:
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new Frame().show();
}
}
}
islandofjava
24-03-2009, 01:26
Vado a tentoni perchè "non va" è un pelo generico :D.
Usa un JScrollPane. Gli infili dentro il pannello che dovrebbe contenere le immagini. Se cambi il contenuto del pannello devi dire al JScrollPane di aggiornare la sua "vista". Quindi dopo aver cambiato il contenuto del pannello p dirai:
scrollpane.setViewportView(p);
Il tuo main non è corretto. Per ragioni di concorrenza la forma dovrebbe essere:
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new Frame().show();
}
}
}
OT
mamma mia PGI sei infaticabile.
Una risorsa insostituibile per chi ha a che fare con Java.
Se mai toccasse e toccherà sicuro so a chi rivolgermi :D
Notevole davvero :flower:
divincodin
24-03-2009, 22:57
Allora,intanto ti ringrazio per avermi risposto.
Cmq per inserire la antemprime nel pannello a sinista,ho dato ad esso un gridLayout
a.setLayout(new GridLayout(f.length/3,3));
ma così facendo,le anteprime se sn poche si vedono + grandi mentre se sn di + si vedono + piccole...penso che sia perchè il gridLayout cerca di occupare tutto lo spazio e quindi le ingrandisce.
Cercando sul forum ho trovato un'implementazione che trovo interessante e che farebbe al mio caso.Ho provato ad inserirla ma non riesco :S
Questa è la nuova impostazione (p.s. mi scuso anticipatamente per tutte le assurdità che ho potuto scrivere nel codice seguente,ma non sn molto ferrato ancora su queste cose :rolleyes: )
import javax.swing.event.*;
import javax.swing.filechooser.*;
import javax.imageio.*;
import javax.swing.border.*;
import javax.swing.filechooser.FileFilter;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.color.*;
import java.io.*;
import java.beans.*;
import java.lang.Object;
import java.awt.image.ImageObserver;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.*;
public class Applicazione
{
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new Frame().show();
}
});
}
}
class Frame extends JFrame implements ActionListener
{
pannelloa a=new pannelloa();
JMenuItem apriCartella,apriVideo;
File f;
String pathfile;
public Frame()
{
setTitle("Analizzatore Video Medicali");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setExtendedState(MAXIMIZED_BOTH);
JMenuBar barra=new JMenuBar();
JMenu menu=new JMenu("File");
apriVideo=new JMenuItem("Apri Video");
apriCartella=new JMenuItem("Apri Cartella Immagini");
barra.add(menu);
menu.add(apriVideo);
menu.add(apriCartella);
apriVideo.addActionListener(this);
apriCartella.addActionListener(this);
this.setJMenuBar(barra);
Container pane=getContentPane();
pane.setLayout(new GridLayout(1,1));
pane.add(a);
}
public void actionPerformed(ActionEvent e)
{
Object source=e.getSource();
if(source==apriVideo)
{
JFileChooser finestra_1 = new JFileChooser();
finestra_1.setDialogTitle("Apri video");
finestra_1.setAcceptAllFileFilterUsed(false);
finestra_1.setFileFilter(new aviFilter());
finestra_1.showOpenDialog(new JFrame());
File file = finestra_1.getSelectedFile();
pathfile=file.getAbsolutePath();
//richiamo il metodo "Grab()" della classe "VideoGrabbing"
VideoGrabbing.grab(pathfile);
//System.exit(0);
}
if(source==apriCartella)
{
JFileChooser finestra_2=new JFileChooser();
finestra_2.setDialogTitle("Apri cartella immagini");
finestra_2.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if(finestra_2.showOpenDialog(a)==JFileChooser.APPROVE_OPTION)
//richiamo il metodo azione passando la cartella selezionata
azione(finestra_2.getSelectedFile());
}
}
public void azione(File dir)
{
File f[]=dir.listFiles();
//ImageIcon icons[]=new ImageIcon[f.length];
//oppure sto provando così
ImageViewerItem [] items=new ImageViewerItem[f.length];
for(int i=0;i<f.length;i++)
items[i]=new ImageViewerItem(f[i],-1,100);
JList itemsList=new JList(items);
itemsList.setCellRenderer(new ImageViewerCellRenderer());
itemsList.addListSelectionListener(this);
JLabel viewerLabel = new JLabel ();
viewerLabel.setHorizontalAlignment (SwingConstants.CENTER);
JScrollPane listScrollPane = new JScrollPane (itemsList,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
JScrollPane labelScrollPane = new JScrollPane (viewerLabel,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
a.add(listScrollPane, BorderLayout.WEST);
a.add(labelScrollPane, BorderLayout.CENTER);
}
}
class pannelloa extends JPanel
{
public pannelloa()
{
setLayout(new BorderLayout ());
}
}
class aviFilter extends FileFilter
{
public boolean accept(File f)
{
String nome = f.getName().toLowerCase();
if (nome.endsWith("avi")||f.isDirectory())
return true;
else
return false;
}
public String getDescription ()
{
return "File (*.avi)";
}
}
Rispetto al precedente ho creato un unico pannello (pannelloa) al quale do un BorderLayout ().Quando nel menu seleziono "carica immagini" e seleziono la cartella,richiamo il metodo "azione()".
Poi ci sn altri 3 file che non posto per evitare di dilungarmi troppo.
L'errore che mi da e che non mi fa funzionare il tutto è questo:
"Applicazione.java:114: addListSelectionListener(javax.swing.event.ListSelectionListener) in javax.swing.JList cannot be applied to (Frame)
itemsList.addListSelectionListener(this);"
Non c'è nulla di cui scusarsi, siamo qua per imparare l'uno dall'altro :).
addListSelectionListener richiede come argomento un ListSelectionListener. Tu usi this, cioè la tua classe Frame la quale non implementa ListSelectionListener, da cui l'errore.
Puoi risolvere semplicemente:
class Frame extends JFrame implements ActionListener, ListSelectionListener {
public void valueChanged(ListSelectionEvent e) {
}
ListSelectionListener funziona un po' come ActionListener. Ora quando cambia la selezione corrente nella lista verrà invocato il metodo valueChanged.
La tua analisi del problema del layout è corretta. GridLayout distribuisce lo spazio disponibile tra le righe e le colonne. Maggiore è lo spazio più grandi sono le celle, minore lo spazio più piccole le celle.
L'uso della lista è senz'altro una soluzione valida. Te ne propongo un'altra altrettanto "stuzzichevole".
Quando uno dei layout predefiniti non ti soddisfa pienamente puoi crearne uno tuo.
E' il caso del favoloso, magnifico e magnificamente nominato BongoLayout:
public class BongoLayout implements LayoutManager {
public void addLayoutComponent(String name, Component comp) {
//does nothing
}
public void removeLayoutComponent(Component comp) {
//does nothing
}
/** Questo metodo viene invocato da Swing ogni volta in cui le dimensioni
del contenitore cambiano. */
public void layoutContainer(Container parent) {
synchronized(parent.getTreeLock()) {
Component[] components = parent.getComponents();
Dimension maxSize = computeCellSize(components);
Insets borderInsets = parent.getInsets();
int columnCount = computeMaxColumnCount(parent, maxSize);
int currentColumn = 0;
int currentRow = 0;
int x = borderInsets.left;
int y = borderInsets.top;
Rectangle componentBounds = new Rectangle(x, y, maxSize.width, maxSize.height);
for(Component c : components) {
componentBounds.x = x + maxSize.width * currentColumn;
componentBounds.y = y + maxSize.height * currentRow;
c.setBounds(componentBounds);
currentColumn++;
if(currentColumn >= columnCount) {
currentColumn = 0;
currentRow++;
}
}
}
}
/** Metodo di servizio, calcola quante colonne possiamo creare data una cella
di dimensioni maxSize in un contenitore parent. */
private int computeMaxColumnCount(Container parent, Dimension maxSize) {
Insets borderInsets = parent.getInsets();
int width = parent.getWidth() - (borderInsets.left + borderInsets.right);
return Math.max(width / maxSize.width, 1);
}
/** Calcola le dimensioni della cella in base alla massima altezza e
larghezza di ogni componente del contenitore */
private Dimension computeCellSize(Component[] components) {
Dimension result = new Dimension(1, 1);
for(Component c : components) {
Dimension preferredSize = c.getPreferredSize();
result.width = Math.max(preferredSize.width, result.width);
result.height = Math.max(preferredSize.height, result.height);
}
return result;
}
/** Calcola la dimensione minima del contenitore, che per noi è identica
alla dimensione preferita. */
public Dimension minimumLayoutSize(Container parent) {
return preferredLayoutSize(parent);
}
/** Calcola la dimensione preferita del contenitore. Stabiliamo che
questo contenitore di norma proietta tutto su una singola colonna. Lo
spazio eventualmente in eccesso è poi gestito dal metodo layoutContainer. */
public Dimension preferredLayoutSize(Container parent) {
synchronized(parent.getTreeLock()) {
Dimension cellSize = computeCellSize(parent.getComponents());
int columnCount = 1;
int width = cellSize.width * columnCount;
int height = (parent.getComponents().length / columnCount) * cellSize.height;
Insets borderMargin = parent.getInsets();
width += borderMargin.left + borderMargin.right;
height += borderMargin.top + borderMargin.bottom;
return new Dimension(width, height);
}
}
}
BongoLayout crea una griglia. Ogni cella ha le stesse dimensioni. La dimensione di ogni cella è calcolata prendendo il più largo ed il più alto dei componenti nel contenitore a cui è applicato BongoLayout (che sarebbe il Container protagonista di tutti i metodi di LayoutManager).
La griglia di BongoLayout ha una sola colonna tuttavia se c'è spazio a sufficienza per proiettare due componenti uno di fianco all'altro allora le colonne diventano 2 o 3, 4... eccetera.
Fine del layout.
Come per la maggior parte dei layout, l'uso è trasparente. A differenza di GridLayout, BongoLayout affida ad ogni componente la dimensione sufficiente a proiettarlo completamente, allargando se necessario (e possibile) il contenitore.
Un esempio d'uso:
public class Main {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new Main().start();
}
});
}
private void start() {
JPanel thumbnailContainer = new JPanel();
thumbnailContainer.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
thumbnailContainer.setLayout(new BongoLayout());
for(int i = 0; i < 20; i++) {
JComponent fakeThumbnail = createFakeThumbnail();
thumbnailContainer.add(fakeThumbnail);
}
JScrollPane scroller = new JScrollPane(thumbnailContainer);
JFrame window = new JFrame("Hello");
window.add(scroller);
window.setSize(400, 400);
window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
window.setVisible(true);
}
private JComponent createFakeThumbnail() {
JButton component = new JButton();
component.setPreferredSize(new Dimension(100, 100));
return component;
}
}
divincodin
25-03-2009, 11:01
Seguendo i tuoi consigli ho fatto passi avanti.
Ma ancora c'è qualcosa che non va.Ho inserito "ListSelectionListener" all'inizio della classe e subito dopo il metodo "azione" ho inserito il metodo "public void valueChanged (ListSelectionEvent ex)".
Le immagini penso proprio che le carichi ma non visualizza niente.
Ho fatto una prova inserendo
a.revalidate();
subito dopo gli "add" ed il tutto spunta.Se xò,dopo aver caricato la prima cartella,provo a visualizzare il contenuto di una seconda cartella (sovrascrivendo quindi nella lista le nuove immagini a quelle vecchie)all'inizio le carica (anche se non tutte),ma se provo a cliccarci sopra,mi spunta una finestra con scritto "error loading image".
class Frame extends JFrame implements ActionListener,ListSelectionListener
{
pannelloa a=new pannelloa();
JMenuItem apriCartella,apriVideo;
File f;
String pathfile;
JList itemsList;
JLabel viewerLabel;
public Frame()
{
setTitle("Analizzatore Video Medicali");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setExtendedState(MAXIMIZED_BOTH);
JMenuBar barra=new JMenuBar();
JMenu menu=new JMenu("File");
apriVideo=new JMenuItem("Apri Video");
apriCartella=new JMenuItem("Apri Cartella Immagini");
barra.add(menu);
menu.add(apriVideo);
menu.add(apriCartella);
apriVideo.addActionListener(this);
apriCartella.addActionListener(this);
this.setJMenuBar(barra);
Container pane=getContentPane();
pane.setLayout(new GridLayout(1,1));
pane.add(a);
}
public void actionPerformed(ActionEvent e)
{
Object source=e.getSource();
if(source==apriVideo)
{
JFileChooser finestra_1 = new JFileChooser();
finestra_1.setDialogTitle("Apri video");
finestra_1.setAcceptAllFileFilterUsed(false);
finestra_1.setFileFilter(new aviFilter());
finestra_1.showOpenDialog(new JFrame());
File file = finestra_1.getSelectedFile();
pathfile=file.getAbsolutePath();
//richiamo il metodo "Grab()" della classe "VideoGrabbing"
VideoGrabbing.grab(pathfile);
//System.exit(0);
}
if(source==apriCartella)
{
JFileChooser finestra_2=new JFileChooser();
finestra_2.setDialogTitle("Apri cartella immagini");
finestra_2.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if(finestra_2.showOpenDialog(a)==JFileChooser.APPROVE_OPTION)
//richiamo il metodo azione passando la cartella selezionata
azione(finestra_2.getSelectedFile());
}
}
public void azione(File dir)
{
try
{
File f[]=dir.listFiles();
ImageViewerItem [] items=new ImageViewerItem[f.length];
for(int i=0;i<f.length;i++)
items[i]=new ImageViewerItem(f[i],-1,100);
itemsList=new JList(items);
itemsList.setCellRenderer(new ImageViewerCellRenderer());
itemsList.addListSelectionListener(this);
viewerLabel = new JLabel ();
viewerLabel.setHorizontalAlignment (SwingConstants.CENTER);
JScrollPane listScrollPane = new JScrollPane (itemsList,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
JScrollPane labelScrollPane = new JScrollPane (viewerLabel,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
a.add(listScrollPane, BorderLayout.WEST);
a.add(labelScrollPane, BorderLayout.CENTER);
a.revalidate();
}
catch (Exception e)
{
System.err.println (e);
}
}
public void valueChanged (ListSelectionEvent ex)
{
ImageViewerItem item = (ImageViewerItem) itemsList.getSelectedValue ();
try
{
ImageIcon imageIcon = item.loadFullImage ();
viewerLabel.setIcon (imageIcon);
}
catch (Exception exc)
{
JOptionPane.showMessageDialog (this, "Error loading image", "ERROR", JOptionPane.ERROR_MESSAGE);
}
}
}
Non capisco proprio xkè,senza il revalidate() non funziona proprio!
Il revalidate() ti serve perchè stai cambiando la struttura di un contenitore visualizzabile (il pannello a).
La cambi in "azione", quando dici "a.add(listScrollPane ... a.add(labelScrollPane".
L'approccio che hai scelto non è concettualmente errato tuttavia in "azione(File dir)" dovresti rimuovere il contenuto di "a" prima di aggiungere nuovi componenti (a.removeAll()) perchè il layout attuale di a (BorderLayout) sovrappone il contenuto nel caso di inserimenti multipli in una stessa regione. Per ogni invocazione di azione, infatti, "a" riceve un nuovo componente in WEST e un nuovo componente in CENTER.
Quanto alle ragione dell'eccezione in valueChanged dovresti stampare sulla console la traccia dell'errore (exc.printStackTrace()), così da avere informazioni sulla causa scatenante.
Ciò premesso il modo che hai scelto per aggiornare l'interfaccia - rigenerarne la struttura - non è il più efficiente a parità di risultato.
Anzichè sostituire i componenti potresti infatti limitarti ad aggiornare i dati che quei componenti proiettano.
Ad esempio:
class Frame extends JFrame implements ActionListener,ListSelectionListener {
pannelloa a=new pannelloa();
JMenuItem apriCartella,apriVideo;
File f;
String pathfile;
JList itemsList;
JLabel viewerLabel;
public Frame() {
setTitle("Analizzatore Video Medicali");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setExtendedState(MAXIMIZED_BOTH);
JMenuBar barra=new JMenuBar();
JMenu menu=new JMenu("File");
apriVideo=new JMenuItem("Apri Video");
apriCartella=new JMenuItem("Apri Cartella Immagini");
barra.add(menu);
menu.add(apriVideo);
menu.add(apriCartella);
apriVideo.addActionListener(this);
apriCartella.addActionListener(this);
this.setJMenuBar(barra);
itemsList = new JList();
itemsList.setCellRenderer(new ImageViewerCellRenderer());
itemsList.addListSelectionListener(this);
viewerLabel = new JLabel();
viewerLabel.setHorizontalAlignment(SwingConstants.CENTER);
JScrollPane listScrollPane = new JScrollPane (itemsList,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
JScrollPane labelScrollPane = new JScrollPane (viewerLabel,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
a.add(listScrollPane, BorderLayout.WEST);
a.add(labelScrollPane, BorderLayout.CENTER);
Container pane=getContentPane();
pane.setLayout(new GridLayout(1,1));
pane.add(a);
}
public void azione(File dir) {
try {
File f[]=dir.listFiles();
ImageViewerItem [] items = new ImageViewerItem[f.length];
for(int i=0;i<f.length;i++){
items[i]=new ImageViewerItem(f[i],-1,100);
}
itemsList.setListData(items);
} catch (Exception e) {
System.err.println (e);
}
}
Il risultato è lo stesso ma lo ottieni senza manipolare la struttura del contenitore "a" e riciclando dei componenti già in vita.
Per quanto riguarda la selezione di una cella nella lista itemsList da parte dell'utente se l'evento che vuoi intercettare è un click del mouse allora non ti serve un ListSelectionListener ma un MouseListener. Ad esempio:
itemsList.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if(SwingUtilities.isLeftMouseButton(e) && e.getClickCount() > 1) {
int index = itemsList.locationToIndex(e.getPoint());
if(index >= 0) {
itemClick(temsList.getModel().getElementAt(index));
}
}
}
});
private void itemClick(Object item) {
//l'utente ha fatto doppio click ini itemsList "beccando" item
}
divincodin
25-03-2009, 17:25
Comincio premettendo che quoto "islandofjava"...sei davvero infaticabile oltre che un mostro di bravura :D
Cmq ho seguito x l'ennesima volta i tuoi consigli...reimpostando la struttura come da te scritto e non manipolando la struttura del contenitore "a".
Dopo l'apertura della 1a cartella,andando ad aprirne una 2a xò spunta nuovamente quell'errore "error loading image"...anche se le immagini le carica ed infatti una volta premuto ok funziona perfettamente.
Questo è la struttura reimpostata secondo le tue direttive
import javax.swing.event.*;
import javax.swing.filechooser.*;
import javax.imageio.*;
import javax.swing.border.*;
import javax.swing.filechooser.FileFilter;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.color.*;
import java.io.*;
import java.beans.*;
import java.lang.Object;
import java.awt.image.ImageObserver;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.*;
public class Applicazione
{
public static void main(String [] args)
{
Frame frame=new Frame();
frame.show();
}
}
class Frame extends JFrame implements ActionListener,ListSelectionListener
{
pannelloa a=new pannelloa();
JMenuItem apriCartella,apriVideo;
File f;
String pathfile;
JList itemsList;
JLabel viewerLabel;
public Frame()
{
setTitle("Analizzatore Video Medicali");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setExtendedState(MAXIMIZED_BOTH);
JMenuBar barra=new JMenuBar();
JMenu menu=new JMenu("File");
apriVideo=new JMenuItem("Apri Video");
apriCartella=new JMenuItem("Apri Cartella Immagini");
barra.add(menu);
menu.add(apriVideo);
menu.add(apriCartella);
apriVideo.addActionListener(this);
apriCartella.addActionListener(this);
this.setJMenuBar(barra);
itemsList = new JList();
itemsList.setCellRenderer(new ImageViewerCellRenderer());
itemsList.addListSelectionListener(this);
viewerLabel = new JLabel();
viewerLabel.setHorizontalAlignment(SwingConstants.CENTER);
JScrollPane listScrollPane = new JScrollPane (itemsList,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
JScrollPane labelScrollPane = new JScrollPane (viewerLabel,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
a.add(listScrollPane, BorderLayout.WEST);
a.add(labelScrollPane, BorderLayout.CENTER);
Container pane=getContentPane();
pane.add(a);
}
public void actionPerformed(ActionEvent e)
{
Object source=e.getSource();
if(source==apriVideo)
{
JFileChooser finestra_1 = new JFileChooser();
finestra_1.setDialogTitle("Apri video");
finestra_1.setAcceptAllFileFilterUsed(false);
finestra_1.setFileFilter(new aviFilter());
finestra_1.showOpenDialog(new JFrame());
File file = finestra_1.getSelectedFile();
pathfile=file.getAbsolutePath();
//richiamo il metodo "Grab()" della classe "VideoGrabbing"
VideoGrabbing.grab(pathfile);
//System.exit(0);
}
if(source==apriCartella)
{
JFileChooser finestra_2=new JFileChooser();
finestra_2.setDialogTitle("Apri cartella immagini");
finestra_2.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if(finestra_2.showOpenDialog(a)==JFileChooser.APPROVE_OPTION)
//richiamo il metodo azione passando la cartella selezionata
azione(finestra_2.getSelectedFile());
}
}
public void azione(File dir)
{
try
{
/*
if(a.getComponentCount()!=0)
{
a.removeAll();
a.updateUI();
}
*/
File f[]=dir.listFiles();
ImageViewerItem [] items = new ImageViewerItem[f.length];
for(int i=0;i<f.length;i++){
items[i]=new ImageViewerItem(f[i],-1,100);
}
itemsList.setListData(items);
}
catch (Exception e)
{
System.err.println (e);
}
}
public void valueChanged (ListSelectionEvent ex)
{
ImageViewerItem item = (ImageViewerItem) itemsList.getSelectedValue ();
try
{
ImageIcon imageIcon = item.loadFullImage ();
viewerLabel.setIcon (imageIcon);
}
catch (Exception exc)
{
JOptionPane.showMessageDialog (this, "Error loading image", "ERROR", JOptionPane.ERROR_MESSAGE);
}
}
}
class pannelloa extends JPanel
{
public pannelloa()
{
setLayout (new BorderLayout ());
}
}
class aviFilter extends FileFilter
{
public boolean accept(File f)
{
String nome = f.getName().toLowerCase();
if (nome.endsWith("avi")||f.isDirectory())
return true;
else
return false;
}
public String getDescription ()
{
return "File (*.avi)";
}
}
Allora...così com'è scritto dà il problema che ho scritto sopra.Invece non commentando l'if dentro il try del metodo "azione" poi non visualizza niente xkè mi sa proprio che sovrascive un qualcosa.
Come faccio a levare quel malefico errore di "loading image" lasciando così la struttura?
Cmq ti ringrazio davvero per l'aiuto che mi stai dando!
Stampando sulla console l'eccezione:
catch (Exception exc)
{
exc.printStackTrace();
JOptionPane.showMessageDialog (this, "Error loading image", "ERROR", JOptionPane.ERROR_MESSAGE);
}
Cosa dice? (incolla la traccia se puoi).
divincodin
25-03-2009, 19:24
Queste sn le eccezioni che dà:
java.lang.NullPointerException
at Frame.valueChanged(Applicazione.java:147)
at javax.swing.JList.fireSelectionValueChanged(Unknown Source)
at javax.swing.JList$ListSelectionHandler.valueChanged(Unknown Source)
at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
at javax.swing.DefaultListSelectionModel.changeSelection(Unknown Source)
at javax.swing.DefaultListSelectionModel.changeSelection(Unknown Source)
at javax.swing.DefaultListSelectionModel.removeSelectionIntervalImpl(Unknown Source)
at javax.swing.DefaultListSelectionModel.clearSelection(Unknown Source)
at javax.swing.JList.clearSelection(Unknown Source)
at javax.swing.JList.setModel(Unknown Source)
at javax.swing.JList.setListData(Unknown Source)
at Frame.azione(Applicazione.java:132)
at Frame.actionPerformed(Applicazione.java:111)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Giusto, ovvio. Avrei dovuto dirlo senza neanche aspettare.
Il metodo valueChanged viene invocato quando cambia la selezione sulla lista. La selezione cambia anche quando si passa da un elemento selezionato a nessun elemento selezionato.
E a causa di questa seconda evenienza che si blocca tutto, rilasciando quella NullePointerException.
Soluzione:
public void valueChanged (ListSelectionEvent ex) {
ImageViewerItem item = (ImageViewerItem) itemsList.getSelectedValue ();
if(item != null) {
try {
ImageIcon imageIcon = item.loadFullImage ();
viewerLabel.setIcon (imageIcon);
} catch (Exception exc) {
JOptionPane.showMessageDialog (this, "Error loading image", "ERROR", JOptionPane.ERROR_MESSAGE);
}
}
}
divincodin
25-03-2009, 19:37
Perfetto...hai ragionissima...adesso va che è una veraviglia!
Non so davvero come ringraziarti :ave:
Mi sa che se,nell'ultimare l'applicazione,avrò qualche altro problema ti contatterò :D
Ancora grazie di cuore...x capire certi errori ci sarei stato secoli!
nuovoUtente86
03-04-2009, 16:28
Mi ricollego alla discussione circa il GridLayout e al suo modo di lavorare ovvero riempire tutto lo spazio disponibile ridimensionando i componenti.
Mi ritrovo nella situazione in cui, non essendo tantissimi i componenti (label e textfield/combobox), vengono ingranditi oltremodo generando uno sgradevole effetto estetico. Sarebbe possibile disabilitare il ridimensionamento automatico oppure esiste qualche altra metodologia per impedire questo eccessivo resize?Grazie
Usa un GridBagLayout al posto di GridLayout. Tempo fa scrissi una guida al riguardo.
http://www.hwupgrade.it/forum/showthread.php?t=1335610
E' più facile di come sembra (non ho mai avuto il dono della sintesi :D).
banryu79
03-04-2009, 17:17
Usa un GridBagLayout al posto di GridLayout. Tempo fa scrissi una guida al riguardo.
http://www.hwupgrade.it/forum/showthread.php?t=1335610
Ottimo quel tutorial, consigliato.
nuovoUtente86
03-04-2009, 18:51
Perfetto, risolto seguendo il tutorial. Grazie
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.