PDA

View Full Version : problema Java Swing


thomasBis
23-01-2012, 18:15
Salve, ho un problema realizzando l'interfaccia grafica di un piccolo gioco in Java.. vorrei adattare dinamicamente le dimensioni del JPanel al JFrame, nel senso che, quando creo il mio frame, questo ha una sua dimensione, ma quando lo estendo a tutto schermo, il panel rimane alla sua dimensione originale attaccandosi all'angolo superiore sinistro! come posso fare?
Grazie mille.. premetto che sto studiando da autodidatta le librerie Swing da poco!

banryu79
24-01-2012, 08:03
Puoi postare lo spezzone di codice dove crei il frame, istanzi il panel e lo infili nel frame? Comunque di default, il layout manager di un JFrame è una istanza di BorderLayout, e se ci infili un componente senza specifiarne esplicitamente la posizione, viene aggiunto in posizione BorderLayout.Center, il che causa il ridimensionamento dinamico del componente fino all'occupazione di tutta la superficie disponibile (al netto di eventuali altri componenti nelle posizioni North, East, South e West).

thomasBis
24-01-2012, 08:55
// classe che crea il JPanel
public class background extends JPanel {

private static final long serialVersionUID = 6679038779869120082L;
private Image _image;
private int _x1;
private int _y1;


public background(Image _image, int _x, int _y) {
super();
this._image = _image;
this._x1 = _x;
this._y1 = _y;
}

public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(_image, 0, 0, _x1, _y1,this);
}
}

// classe JFrame in cui istanzio il mio background
public class MainFrame extends JFrame {

private static final long serialVersionUID = 1L;
private Image _image;
private int _x = 1614;
private int _y = 814;
JMenuBar menuBar;

public MainFrame() {

super("blabla");
setSize(1625,1014);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);

try {
_image = ImageIO.read(new File ("C:/Users/...etc.etc."));
JPanel panel = new background(_image, _x, _y);
setContentPane(panel);
panel.setLayout(null);

menuBar = new JMenuBar();
menuBar.setBounds(137, 117, 22, 20);
panel.add(menuBar);

JMenu mnNewMenu = new JMenu("");
mnNewMenu.setPreferredSize(new Dimension(22, 20));
menuBar.add(mnNewMenu);

JMenuItem mntmNewMenuItem = new JMenuItem("prova1");
mnNewMenu.add(mntmNewMenuItem);

JMenuItem mntmNewMenuItem_1 = new JMenuItem("prova2");
mnNewMenu.add(mntmNewMenuItem_1);

}
catch (Exception e) {
e.printStackTrace();
}

}

}

come vedi ho impostato il layout su "absolute".. con questo codice, nel momento in cui ingradisco il frame con il classico pulsante "Ingrandisci" di Windows, il JPanel si riposiziona con le sue dimensioni originali in alto a sinistra!
Grazie mille :)

banryu79
24-01-2012, 10:44
Non avendo specificato un layout manager per il frame, esso è di default un BorderLayout, come ti spiegavo sopra. Il tuo JPanel (background) viene aggiunto nel frame senza specificare la posizione, quindi viene inserito nella posizione in BorderLayout.Center (sempre come detto sopra):

JPanel panel = new background(_image, _x, _y);
setContentPane(panel);


Ergo: il tuo pannello si ridimensiona dinamicamente.
A te non sembra solo perchè l'immagine che disegni come sfondo viene sempre disegnata, rispetto al pannello che la contiene, dentro un rettangolo in posizione X0 Y0 di larghezza e altezza fissate (_x, _y).

public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(_image, 0, 0, _x1, _y1,this);
}

Che il frame sia a tutto schemo o sia piccolo non cambia il fatto che tu disegni quella immagine sempre in un rettangolo x0, y0, di larghezza _x e altezza _y.

Te ne puoi rendere conto ad esempio impostando il colore rosso come sfondo del tuo background:

JPanel panel = new background(_image, _x, _y);
background.setBackground(Color.red);
setContentPane(panel);

thomasBis
24-01-2012, 10:56
Ok, ora mi è chiaro.. allora come dovrei fare per ingrandire anche il panel? si può fissare come dimensione la Size del frame in modo che si modifichi automaticamente?
Thanks :help:

banryu79
24-01-2012, 11:04
Ok, ora mi è chiaro.. allora come dovrei fare per ingrandire anche il panel? si può fissare come dimensione la Size del frame in modo che si modifichi automaticamente?
Thanks :help:
No, credo che non ti sia ancora chiaro al 100%.
Per come hai definito:
1) il tipo di layout manager del frame [BorderLayout]
2) la posizione di inserimento del pannello nel layout manager del frame [BorderLayout.CENTER]
il pannello si ridimensiona già dinamicamente al ridimensionarsi del frame.

Il problema è che tu poi disegni l'immagine sempre con le stesse dimensioni, a prescindere da quanto è largo e alto il pannello in quel momento.
Non so se ora è più chiaro.

Comunque, per ottenere le dimensioni di un componente, basta invocare il metodo getSize sul componente stesso :)
Poi non so in che posizione vuoi avere la menubar, ma se per caso la vuoi nella posizione tipica che occupa nelle finestre standard a cui simao abituati (in alto), basta che, invece di inserirla nel pannello dopo averle settato esplicitamente i bounds, la inserisci (senza averle settato i bounds) nel frame con frame.setMenuBar(menuBar)...

thomasBis
24-01-2012, 15:10
Ora mi è tutto più chiaro, però il problema che persiste è:
anche se io con un getSize() ottengo le dimensioni del mio JFrame, poi come posso far si che l'oggetto 'panel' ricostruisca l'immagine con le nuove dimensioni una volta ingrandito il frame? in pratica per trovare una soluzione dovrei sapere cosa succede quando clicco su "ingrandisci", cioè se posso implementare una sorta di listener che mi cambi le dimensioni di caricamento dell'immagine!

:help:

banryu79
24-01-2012, 15:56
Non occorre che prendi le dimensioni del frame, basta chre prendi le dimensione del pannello con un getSize/getWidth/getHeight (visto che, come detto sopra, il pannello è sempre esteso) subito prima di disegnare l'immagine (ovvero nel metodo paintComponet del pannello stesso). Ad esempio:

public void paintComponent(Graphics g) {
super.paintComponent(g);
int width = this.getWidth();
int height = this.getHeight();
g.drawImage(_image, 0, 0, width, height, this);
}


Poi bisogna vedere se il risultato è gradevole, dato che questa operazione forza l'immagine a essere scalata alle dimensioni rettangolari specificate come parametri nella chiamata a drawImage.

thomasBis
24-01-2012, 23:10
GRAZIE MILLE :D sono riuscito a risolvere questo bel grattacapo!