2012-03-01 8 views
12

Sto cercando di mostrare immagini multiple in tooltip di un componente, trovato createToolTip() e implementato un personalizzato che aggiunge i componenti necessari in questo modo:Java personalizzato punta dell'utensile con componenti Swing come contenuto non rivela

setComponent(component); 

JPanel images = new JPanel(null); 
images.setLayout(new BoxLayout(images, BoxLayout.X_AXIS)); 
for(ImageIcon icon:myIcons) { 
    images.add(new JLabel(icon)); 
} 

JPanel content = new JPanel(new BorderLayout()); 
content.add(new JLabel(title), BorderLayout.NORTH); 
content.add(new JLabel(description)); 
content.add(images, BorderLayout.SOUTH); 

add(content); 

Tuttavia, tutto quello che vedo è un piccolo punto, che indica che la punta dello strumento è mostrata, ma in qualche modo la dimensione viene ignorata. Cosa mi manca implementando un tooltip personalizzato?

+0

Sto postando questa domanda dopo averlo risolto. Non sono sicuro di quanto sia buono o cattivo pubblicare in una situazione del genere, ma dal momento che né The Java Tutorial né Stack Overflow lo spiegano, volevo condividere i miei risultati. Se questo è buono o cattivo di me, sarei felice di essere educato educatamente meglio;) –

+2

bella domanda con ottimo track-down :-) Solo alcuni link-dropping che potrebbero essere interessanti: https://forums.oracle. com/forums/thread.jspa? threadID = 2128796 - vedi il mio ultimo commento sul perché il delegato ui ignora il tipo LayoutManager – kleopatra

risposta

11

la base "problemi" sono che JToolTip

  • -non è progettato come un contenitore, è solo accidentalmente un contenitore perché è JComponent. Per un "non-contenitore" di Swing è responsabilità dell'i-delegato agire come LayoutManager.
  • non è ricco abbastanza, può gestire solo testo (almeno con il codice html porta di emergenza, che è @ :-) preferito di Andrew

By-passando tali limitazioni fondamentalmente è una guida che widget di quasi sulla cima. Una soluzione pulita rotolerebbe un nuovo componente. D'altra parte, l'OP ha già trovato le viti da modificare. L'unica cosa che potrebbe essere leggermente migliorata è non chiamare né setXXSize, né impostare un ui personalizzato. Invece, fanno si comportano come un contenitore sovrascrivendo getXXSize() come:

@Override 
public Dimension getPreferredSize() { 
    if (getLayout() != null) { 
     return getLayout().preferredLayoutSize(this); 
    } 
    return super.getPreferredSize(); 
} 
+2

Ottimo! Ho aggiunto '! IsPreferredSizeSet ​​()' alla condizione e ora sto usando questa variante! –

+0

E vedo come JToolTip non è progettato per farlo, ma non capisco perché. Per come la vedo io, i tooltip spiegano un componente, ma possono anche fornire informazioni aggiuntive: posso vedere dall'icona della barra degli strumenti che il pulsante stampa il documento, ma il tooltip inoltre mi dice che l'acellerator è Ctrl + P. Di fronte al fatto che il tooltip può legittimamente migliorare il significato di un componente, limitarlo al testo è sicuramente storico? (Volevo solo farlo uscire, non c'è bisogno di discutere una domanda "filosofica" qui;)) –

+1

+1, questa risposta mi ha riportato a Swing Tutorials, sembra che mi sia mancato troppo, leggendo questa risposta :-) –

3

Potrebbe sembrare sciocco ma, hai provato a impostare limiti per JPanel?

setBounds(100, 100, 150, 50); 

E si può provare setting a gap between components in BorderLayout

JPanel content = new JPanel(new BorderLayout(1,1)); 
+0

; vedere la mia risposta imminente in pochi minuti;) sfortunatamente, ci sono alcune avvertenze che rendono strano l'utilizzo di tooltip personalizzati, anche con l'esperienza swing –

+0

@SillyFreak Bene, è Swing. Puoi aspettarti qualcosa in qualsiasi momento. –

+1

+1 questa potrebbe essere la giusta direzione, [non sciocco] (http://stackoverflow.com/a/5957405/714968) – mKorbel

4

Io suggerirei di usare JWindow o un_decorated JDialog, come finestra pop-up (utilizzata per impostazione predefinita per JCalendar o JDatePicker) piuttosto che JTooltip, per più bello output per gli strumenti della GUI Translucent and Shaped Windows

+1

Il collegamento non è aggiornato. Candidati dal sito: [link] (https://docs.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html) [link] (http://www.oracle.com/technetwork/articles/java /translucent-shaped-windows-139324.html), e nel caso si spostino di nuovo: [link di Google] (https://www.google.com/search?q=site%3Aoracle.com+translucent+and+shaped+ windows) –

+0

"EDIT": ho appena preso la fonte di trasparenza di Oracle e aggiunto la porzione di sorgente di forma, quindi hai entrambi in una breve demo: http://pastebin.com/pcPArzRH –

13

I suggerimenti degli strumenti possono rendere HTML. Se è possibile creare URL per le immagini (non pratico se sono generati in memoria ma generalmente fattibili diversamente), è facile scrivere un codice HTML che carichi le immagini e utilizzare tale HTML come suggerimento.


AD ESEMPIO

MultiIconToolTip

import javax.swing.*; 

class MultiIconToolTip { 

    public static void main(String[] args) throws Exception { 
     final String html = 
      "<html><body>" + 
      "<img src='" + 
      "http://i.stack.imgur.com/OVOg3.jpg" + 
      "' width=160 height=120> " + 
      "<img src='" + 
      "http://i.stack.imgur.com/lxthA.jpg" + 
      "' width=160 height=120>" + 
      "<p>Look Ma, no hands!"; 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       JLabel hover = new JLabel("Point at me!"); 
       hover.setToolTipText(html); 
       JOptionPane.showMessageDialog(null, hover); 
      } 
     }); 
    } 
} 
+0

Questa è una buona idea! Non l'ho provato, ma suppongo che dovrebbe funzionare con gli URL di ClassLoader.getResource(), anche –

+0

Sì, gli URL che puntano al percorso del percorso funzionano bene. In effetti, è meglio che raggiungere il mio sito, dal momento che il pop-up appare più veloce. –

3

Ci sono essenzialmente due cose mancanti. Innanzitutto, JToolTip estende JComponent e, a differenza di JPanel, non ha un layout predefinito. Per allungare il content sulla descrizione comando, utilizzare un BorderLayout.

setLayout(new BorderLayout()); 

Il secondo problema è la dimensione. Lo ToolTipManager rispetta la dimensione preferita della punta dell'utensile. Mentre il BorderLayout calcola la dimensione, lo ToolTipUI lo ignora. Quindi, ci sono due alternative: impostare manualmente la dimensione preferita ...

setPreferredSize(content.getPreferredSize()); 

Si noti che ciò non rende obsoleto il layout; altrimenti, si ottiene una punta di strumento vuota con le giuste dimensioni.

... o sottoclasse ToolTipUI per rispettare il layout, che è quello che sono andato con. Il codice risultante è:

setComponent(StadtLabel.this); 

JPanel images = new JPanel(null); 
waren.setLayout(new BoxLayout(waren, BoxLayout.X_AXIS)); 
for(ImageIcon icon:myIcons) { 
    JLabel lbl = new JLabel(icon); 
} 

JPanel content = new JPanel(new BorderLayout()); 
content.add(new JLabel(title), BorderLayout.NORTH); 
content.add(new JLabel(description)); 
content.add(images, BorderLayout.SOUTH); 

setLayout(new BorderLayout()); 
add(content); 
setUI(new ToolTipUI() { 
    @Override 
    public Dimension getMinimumSize(JComponent c) { 
     return c.getLayout().minimumLayoutSize(c); 
    } 

    @Override 
    public Dimension getPreferredSize(JComponent c) { 
     return c.getLayout().preferredLayoutSize(c); 
    } 

    @Override 
    public Dimension getMaximumSize(JComponent c) { 
     return getPreferredSize(c); 
    } 
}); 
0

Invece di reinventare la ruota provate questo: https://github.com/timmolderez/balloontip. Puoi inserire qualsiasi contenuto come JComponent.

+1

Con la fine di java.net, credo che BalloonTip sia ora su [github] (https://github.com/timmolderez/balloontip). – Pixelstix