Принудительная всплывающая подсказка Java
Учитывая JTextField
(или любой JComponent
, если на то пошло), как можно было заставить форматировать эту компонентную подсказку, без какого-либо прямого события ввода от пользователя? Другими словами, почему нет JComponent.setTooltipVisible(boolean)
?
Ответы
Ответ 1
Единственный способ (помимо создания собственного окна всплывающей подсказки), я нашел для эмуляции нажатия клавиши 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
).
Ответ 2
Вам нужно вызвать действие по умолчанию, чтобы показать всплывающую подсказку. Например, чтобы показать всплывающую подсказку, когда компонент получает фокус, вы можете добавить в компонент следующий 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 );
}
}
};
Edit:
Вышеприведенный код больше не работает. Другим подходом является отправка 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.
Ответ 3
Для меня работает аналогичная версия, указанная выше (вместо Timer я использовал 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);
}
});
}
Ответ 4
Вы можете получить доступ к 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());
}
Ответ 5
Это не ToolTip
, но вы можете использовать подсказку:
http://timmolderez.be/balloontip/doku.php
Он показывает только по вызову и чувствует себя лучше в некоторые моменты, затем по умолчанию ToolTip