PDA

View Full Version : [java] creare 4 jpanel con immagini differenti


prototipo88
30-07-2010, 20:31
ciao a tutti,
volevo sapere come faccio a creare 4 jpanel differenti posti in un unico jframe e poi caricare immagini differenti per ogni jpanel...
praticamente a ogni messaggio che mi arriva, leggo l'id del messaggio e in base a questo id cambio l'immagine del jpanel corrispondente... ora ho un unico jpanel e ogni vvolta che mi arriva un messaggio mi si cancella l'iimagine precedente e viene ricreata quella nuova (penso che venga creto un nuovo jpanel tutte le volte, non va bene!!!)...
scusate ma non ne capisco molto di java...


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 static ImagePanel panel;
//public JPanel panel = new JPanel();
public ImagePanel panel;


public void setJFrame() {


frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(WIDTH, HEIGHT);
frame.setResizable(true);
frame.setLocationRelativeTo(null);
frame.validate();
frame.setVisible(true);
}

public void showImage() {

panel= new ImagePanel(BIGMSG.image); //corretta!!! legge l'immagine dai byte
//JPanel panel = new JPanel();

frame.getContentPane().add(panel, BorderLayout.CENTER);
panel.setVisible(true); //se false,no si vede niente

panel.setDoubleBuffered(true);// ??? forse serve per una specie di buffer, mi fa vedere tutte le immagini e non solo la fragola
panel.setBackground(Color.white);
panel.setBorder(BorderFactory.createLineBorder(Color.black));
panel.setOpaque(true);

}

}

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();
}


public void paintComponent(Graphics g)
{
if(image!=null){
super.paintComponent(g);
g.drawImage(image,BIGMSG.numero_nodo*30,BIGMSG.numero_nodo*30,null);

}

}

}



grazie a tutti

MEMon
31-07-2010, 09:29
Crei un array di ImagePanel e li aggiungi al jframe (usi il layout che ti pare).
Quando ti arriva il messaggio usi l'id per prendere il pannello giusto dall'array e chiami resetImage.

prototipo88
02-08-2010, 01:14
ciao, grazie per avermi risposto... ho cercato di fare come hai detto... e il risultato è questo... funziona tutto tranne che se BIGMSG.numero_nodo == 6, non mi fa visualizzare l'immagine... mah???


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);

}

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
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==5){ //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();


}




public void paintComponent(Graphics g)
{
if(image!=null){
super.paintComponent(g);
g.drawImage(image,10,10,null);

}

}

}

banryu79
02-08-2010, 09:24
ciao, grazie per avermi risposto... ho cercato di fare come hai detto... e il risultato è questo... funziona tutto tranne che se BIGMSG.numero_nodo == 6, non mi fa visualizzare l'immagine... mah???

Bisognerebbe vedere come viene usato questo BIGMSG, al di la del codice che vediamo noi qui.
Comunque ho provato a copia-incollare il codice che hai postato nell'ultimo tuo post.

In ogni caso bisogna assicurasi di far corrispondere esattamente ad ogni valore di BIGMSG.numero_nodo un preciso ImagePanel, cosa che nel tuo codice, forse per la fretta di postare, non mi sembra fosse stato fatto.
Prova a dare un occhio alla modifica al metodo showImage: ora c'è un controllo sui valori attesi di BIGMSG.numero_nodo che se fallisce lancia un'eccezione "parlante" (riporta il valore inatteso).
Questo se sai e vuoi che arrivino solo numeri_nodo con quei 4 valori e che se ne arriva uno diverso è un errore/una cosa che non deve succedere mai.
Se invece vuoi permettere che arrivino numeri_nodo con valori non compresi trai i 4, e in questo caso vuoi semplicemente ignorare il
BIGMSG e non aggiornare gli ImagePanel basta che nell'ultimo else invece di lanciare l'eccezione esci dal metodo con una istruzione 'return'.

Ci sono almeno due aspetti che andavano corretti (colorati in marroncino):
- la sequenza di realizzazione del frame e sua esecuzione nell'event dispatching thread;
- la chiamata a super.paintComponent nell'override del metodo paintComponent ereditato da JComponent in ImagePanel.



import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class DemoImage extends JFrame
{
public static JFrame frame = new JFrame("My JFrame");
public static int _WIDTH = 300;
public static int _HEIGHT = 300;

private ImagePanel panel1;
private ImagePanel panel2;
private ImagePanel panel3;
private ImagePanel panel4;

public void setJFrame() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(_WIDTH, _HEIGHT);
frame.setResizable(true);

// imposta layout finestra:
Container contentPane = frame.getContentPane();
contentPane.setLayout(new GridLayout(2,2));

// crea & aggiunge i 4 ImagePanel:
panel1 = createImagePanelAndAddInto(contentPane);
panel2 = createImagePanelAndAddInto(contentPane);
panel3 = createImagePanelAndAddInto(contentPane);
panel4 = createImagePanelAndAddInto(contentPane);

// realizza & mostra la finestra:
EventQueue.invokeLater(new Runnable() {
public void run() {
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

// Metodo utile per creare, inizializzare e aggiungere ciascuno
// dei 4 ImagePanel alla finestra demo.
private ImagePanel createImagePanelAndAddInto(Container contentPane) {
ImagePanel p = new ImagePanel("");
p.setDoubleBuffered(true);
p.setBackground(Color.white);
p.setBorder(BorderFactory.createLineBorder(Color.black));

contentPane.add(p);
return p;
}

// Aggiorna l'ImagePanel corretto con la nuova immagine.
// BIGMSG contiene sia l'id del pannello da aggiornare
// che l'immagine.
public void showImage() {
ImagePanel panel = null;
Image image = BIGMSG.image;
int nNodo = BIGMSG.numero_nodo;

// selezione pannello:
if (nNodo == 5) {
panel = panel1;
}
else if (nNodo == 6) {
panel = panel2;
}
else if (nNodo == 7) {
panel = panel3;
}
else if (nNodo == 8) {
panel = panel4;
}
else {
throw new IllegalArgumentException("Unexpected BIGMSG.numero_nodo argument: "+nNodo);
}

panel.resetImage(image);
panel.revalidate();
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);
}
}
}

prototipo88
02-08-2010, 09:43
grazie mille!!!! molto gentile