|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
[Java Swing] Canvas dentro JSplitPane
Salve a tutti, ho di nuovo un problema di interoperabilitá tra componenti AWT e Swing: ho inserito un JSplitPane (che splitta verticalmente) in un JFrame e ci ho messo dentro un Canvas AWT e una JTextArea, il primo sopra e la seconda sotto; il problema é che il Canvas si rifiuta di rimpicciolirsi: l'utente non riesce ad alzare lo splitter ma solo ad abbassarlo, ne' riesce a rimpicciolire tutto il JFrame perché questo provocherebbe un rimpicciolimento del Canvas
![]() naturalmente se invece del Canvas inserisco un JPanel funziona tutto regolarmente. qualcuno saprebbe dirmi se c'é modo di correggere anche questa cosa? ^^ di nuovo grazie! |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
ho dimenticato un dettaglio fondamentale: in fase di costruzione della GUI io ho chiamato Canvas.setPreferredSize per far si' che la chiamata pack() finale effettuata sul JFrame non mi riduca il Canvas al minimo. in altre parole io vorrei che all'avvio dell'applicazione il Canvas avesse una certa dimensione, ma anche che l'utente sia in grado di alzare lo splitter e di rimpicciolire il JFrame.
ari-grazie. |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
up :P
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
guarda, se non ricordo male era sconsigliato dalla sun stessa utilizzare componenti awt e swing insieme...
E tra l'altro ormai si dovrebbe usare solo swing. come mai hai questa necessità?
__________________
|
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
perché in realtá non si tratta propriamente di un Canvas ma di un GLCanvas di JOGL (che eredita Canvas). so che in JOGL esiste anche GLJPanel, ma questo invece é sconsigliato dal team di JOGL perché é meno performante
![]() e quindi se possibile volevo realizzare la mia GUI col GLCanvas. questo dovrebbe essere l'ultimo problema rimasto: oltre a questo avevo avuto solamente il problema relativo al fatto che il Canvas é heavyweight e nascondeva i menu. |
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
sicuro-sicuro sche sia ancora sconsigliato? Te lo chiedo perchè anni fa per realizzare un visualizzatore per modelli 3D per un software CAM abbiamo avuto la stessa neccessità per motivi di performance. In seguito poi, quando le JOGL sono diventate "più mature" anche in parallelo a miglioramenti lato Swing, siamo potuti passare alla versione con JPanel senza perdite di performance (ovvio che poi dipende da cosa devi renderizzare). Quindi fossi in te/voi proverei prima con il GLJPanel, e poi, solo dopo aver riscontrato effettiva perdita di performance (e aver verificato con un profiler quale è l'effettivo collo di bottiglia, altra lezione imparata sulla mia pelle) come sicuramente imputabile al GLJPanel lo sostituite con GLCanvas. In questo secondo caso dovrete escogitare una qualche strategia per integrarlo nella UI minimizzando i problemi di interoperabilità che avvengono quando si mescolano componenti Swing con componenti AWT (maggiori informazioni in tal senso le trovi spluciando sul sito della Sun, altrimenti, se ti servissero me lo dici via pvt che ti scrivo quache indicazione di massima).
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 28-10-2009 alle 10:18. |
|
|
|
|
|
|
#7 | ||
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
leggendo le guide varie vedo che ora la situazione é migliorata, ma le performances non sono ancora comparabili. il motivo é che JPanel (da cui eredita GLJPanel) é un componente lightweight e come tale non ha una finestra nativa (tipicamente in ambiente nativo per fare rendering con OpenGL serve una finestra nativa dedicata sulla quale si possa fare solo quello e non si possa renderizzare nient'altro), e se a questo aggiungi che un JPanel debba opzionalmente anche poter essere reso parzialmente trasparente la soluzione piu ragionevole per il team di JOGL é stata che quando disegni su un GLJPanel non disegni direttamente su schermo, ma viene prelevato il contenuto del frame buffer con glReadPixels o analoga e tale contenuto viene poi renderizzato sul GLJPanel con le eventuali semitrasparenze. questa soluzione, ragionevolissima, é inerentemente meno performante del funzionamento di un Canvas, per quanto si possa ottimizzare.
Quote:
![]() specialmente dopo essere stato incoraggiato dall'incredibile semplicitá con cui mi hai fatto risolvere il problema dei menu che erano nascosti dal Canvas Quote:
per i motivi di cui sopra mi interesserebbe molto leggere qualcuna di queste strategie
|
||
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
In pvt era perchè mi sarei trovato agevolato a scambiare con te del codice senza troppi patemi. Comunque, a prescindere da queste considerazioni, vorrei che facessimo un passo indietro, se per te va bene. Ho cercato di ricostruire la situazione che hai descritto: frame contentente uno JSplitPane che splitta verticalmente due componenti, uno AWT e uno Swing. Ho di proposito "ignorato" che il componete AWT è un GLCanvas. Ho usato invece un java.awt.Panel. Ho anche aggiunto un menu, per far vedere, aprendolo, che il componente posizionato più in alto è efettivamente un componente AWT, con tutte le conseguenze del caso. Ecco il codice: Codice:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Label;
import java.awt.Panel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
/**
* @author francesco
*/
public class SplitAWTComponent extends JFrame
{
public static void main(String... args) {
SplitAWTComponent frame = new SplitAWTComponent("Splitting Swing and AWT components");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(500, 400);
frame.setVisible(true);
}
public SplitAWTComponent(String title) {
super(title);
initialize();
}
private void initialize() {
// add a menu to the frame
JMenuBar menu = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenuItem fileItem1 = new JMenuItem("Item1");
JMenuItem fileItem2 = new JMenuItem("Item2");
fileMenu.add(fileItem1);
fileMenu.add(fileItem2);
menu.add(fileMenu);
this.setJMenuBar(menu);
// create red AWT Panel
Panel awtPanel = new Panel();
Label awtlabel = new Label("Questo è un java.awt.Panel");
awtPanel.add(awtlabel);
awtPanel.setBackground(Color.red.darker());
awtPanel.setMinimumSize(new Dimension(0,0));
// create blue Swing JPanel
JPanel swingPanel = new JPanel();
JLabel swinglabel = new JLabel("Questo è un javax.swing.JPanel");
swingPanel.add(swinglabel);
swingPanel.setBackground(Color.blue);
swingPanel.setMinimumSize(new Dimension(0,0));
// create vertical JSplitter for red and blue panels
JSplitPane splitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT, awtPanel, swingPanel);
splitter.setDividerLocation(0.5);
splitter.setContinuousLayout(true);
splitter.setOneTouchExpandable(true);
this.add(splitter, BorderLayout.CENTER);
}
}
Le cose da notare (in grassetto), sono le seguenti: 1) L'unico componente a cui viene esplicitamente impostata la dimensione (size) è il frame. 2) I pannelli sono inseriti direttamente nel frame, e il layout manager conivolto e' quello di default per JFrame (BorderLayout). 3) Ai pannelli inseriti viene imposta una minimumSize pari a zero: la minimumSize funge da limite per lo splitter, mettendola a zero si dice che si vuole che lo splitter possa estendersi fino a far "sparire"/"coprire completamente" quel componente. Se invece sostiuissimo il blocco che crea il java.awt.Panel con un Canvas: Codice:
...
// create red AWT Canvas
Canvas awtCanvas = new Canvas(){
@Override
public void paint(Graphics g) {
g.setColor(Color.green.darker());
g.drawString("Questo è un javax.awt.Canvas", 15, 20);
}
};
awtCanvas.setBackground(Color.red.darker());
awtCanvas.setMinimumSize(new Dimension(0,0));
...
...
// create vertical JSplitter for red and blue panels
// JSplitPane splitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT, awtPanel, swingPanel);
JSplitPane splitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT, awtCanvas, swingPanel);
Quindi il tuo problema sembra più aver a che fare con il setting delle dimensioni (preferredSize/minimum-maximumSize) e i componenti contenitori (JSplitPane) e i layout manager coinvolti tra loro che altro. Per le guidelines da seguire quando si integrano tra loro ligthweight e heavyweight components c'era qualcosa sul sito sun.java ora non riesco più a trovarlo ma a casa ho delle informazioni che posso postarti domani. P.S.: questa volta non ti ho potuto dare una risposta secca perchè la faccenda non è completamente chiara neanche a me, sto ancora studiando le Swing in dettaglio (finalmente con un libro, come si deve) e nell'applicativo CAM di cui sopra il problema era di un altro tipo (la sovvraposizione tra heavyw. e lightw.) ed era stato rimosso in modo semplice & brutale (relegando il viewer 3D in un pannello non ridimensionabile posizionato in alto a destra della finestra, funzionava come una sorta di preview, si poteva poi aprire una finestra dedicata solo per il GLCanvas e pochi altri componenti light affiancati, anche questa non ridimensionabile). P.P.S.: qui trovi indicazioni su come usare uno split pane e settare i componenti coinvolti P.P.P.S.: ho provato pure settando la preferredSize per i due pannelli contenuti e non impostando la size del frame contenitore e invocando un pack(): funziona tutto come ti ho descritto e non riscontro il problema che hai segnalato.
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 29-10-2009 alle 11:32. |
|
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
EDIT:
Aggiungo una considerazione, a quanto dici qua:
Quote:
Se poi, POI, viene riscontrato che le performance di rendering vanno migliorate profili l'esecuzione del rendering per CAPIRE esattamente cosa causa la perdita di performance. Se si verificasse questo scenario potrebbe anche saltare fuori facilmente che il problema non è l'uso del GLJPanel versus GLCanvas. Ci sono un sacco di altre cose che posso essere il collo di bottiglia. Il modo in cui è stato implementato il rendering, ad esempio. GLi oggetti coinvolti. Il tipo di Animator scelto per schedulare il rendering Io, se fossi al tuo posto, userei fin da subito GLCanvas se e solo se fossi assolutamente sicuro che è strettamente neccessario.
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 29-10-2009 alle 11:21. |
|
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Fero, eccoti il link che spiega le 4 regole da tenere presente quando si costruiscono interfacce composte sia da componenti AWT che Swing:
- Mixing heavy and light components Dentro c'è un link che punta ad un articolo più recente (2009). Ancora più importante, fero86, non so se hai mai letto questa pagina. In particolare guarda il paragrafo sotto il titolo "Heavyweight and Lightweight Issues", sembra che sia *esattamente* quello che vi serve per risolvere le questioni di resize che affliggono il vostro GLCanvas.
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 30-10-2009 alle 09:41. |
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
Quote:
che poi quella pagina me la saró scorsa un sacco di volte in passato, e ora che mi servivano alcune nozioni in essa contenute l'ho lisciata completamente ![]() poi quando ho tempo cerco la soluzione migliore e la provo; intanto sentitamente grazie |
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
ma il post #8 si é possentemente ingigantito con l'ultimo edit? :|
ora sono di fretta ma quando ci ritorno lo leggo; grazie moltissime per l'interesse!! ciao |
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
banryu79, ho letto il post #8: grazie per l'interesse!
se me l'avessi chiesto avrei postato io del codice. ho consultato la tua ricostruzione e in base a quella ho provato ad aggiungere una chiamata setMinimumSize(new Dimension(0, 0)) sul GLCanvas e ora funziona egregiamente! |
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Prego
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 09:54.






















