2011-06-24 13 views
14

Jeśli chodzi o JTextField (lub jakakolwiek inna JComponent), w jaki sposób można wymusić wyświetlenie wskazanej etykietki komponentu, bez żadnego bezpośredniego zdarzenia wejściowego od użytkownika? Innymi słowy, dlaczego nie ma żadnego JComponent.setTooltipVisible(boolean)?Wymuszenie etykiety narzędzia Java w celu wyświetlenia

+0

Masz na myśli, że chcesz czy podpowiedź jest ciągle widoczna? Ponieważ nie jest to użyteczne przy etykietach narzędzi ... – MirroredFate

Odpowiedz

4

Musisz wywołać domyślną akcję, aby wyświetlić etykietkę narzędzia. Na przykład, aby pokazać etykietkę, gdy komponent zyski skupić można dodać następujące FocusListener do komponentu:

FocusAdapter focusAdapter = new FocusAdapter() 
{ 
    public void focusGained(FocusEvent e) 
    { 
     JComponent component = (JComponent)e.getSource(); 
     Action toolTipAction = component.getActionMap().get("postTip"); 

     if (toolTipAction != null) 
     { 
      ActionEvent postTip = new ActionEvent(component, ActionEvent.ACTION_PERFORMED, ""); 
      toolTipAction.actionPerformed(postTip); 
     } 

    } 
}; 

Edit:

Powyższy kod nie wydają się już pracować. Innym podejściem jest wywoła MouseEvent do komponentu:

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class PostTipSSCCE extends JPanel 
{ 
    public PostTipSSCCE() 
    { 
     FocusAdapter fa = new FocusAdapter() 
     { 
      public void focusGained(FocusEvent e) 
      { 
       JComponent component = (JComponent)e.getSource(); 

       MouseEvent phantom = new MouseEvent(
        component, 
        MouseEvent.MOUSE_MOVED, 
        System.currentTimeMillis(), 
        0, 
        10, 
        10, 
        0, 
        false); 

       ToolTipManager.sharedInstance().mouseMoved(phantom); 
      } 
     }; 

     JButton button = new JButton("Button"); 
     button.setToolTipText("button tool tip"); 
     button.addFocusListener(fa); 
     add(button); 

     JTextField textField = new JTextField(10); 
     textField.setToolTipText("text field tool tip"); 
     textField.addFocusListener(fa); 
     add(textField); 

     JCheckBox checkBox = new JCheckBox("CheckBox"); 
     checkBox.setToolTipText("checkbox tool tip"); 
     checkBox.addFocusListener(fa); 
     add(checkBox); 
    } 

    private static void createAndShowUI() 
    { 
     JFrame frame = new JFrame("PostTipSSCCE"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new JScrollPane(new PostTipSSCCE())); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 

Takie podejście skutkuje lekkim opóźnieniem, zanim zostanie wyświetlona podpowiedź jak to symulowane myszy wejściem komponent. Aby natychmiast wyświetlić etykietkę narzędzia, możesz użyć rozwiązania pstanton.

+0

Należy zauważyć, że z tym kodem pozycja etykiety narzędzia nie jest określona i najprawdopodobniej nie będzie pod kursorem myszy – dm76

+0

toolTipAction ma wartość null dla mojego JButton. Dlaczego? –

+0

to nie działa, 'component.getActionMap(). Get (" postTip ");' zwraca null dla 'JTextField' – pstanton

5

Jedynym sposobem (oprócz tworzenia własnego okna etykietka) Znalazłem to emmulate z klawiszy CTRL + F1 na ostrości:

new FocusAdapter() 
{ 
    @Override 
    public void focusGained(FocusEvent e) 
    { 
     try 
     { 
      KeyEvent ke = new KeyEvent(e.getComponent(), KeyEvent.KEY_PRESSED, 
        System.currentTimeMillis(), InputEvent.CTRL_MASK, 
        KeyEvent.VK_F1, KeyEvent.CHAR_UNDEFINED); 
      e.getComponent().dispatchEvent(ke); 
     } 
     catch (Throwable e1) 
     {e1.printStackTrace();} 
    } 
} 

Niestety, etykietka zniknie tak szybko, jak poruszać myszą (poza komponentem) lub po opóźnieniu (patrz ToolTipManager.setDismissDelay).

+0

+1, moja oryginalna sugestia została oparta na klawiszu F1 wywołującym działanie "postTip". Pomyślałem, że czystsze jest wywoływanie akcji bezpośrednio, niż ekspedycja KeyEvent. Nie wiem, dlaczego to już nie działa. – camickr

+0

tooltipy są naprawdę źle zaimplementowane w java imo. bardzo nieelastyczny. że takie hacki są konieczne (i prawie nie osiągają tego, co jest potrzebne) pokazują brak api. – pstanton

+0

Czy platforma Ctrl + F1 jest niezależna? Czy powinienem oczekiwać, że będzie działać na Macu tak samo jak Windows? –

0

Możesz uzyskać dostęp do ToolTipManager, ustawić początkowe opóźnienie na 0 i wysłać je. Nie zapomnij przywrócić wartości później.

private void displayToolTip() 
{ 
    final ToolTipManager ttm = ToolTipManager.sharedInstance(); 
    final MouseEvent event = new MouseEvent(this, 0, 0, 0, 
              0, 0, // X-Y of the mouse for the tool tip 
              0, false); 
    final int oldDelay = ttm.getInitialDelay(); 
    final String oldText = textPane.getToolTipText(event); 
    textPane.setToolTipText("<html><a href='http://www.google.com'>google</a></html>!"); 
    ttm.setInitialDelay(0); 
    ttm.setDismissDelay(1000); 
    ttm.mouseMoved(event); 

    new Timer().schedule(new TimerTask() 
    { 
     @Override 
     public void run() 
     { 
      ttm.setInitialDelay(oldDelay); 
      textPane.setToolTipText(oldText); 
     } 
    }, ttm.getDismissDelay()); 
} 
1

Dla mnie działa podobną wersję podaną powyżej (zamiast czasowy użyłem SwingUtilities i podejście invokeLater):

private void showTooltip(Component component) 
{ 
    final ToolTipManager ttm = ToolTipManager.sharedInstance(); 
    final int oldDelay = ttm.getInitialDelay(); 
    ttm.setInitialDelay(0); 
    ttm.mouseMoved(new MouseEvent(component, 0, 0, 0, 
      0, 0, // X-Y of the mouse for the tool tip 
      0, false)); 
    SwingUtilities.invokeLater(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      ttm.setInitialDelay(oldDelay); 
     } 
    }); 
} 
0

To nie ToolTip, ale można użyć końcówkę balonu: http://timmolderez.be/balloontip/doku.php

Pokazuje się tylko na wezwanie i czuje się lepiej w niektórych momentach. Domyślnie ToolTip

+0

Należy zauważyć, że w przeciwieństwie do etykiet narzędziowych, te dymki nie mogą wyjść z okna zawierającego element docelowy. –

Powiązane problemy