2011-06-24 154 views
14

鑑於JTextField(或針對該問題的任何JComponent),如何避免強迫該組件的指定工具提示出現,而無需用戶輸入任何直接事件?換句話說,爲什麼沒有JComponent.setTooltipVisible(boolean)強制Java工具提示出現

+0

你的意思是你希望t他的工具提示不斷可見?因爲這不是什麼工具提示用於... – MirroredFate

回答

4

您需要調用默認的Action來顯示工具提示。例如,以顯示工具提示當組件獲得焦點您可以將下面的FocusListener添加到組件:

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

    } 
}; 

編輯:

上面的代碼似乎沒有工作了。另一種方法是分派的MouseEvent到組件:

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

這種方法將導致輕微的延遲前,因爲它模擬輸入部件鼠標被顯示在工具提示。要立即顯示工具提示,您可以使用pstanton的解決方案。

+0

請注意,使用此代碼,工具提示的位置未指定,很可能不在鼠標光標下方。 – dm76

+0

toolTipAction對於我的JButton爲空。這是爲什麼? –

+0

這不起作用,'component.getActionMap()。get(「postTip」);''JTextField'返回null – pstanton

5

的唯一方法(除了創建自己的提示窗口),我發現是emmulate焦點的CTRL + F1鍵擊:只要您移動鼠標

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

不幸的是,該提示將消失(部件外部)或延遲後(見ToolTipManager.setDismissDelay)。

+0

+1,我最初的建議是基於調用「postTip」操作的F1鍵。我認爲直接調用Action比清理KeyEvent更清晰。不知道爲什麼它不工作了。 – camickr

+0

tooltips在java imo中真的很糟糕。非常不靈活。這樣的黑客是必要的(並且幾乎不能實現所需)顯示api缺乏。 – pstanton

+0

Ctrl + F1平臺是獨立的嗎?我應該期望它能像Windows一樣在Mac上工作嗎? –

0

您可以訪問ToolTipManager,將初始延遲設置爲0併發送一個事件。不要忘記在之後恢復數值。

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

對我的作品之上(而不是定時器我使用SwingUtilities類和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

這不是一個ToolTip,但你可以使用一個氣球提示: http://timmolderez.be/balloontip/doku.php

它只是在通話中顯示,並在某些時刻感覺更好默認ToolTip

+0

請注意,與工具提示不同,這些氣球無法退出包含目標組件的窗口。 –