View Full Version : [JAVA-Swing] setTooltipText buggato dopo aver effettuato una deserializzazione
tylerdurden83
01-03-2011, 21:30
Ciao a tutti raga, rieccomi di nuovo con un problema da :mc: :mc:
Posto un pezzetto di codice...
Il background loader per caricare un'istanza di un Player da file. Player naturalmente implementa serializable:
private class LoadPlayerTask extends org.jdesktop.application.Task<Object, Void> {
private FileContents fileContents = null;
LoadPlayerTask(org.jdesktop.application.Application app) {
super(app);
FileOpenService fos = null;
fos = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
this.fileContents = fos.openFileDialog(null, null);
}
@Override protected Player doInBackground() {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(this.fileContents.getInputStream());
Object o = ois.readObject();
Player p = (Player)o;
return p;
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if(ois!=null){
try {
ois.close();
} catch (IOException ex) {}
}
}
return null;
}
@Override protected void succeeded(Object result) {
try {
if (this.get() != null) {
Player p = (Player)this.get();
OutputFrameView outputFrame = new OutputFrameView();
outputFrame.setVisible(true);
outputFrame.setSlotIconAndTooltip(p);
outputFrame.setComputationResult(p);
} else {
JOptionPane.showMessageDialog(null,
"Error loading the selected Player.",
"Error",
JOptionPane.ERROR_MESSAGE);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Per chiudere il giro, un pezzo del codice di OutputFrameView:
private void setSlotIconAndTooltip(GearSlots gearSlot, Item item){
// assign a value to imageIcon and borderIcon ...
if(gearSlot.compareTo(WoWConstants.GearSlots.HEAD)==0 && item.getItemId()!=-1){
this.headIcon.setIcon(imageIcon);
this.headBorderIcon.setIcon(borderIcon);
this.headIcon.setToolTipText("Lightning Flash Pendant");
}
// ....
}
Il bug è il seguente:
this.headIcon.setToolTipText("Lightning Flash Pendant"); funziona this.headIcon.setToolTipText("<html><body>Lightning Flash Pendant</body></html>"); NON funziona
In pratica, settare html tooltips non funziona più dopo aver deserializzato un oggetto...
Non so più che pesci prendere...
Rob
banryu79
02-03-2011, 10:05
In pratica, settare html tooltips non funziona più dopo aver deserializzato un oggetto...
Ma la stringa da dove salta fuori?
Da un Item, a sua volta serializzato con Player?
Ammesso che la serializzazione di Player sia implementata correttamente: prova a controllare/stampare i campi di un Player prima di serializzarlo e dopo averlo deserializzato.
Hai provato a controllare quello che succede in modalità debug?
Inoltre "non funziona più" è un po' generico, cosa succede di preciso? Viene lancaiata qualche eccezione? Semplicemente non c'è il tooltip? Boh...
tylerdurden83
02-03-2011, 13:12
Ma la stringa da dove salta fuori?
Da un Item, a sua volta serializzato con Player?
Yes.
Ammesso che la serializzazione di Player sia implementata correttamente: prova a controllare/stampare i campi di un Player prima di serializzarlo e dopo averlo deserializzato.
Player è deserializzato perfettamente, stampando la stringa che viene data in pasto a setTooltipText vedo esattamente la stringa che c'era prima di serializzare/deserializzare, e aprendola dentro un browser come pagina html è perfettamente "formata".
Hai provato a controllare quello che succede in modalità debug?
Inoltre "non funziona più" è un po' generico, cosa succede di preciso? Viene lancaiata qualche eccezione? Semplicemente non c'è il tooltip? Boh...
Nessuna eccezione, semplicemente setTooltipText non funziona più (non compare nessun tooltip) nel caso ho deserializzato qualcosa e solo se passo html a settooltiptext, se passo un text normale funziona ancora.
Ho fatto un video per mostrarti il problema:http://www.youtube.com/watch?v=01TDZTr7mN4
Quello che vedrai nel video:
1) creo un Player e lo serializzo/salvo su hd
2) se riapro il software e deserializzo il player come prima azione, set tooltip text con in pasto html è definitivamente broken
3) se prima chiamo set tooltip text con in pasto html, e poi deserializzo, non smette di funzionare
banryu79
02-03-2011, 13:24
Sto andando a pranzo, se ho tempo dopo do un'occhiata.
Però penso che non sia la serailizzazione/deserializzazione di Player il problema (ammesso che serializzare Player non significhi serializzare componenti grafici Swing).
Forse il problema sta nell'inizializzazione/funzionamento di un componente Swing (il tooltip) quando la sua proprety "text" è testo normale contro testo formattato html.
Magari le due cose sono mutuamente esclusive: indagherei in questa direzione.
tylerdurden83
03-03-2011, 01:23
(ammesso che serializzare Player non significhi serializzare componenti grafici Swing).
No, nessun componente grafico.
Forse il problema sta nell'inizializzazione/funzionamento di un componente Swing (il tooltip) quando la sua proprety "text" è testo normale contro testo formattato html.
Magari le due cose sono mutuamente esclusive: indagherei in questa direzione.
Non sono sicuro di seguirti, ma continuo a non capire cosa cambi tra il chiamare setTooltipText, deserializzare, e richiamarlo (così funziona), rispetto a deserializzare e chiamarlo (cosi diventa broken fino a che non chiudo l'applicazione)....
banryu79
03-03-2011, 15:54
Ho fatto un video per mostrarti il problema:http://www.youtube.com/watch?v=01TDZTr7mN4
Quello che vedrai nel video:
1) creo un Player e lo serializzo/salvo su hd
2) se riapro il software e deserializzo il player come prima azione, set tooltip text con in pasto html è definitivamente broken
3) se prima chiamo set tooltip text con in pasto html, e poi deserializzo, non smette di funzionare
Ciao, ho visto il video.
Ho una perplessità nata dall'osservazione del 2° e del 3° (e ultimo) run che fai dell'applicativo.
La situazione di partenza comune ai due run è che
- l'applicazione ha già girato almeno una volta
- il file con il player serializzato è presente sul disco locale
- l'applicazione non è in esecuzione
Nel 2° run io vedo questo:
- lanci l'applicazione
- carichi il player
> nella finestra [Optimal Setup] mancano i tooltip alle immagini e manca anche il testo nell'area centrale
- lanci la ricerca [SEARCH]
> vengono visualizzate le row ma mancano i tooltip e anche i testi nelle celle
Nel 3° run invece vedo questo:
- lanci l'applicazione
- lanci la ricerca [SEARCH]
> viene visualizzato il risultato della ricerca correttamente
- carichi il player
> viene visualizzata la finestra [Optimal Search] normalmente
Da queste osservazioni io ho l'impressione che il problema non riguardi strettamente i tooltip in formato html e la sua deserializzazione... (il 3° run mostra come una semplice inversione di due operazioni renda funzionante quello che nel 2° run non funziona, a parità di condizioni e sempre se non mi sono perso qualcosa).
tylerdurden83
03-03-2011, 18:41
Lo pensavo anche io! Tuttavia:
1) stampando quello che passo a setTooltipText, vedo la stringa corretta
2) ho sostituito this.headIcon.setToolTipText(tooltip); con this.headIcon.setToolTipText("Lightning Flash Pendant"); e this.neckIcon.setToolTipText(tooltip); con this.neckIcon.setToolTipText("<html><body>Lightning Flash Pendant</body></html>");. In pratica, non uso per niente l'oggetto deserializzato, ma setto i tooltip a delle stringhe costanti. Quella senza tag html va, l'altra no...
Guarda questo bug (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6332297)
Li dice:
This class demonstrates 2 bugs in JRE 5.0 update 5. The first bug occurs when you Java serialize a component. The tool tip associated with the component is lost. The second bug occurs when you deserialize a component. The tool tip associated with the component is lost. To witness the behavior, run this class with no arguments. 3 windows will pop up with descriptive title bar's. The original window will have a button with a working tool tip. The middle window is a new window which has been serialized. The tool tips don't work on this one. The third is the reserialization of the second window. Tools tips don't work here either. I believe the first bug could be fixed by adding a ToolTipManager.registerComponent call to the end of the JComponent.writeObject method. I believe the second bug could be fixed by moving the call tooolTipManager->registerComponent, inside JComponent.readObject, after the client properties have been read.
Ho lanciato il suo esempio, in realtà a me il primo e terzo frame visualizzano il tooltip correttamente (prob fixato in una versione più recente di java), ma il secondo frame continua a non visualizzare nulla. Potrebbe essere legato al mio problema magari
banryu79
03-03-2011, 20:14
Ho provato anche io a lanciare l'esempio del bug:
- tooltip prima finestra va (deve andare)
- tooltip seconda finestra che è appena stat serializzata non va
- tooltip terza finestra che è la deserializzazione della seconda va
Potrebbe essere legato al mio problema magari
Non lo credo, per vari motivi.
Primo, il bug è "fix-released" il che vuol dire che è stato sistemato,
Secondo, nel tuo caso non c'è alcuna serializzazione di componenti grafici (il tool tip non viene serializzato) stando a quanto hai detto, quindi non rientra nel caso preso in esame da quel vecchio bug.
E terzo, come ho riportato sopra, a parità di condizioni (2° e 3° caso illustrati dal tuo video, che lavorano con un Player deserializzato) in un caso funziona, nell'altro no e la differenza tra i due casi è l'ordine di esecuzione delle operazioni.
Per non parlare del fatto che nel tuo caso non sono solo i tooltip a non funzionare!
tylerdurden83
03-03-2011, 22:06
doppio post...
tylerdurden83
03-03-2011, 22:07
Primo, il bug è "fix-released" il che vuol dire che è stato sistemato,
Tanto sistemato non mi pare, il secondo dei tre frame è ancora buggato.
Per non parlare del fatto che nel tuo caso non sono solo i tooltip a non funzionare!
Si si sono solo i tooltip/renderer e solo se prendono html in input (persino una string statica, se tra html tag, non va), il resto va tutto.
banryu79
03-03-2011, 22:20
Tanto sistemato non mi pare, il secondo dei tre frame è ancora buggato.
Si si sono solo i tooltip/renderer e solo se prendono html in input (persino una string statica, se tra html tag, non va), il resto va tutto.
D'accordo, ma ripeto, tu non serializzi per poi deserializzare il tooltip, non rientri nella casistica descritta dal bug, sei d'accordo?
E se inverti l'ordine con cui esegui le due operazioni al run 2 il problema non si manifesta (testimoniato nel run3) o no?
Puoi chiarire questi due punti per picere, sennò non riesco a seguirti :(
tylerdurden83
03-03-2011, 22:35
D'accordo, ma ripeto, tu non serializzi per poi deserializzare il tooltip, non rientri nella casistica descritta dal bug, sei d'accordo?
E se inverti l'ordine con cui esegui le due operazioni al run 2 il problema non si manifesta (testimoniato nel run3) o no?
Puoi chiarire questi due punti per picere, sennò non riesco a seguirti :(
No non deserializzo jcomponent o similia.
Corretto, se prima kiamo set tooltip text va, se prima deserializzo, non va piu.
Cosa puo far si che settooltiptext con una stringa html ben formata non abbia alcun effetto (tantomeno eccezione)?
tylerdurden83
04-03-2011, 01:14
Ho fatto un altro esempio e video ancora piu esplicativo.
Codice:
package varioustests;
import java.awt.*;
import java.io.*;
import javax.jnlp.*;
import javax.swing.*;
import wowgearoptimizer.model.Player;
import wowgearoptimizer.wowconstants.WoWConstants.GearSlots;
public class MyToolTipTest extends JFrame {
public static int positionOffset = 0;
public MyToolTipTest (String id) {
setTitle("Tool Tip Test: ");
JButton button = new JButton ("This is a button with tool tip text: ");
getContentPane().add(button);
button.setToolTipText(id);
getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER));
pack();
setVisible(true);
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
positionWindow();
}
public void positionWindow (){
Point position = new Point(positionOffset, positionOffset);
positionOffset += 100;
setLocation (position);
}
static void ThisWorks(){
try {
MyToolTipTest toolTipTest1 = new MyToolTipTest("<html><body>tooltip con html</body></html>");
Thread.sleep(6000L);
FileOpenService fos = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
FileContents fileContents = fos.openFileDialog(null, null);
ObjectInputStream ois2 = new ObjectInputStream(fileContents.getInputStream());
Player player2 = (Player) ois2.readObject();
MyToolTipTest toolTipTest2 = new MyToolTipTest(player2.getItemForGearSlot(GearSlots.CHEST).getCurrentTooltip());
MyToolTipTest toolTipTest3 = new MyToolTipTest("tooltip senza html");
MyToolTipTest toolTipTest4 = new MyToolTipTest("<html><body>tooltip con html</body></html>");
} catch (Exception ex) {
ex.printStackTrace();
}
}
static void ThisDoesntWork(){
try {
FileOpenService fos = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
FileContents fileContents = fos.openFileDialog(null, null);
ObjectInputStream ois2 = new ObjectInputStream(fileContents.getInputStream());
Player player2 = (Player) ois2.readObject();
MyToolTipTest toolTipTest1 = new MyToolTipTest(player2.getItemForGearSlot(GearSlots.CHEST).getCurrentTooltip());
MyToolTipTest toolTipTest2 = new MyToolTipTest("tooltip senza html");
MyToolTipTest toolTipTest3 = new MyToolTipTest("<html><body>tooltip con html</body></html>");
} catch (Exception ex) {
ex.printStackTrace();
}
}
static public void main(String args[]){
//ThisWorks();
ThisDoesntWork();
}
}
E video (http://www.youtube.com/watch?v=h6LpRDXkNEo)di cosa succede...
Usa XMLEncoder/Decoder per serializzare i componenti swing. Se vuoi personalizzarli con delle proprietà ad hoc, basta che le "bean-izzi"
tylerdurden83
04-03-2011, 01:32
Non sto (de)serializzando componenti swing però...
tylerdurden83
04-03-2011, 01:54
static void ThisAlsoWorks(){
try {
String message = "<html><body>This is my serialized object</body></html>";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(message);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream oins = new ObjectInputStream(bais);
Object o = oins.readObject();
MyToolTipTest2 toolTipTest = new MyToolTipTest2(message);
Thread.sleep(5000L);
FileOpenService fos = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
FileContents fileContents = fos.openFileDialog(null, null);
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
ObjectOutputStream oos2 = new ObjectOutputStream(baos2);
oos2.writeObject(message);
ByteArrayInputStream bais2 = new ByteArrayInputStream(baos2.toByteArray());
ObjectInputStream oins2 = new ObjectInputStream(bais2);
Object o2 = oins2.readObject();
MyToolTipTest2 toolTipTest2 = new MyToolTipTest2(message);
} catch (Exception ex) {
ex.printStackTrace();
}
}
E' ufficiale, è un bug di FileContents :)
Da questo esempio che tutti possono lanciare si nota come se si va sul primo frame prima che il thread.sleep termina, il tooltip compare correttamente. Poi compare il file chooser, si sceglie un file a caso tanto non è usato, e poi compare il secondo frame. Tutti e due con tooltip funzionanti.
Tuttavia, se non si mousehover il primo frame prima che la thread.sleep termina e il file chooser compare, entrambi i frame non avranno mai i tooltip visualizzati.
Video dimostrativo (http://www.youtube.com/watch?v=bpuFB_RmuMQ)
banryu79
04-03-2011, 09:54
E' ufficiale, è un bug di FileContents :)
Mi spiace, non conosco jnlp, quindi non riesco a immaginare quale sia il problema.
Però adesso hai un punto di riferimento preciso dal quale partire per trovare un workaround.
P.S.: bella la GUI del tuo applicativo :)
tylerdurden83
04-03-2011, 12:09
Mi spiace, non conosco jnlp, quindi non riesco a immaginare quale sia il problema.
Però adesso hai un punto di riferimento preciso dal quale partire per trovare un workaround.
P.S.: bella la GUI del tuo applicativo :)
Grazie! Ora switcho su nimbus look and feel però perchè sytem mi sta dando dei problemi su ubuntu etc!
Penso ci sia poco da fare in realtà, sto usando l'ultimo jar con quella classe. Non riesco più a trovare dove aprire bug da quando oracle ha acquistato sun... Vuoi vedere che ti apro persino un bug!
vBulletin® v3.6.4, Copyright ©2000-2026, Jelsoft Enterprises Ltd.