PDA

View Full Version : [JAVA] - problema jpanel immagini dinamiche


prototipo88
06-08-2010, 01:24
ciao a tutti... ho un'applicazione dove arrivano messaggi, io voglio visualizzare l'immagine collegata al nodo che invia il messaggio in un jpanel associato... ad esempio arriva messaggio del nodo 5, creo un'immagine A nel jpanel1, invece dal nodo 6, creo immagine B nel jpanel2... quindi si dovrebbe modificare l'immagine del jpanel dinamicamente...
il problema è che viene visualizzata solo la PRIMA immagine associata al PRIMO messaggio ricevuto... se arriva prima il messaggio del nodo 5, viene visualizzata solo A, e viceversa...
può essere un problema dovuto alla dichiarazione delle variabili?
premetto che non capisco molto di java... :) ... grazie a tutti

//BIGMSG.nome è il nome dell'immagine.. es: "fragola.jpg"


import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.color.*;


public class DemoImage extends JFrame {

public static JFrame frame = new JFrame("My JFrame");
public static int WIDTH=300;
public static int HEIGHT=300;
public ImagePanel panel1 = new ImagePanel("");
public ImagePanel panel2 = new ImagePanel("");
public ImagePanel panel3 = new ImagePanel("");
public ImagePanel panel4 = new ImagePanel("");

public void setJFrame() {


frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(WIDTH, HEIGHT);
frame.setResizable(true);
frame.setLocationRelativeTo(null);
frame.validate();
frame.setVisible(true);
frame.getContentPane().setLayout(new GridLayout(2,2));
frame.pack();

panel1= new ImagePanel("");
panel1.setDoubleBuffered(true);
panel1.setBackground(Color.white);
panel1.validate();
panel1.setVisible(true);
panel1.setBorder(BorderFactory.createLineBorder(Color.black));

panel2= new ImagePanel("");
panel2.setDoubleBuffered(true);
panel2.validate();
panel2.setVisible(true);
panel2.setBorder(BorderFactory.createLineBorder(Color.black));

panel3= new ImagePanel("");
panel3.setDoubleBuffered(true);
panel3.validate();
panel3.setVisible(true);
panel3.setBorder(BorderFactory.createLineBorder(Color.black));

panel4= new ImagePanel("");
panel4.setDoubleBuffered(true);
panel4.validate();
panel4.setBackground(Color.white);
panel4.setVisible(true);
panel4.setBorder(BorderFactory.createLineBorder(Color.black));



frame.getContentPane().add(panel1, BorderLayout.NORTH);
frame.getContentPane().add(panel2, BorderLayout.EAST);
frame.getContentPane().add(panel3, BorderLayout.SOUTH);
frame.getContentPane().add(panel4, BorderLayout.WEST);
frame.validate();
frame.setVisible(true);

}


// Aggiorna l'ImagePanel corretto con la nuova immagine.
// BIGMSG contiene sia l'id del pannello da aggiornare
// che l'immagine.

public void showImage() {


if(BIGMSG.numero_nodo==5){ //se è 5 tutto ok, se è 6, non mi fa vedere l'immagine, anche se entra nel ciclo
//RETTIFICA... anche il 6 funziona, solo se il 5 non crea l'immagine.. che cosa strana
panel1.resetImage(BIGMSG.image);
panel1.validate();
}
if(BIGMSG.numero_nodo==6){ //metto l'else solo per ora... ma perchè == 6 non stampa niente? secondo me sta troppo poco tempo con BIGMSG.numero_nodo a 6
panel2.resetImage(BIGMSG.image);
panel2.validate();
}

if(BIGMSG.numero_nodo==7){
panel3.resetImage(BIGMSG.image);
panel3.validate();
}

if(BIGMSG.numero_nodo==8){ //in teoria dovrebbe essere 8
panel4.resetImage(BIGMSG.image);
panel4.validate();
}
/*
if(BIGMSG.numero_nodo==6){
ImageIcon image2 = new ImageIcon();
image2 = new ImageIcon(BIGMSG.nome);
panel2.resetImage(image2.getImage());
}
*/

frame.validate();


}

}

class ImagePanel extends JPanel{

private Image image;
private Dimension dim=null;

public ImagePanel(String image) {
this(new ImageIcon(image).getImage());
}

public ImagePanel(Image image){
this.image=image;
dim=new Dimension();
dim.width=WIDTH;
dim.height=HEIGHT;
setPreferredSize(dim);
}

public void resetImage(Image image){

this.image=image;
repaint();


}



@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);

if(image!=null){
g.drawImage(image,10,10,null);

}

}

}

tylerdurden83
06-08-2010, 15:19
Prova questo:


package testimmagine;

import java.awt.*;
import javax.swing.*;

public class DemoImage extends JFrame {
private JPanel panel1;
private JPanel panel2;
private JPanel panel3;
private JPanel panel4;
private static final ImageIcon ICONA = new ImageIcon("C:\\Documents and Settings\\User15\\Documenti\\Immagini\\assist_listening.jpg");

private static JPanel createNewJPanel(Color color){
JPanel panel = new JPanel();
panel.setBackground(color);
panel.setDoubleBuffered(true);
panel.setBackground(Color.white);
panel.setBorder(BorderFactory.createLineBorder(Color.black));
return panel;
}

public DemoImage() {
//Create and set up the window.
super("My JFrame");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

this.panel1 = createNewJPanel(Color.black);
this.panel2 = createNewJPanel(Color.white);
this.panel3 = createNewJPanel(Color.black);
this.panel4 = createNewJPanel(Color.white);

this.setLocationRelativeTo(null);
this.getContentPane().setLayout(new GridLayout(2,2));

this.getContentPane().add(this.panel1, BorderLayout.NORTH);
this.getContentPane().add(this.panel2, BorderLayout.EAST);
this.getContentPane().add(this.panel3, BorderLayout.SOUTH);
this.getContentPane().add(this.panel4, BorderLayout.WEST);

this.pack();
this.setVisible(true);
}

public void showImage(int pannello) {
if(pannello==5){ //se è 5 tutto ok, se è 6, non mi fa vedere l'immagine, anche se entra nel ciclo
this.panel1.add(new JLabel(ICONA));
}
if(pannello==6){ //metto l'else solo per ora... ma perchè == 6 non stampa niente? secondo me sta troppo poco tempo con BIGMSG.numero_nodo a 6
this.panel2.add(new JLabel(ICONA));
}
if(pannello==7){
this.panel3.add(new JLabel(ICONA));
}
if(pannello==8){ //in teoria dovrebbe essere 8
this.panel4.add(new JLabel(ICONA));
}
this.pack();
this.setLocationRelativeTo(null);
}

public static void main(String[] args) throws InterruptedException {
SwingUtilities.invokeLater(new Runnable() {
@Override public void run() {
DemoImage demoImage = new DemoImage();
demoImage.showImage(5);
demoImage.showImage(6);
}
});
}
}

*andre*
06-08-2010, 18:40
in che modo prendi le immagini?
che può essere che ci sia l'oggetto e non sia nullo ma l'immagine dentro non ci sia, e poi aggiungi di disegnarla con altezza e larghezza WIDTH HEIGHT a meno che non sei sicuro che siano tutte e due 300

prototipo88
11-08-2010, 08:09
il codice del BIGMSG è lunghissimo, non lo metto che tanto non si capisce niente :) ... però praticamente salva un'array di byte che sarebbe la mia immagine da visualizzare con l'id nel sensore che la invia (BIGMSG.numero_nodo==8)...
però arriva tutto correttamente, ne sono certo, in quanto la prima immagine si vede bene... e il codice che arriva dopo è giusto... per questo motivo penso che il problema sia solo in questo file che ho postato...

quindi o sbaglio qualcosa nel layout, o sono le variabili... o non ne ho idea...
praticamente mi fa vedere solo la prima immagine e poi è come se si bloccasse... (non si aggiorna nemmeno la stessa immagine)

Aggiungo che nel file BIGMSG.java chiamo questo file così:



DemoImage show1 = new DemoImage();
if(primo==1){
show1.setJFrame();
primo=0;
}
show1.showImage();

tylerdurden83
11-08-2010, 11:13
Il codice che t'ho postato ti funziona no?

prototipo88
11-08-2010, 17:11
Il codice che t'ho postato ti funziona no?

si, il tuo codice funziona, mi fa vedere l'immagine nel pannello 5 e 6... però come faccio a implementarlo nel mio programma? nel senso che questo DemoImage.java ha un suo main, io il vero main lo voglio nel BIGMSG.java ... o va bene lo stesso avere 2 main diversi??
Dal BIGMSG.java richiamo la funzione così:
show1.showImage(nodo);
dove nodo è il numero del sensore che invia l'immagine, così da selezionare il pannello corretto... Però così non mi perdo tutta la parte del :

SwingUtilities.invokeLater(new Runnable() {
@Override public void run() {
DemoImage demoImage = new DemoImage();
demoImage.showImage(5);
demoImage.showImage(6);
}
});


il problema che ho ora è che mi si apre a ogni immagine che mi arriva una nuova finestra... quindi al termine del programma ho tanti jframe aperti...
come lo sistemo?
grazie

tylerdurden83
11-08-2010, 18:31
nel senso che questo DemoImage.java ha un suo main, io il vero main lo voglio nel BIGMSG.java ... o va bene lo stesso avere 2 main diversi??

Avere due main non è un problema, tanto sempre e solo uno è eseguito allo startup dell applicazione. Io avevo messo un main nella mia classe per lanciarla e testarla, puoi anche levarlo chiaramente.

Dove prima lanciavi

DemoImage show1 = new DemoImage();

adesso devi mettere


SwingUtilities.invokeLater(new Runnable() {
@Override public void run() {
DemoImage demoImage = new DemoImage();
}
});


Poi devi cambiare il mio metodo

public void showImage(int pannello) {...}

che ho messo in modo da prendere un int che rappresentava uno dei quattro pannelli e lo settava con una icona statica presa a caso dal mio pc perchè non avevo il codice di BIGMSG da cui far prendere l'id del pannello, l'immagine etc. Non dovresti avere problemi a modificarlo per usare il tuo codice.

Attenzione al BIGMSG, mi pare di capire che è una classe enorme che fa molte cose diverse, il che non è corretto. Anche la gui dovrebbe essere completamente slegata dal resto.

EDIT: rivedendo il tuo codice direi che show1.setJFrame(); era veramente superfluo, una volta inizializzato il frame non lo devi ricostruire tutte le volte, e se non è corretto che ne compaiano piu d'uno, penserei ad adottare il design pattern singleton