2011-06-24 10 views
14

Dado un JTextField (o cualquier JComponent para el caso), ¿cómo se podría forzar a que aparezca la información sobre herramientas designada de ese componente, sin ningún evento de entrada directa del usuario? En otras palabras, ¿por qué no hay JComponent.setTooltipVisible(boolean)?Obligar a que aparezca una información sobre herramientas Java

+0

Quiere decir que desea t ¿La información sobre herramientas está continuamente visible? Porque eso no es para lo que se usan los tooltips ... – MirroredFate

Respuesta

4

Necesita invocar la acción predeterminada para mostrar la información sobre herramientas. Por ejemplo, para mostrar un texto de ayuda cuando un componente gana enfoque Se puede agregar la siguiente FocusListener al componente:

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); 
     } 

    } 
}; 

Editar:

no parece el código anterior para trabajar más. Otro enfoque es despachar un MouseEvent al componente:

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(); 
      } 
     }); 
    } 
} 

Este enfoque dará lugar a un ligero retraso antes de que aparezca la información de herramientas, ya que simula el ratón entra en el componente. Para la visualización inmediata de la información sobre herramientas, puede usar la solución de pstanton.

+0

Tenga en cuenta que con este código, la posición de la información sobre herramientas no está especificada y probablemente no estará debajo del cursor del mouse – dm76

+0

toolTipAction es nulo para mi JButton. ¿Porqué es eso? –

+0

esto no funciona, 'component.getActionMap(). Get (" postTip ");' devuelve nulo para 'JTextField' – pstanton

5

La única forma (además de la creación de su propia ventana de información sobre herramientas) que he encontrado es emmulate la combinación de teclas CTRL + F1 en el foco:

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();} 
    } 
} 

Desafortunadamente, la información sobre herramientas desaparecerá tan pronto como se mueve el puntero del ratón (fuera del componente) o después de un retraso (consulte ToolTipManager.setDismissDelay).

+0

+1, mi sugerencia original se basó en la tecla F1 que invoca la acción "post-disparo". Pensé que era más claro invocar la Acción directamente en lugar de enviar KeyEvent. No estoy seguro de por qué ya no funciona. – camickr

+0

tooltips están muy mal implementados en java imo. muy inflexible. que tales hacks son necesarios (y difícilmente logran lo que se necesita) muestran que falta la API. – pstanton

+0

¿La plataforma Ctrl + F1 es independiente? ¿Debo esperar que funcione en una Mac igual que Windows? –

0

Puede acceder al ToolTipManager, establecer el retraso inicial en 0 y enviar un evento. No te olvides de restaurar los valores después.

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

Para mí funciona la versión similar se ha dicho (en lugar de temporizador Solía ​​SwingUtilities y el enfoque 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

No es un ToolTip, pero se puede utilizar un globo: http://timmolderez.be/balloontip/doku.php

Se muestra justo cuando se llama y se siente mejor en unos instantes luego Predeterminado ToolTip

+0

Tenga en cuenta que, a diferencia de la información sobre herramientas, estos globos no pueden salir de la ventana que contiene el componente específico. –

Cuestiones relacionadas