'ToolTipManager'에 해당되는 글 1건

  1. 2006.03.30 Tool Tip Management in Swing
자바2006.03.30 12:10

1. javax.swing.ToolTipManager
ToolTipManager는 tooltip과 관련된 동작을 총괄하는 class로서 shared instance가 사용된다. 다음은 ToolTipManager에 대한 javadoc description이다.

Manages all the ToolTips in the system. ToolTipManager contains numerous properties for configuring how long it will take for the tooltips to become visible, and how long till they hide. Consider a component that has a different tooltip based on where the mouse is, such as JTree. When the mouse moves into the JTree and over a region that has a valid tooltip, the tooltip will become visibile after initialDelay milliseconds. After dismissDelay milliseconds the tooltip will be hidden. If the mouse is over a region that has a valid tooltip, and the tooltip is currently visible, when the mouse moves to a region that doesn't have a valid tooltip the tooltip will be hidden. If the mouse then moves back into a region that has a valid tooltip within reshowDelay milliseconds, the tooltip will immediately be shown, otherwise the tooltip will be shown again after initialDelay milliseconds.

2. ToolTip Registration
JComponent의 tooltip은 JComponent.setToolTipText(String) 메서드로 등록할 수 있다. JComponent.setToolTipText(String) 메서드는 clientProperties라는 ArrayTable에 tooltip에 해당하는 key, value를 세팅한 뒤, ToolTipManager.registerComponent(JComponent) 메서드를 호출하는데, 이 메서드는 ToolTipManager 자신을 해당 JComponent에 MouseListener, MouseMotionListener로 등록한다.

3. ToolTip Component Structure
child window 형태인 듯 하나 아직 제대로 안 봤음. 나중에 기회가 생기면 update하자~

4. ToolTip Display Process
ToolTipManager가 tooltip을 띄우고, 감추는 과정은 다음과 같다.

  • mouse enter 시점에 enterTimer.start()를 호출한다.
  • enterTimer는 750 ms 이후 insideTimerAction.actionPerformed()를 호출한다.
  • insideTimerAction은 showTipWindow()를 호출하여 tooltip을 띄운 뒤 insideTimer.start()를 호출한다.
  • insideTimer는 4000 ms 후에 stillInsideTimerAction.actionPerformed()를 호출한다.
  • stillInsideTimerAction은 hideTipWindow()를 호출하여 tooltip을 감춘다.

기본적으로는 위와 같이 동작하고, 조금 더 자세히 살펴보면 다음과 같다.

  • tooltip이 뜨기 전에 해당 component내에서 mouse move가 발생하면 enterTimer.restart()가 호출되므로, 엄밀히 따지면 mouse cursor가 해당 component내에서 정지된 뒤 750 ms가 흘러야 tooltip이 뜬다.
  • tooltip이 뜬 상태에서 해당 component내에서 mouse move가 발생하면 insideTimer.restart()가 호출되므로, 엄밀히 따지면 mouse cursor가 해당 component내에서 정지된 뒤 4000 ms가 흘러야 tooltip이 사라진다.
  • mouse exit 시점에 exitTimer.restart()가 호출되고, 이 Timer는 500 ms 이후 showImmediately(delay 없이 tooltip을 즉시 띄우는 flag)를 false로 세팅한다. 즉, mouse exit 이후 500 ms 이전에 (tooltip을 가진) 다른 component 영역에 mouse enter가 발생하면 해당 component의 tooltip이 delay 없이 즉시 뜨게 된다.

위에서 언급된 각 시간들에 대한 명칭과 내부적인 reference는 다음과 같다.

Time Name Reference
750 ms initialDelay enterTimer.initialDelay
4000 ms dismissDelay insideTimer.initialDelay
500 ms reshowDelay exitTimer.initialDelay

이 시간들은 ToolTipManager의 getter/setter 메서드로 참조 및 설정이 가능하다. (ex. ToolTipManager.setDismissDelay(int))

5. Issues about ToolTip
a. JTable, JTree, JTabbedPane의 multi-tooltip
부위별로 다른 tooltip이 떠야 하는 component들이다. 자세한 내용은 필요한 경우에 조사할거다. 하하...
b. tooltip by window focusing
JRE 1.5에서 ToolTipManager.showTipWindow() 메서드의 초반부에 다음 코드가 추가되었다.

for (Container p = insideComponent.getParent(); p != null; p = p.getParent()) {
if (p instanceof JPopupMenu) break;
if (p instanceof Window) {
if (!((Window)p).isFocused()) {
return;
}
break;
}
}

이 코드는 deactivated(defocused) Window의 component가 tooltip을 띄우던 버그때문에 추가되었다. (일반적인 windowing system에서는 focused window만 tooltip을 띄울 수 있도록 하는 듯... 그럼 rollover도 마찬가지 아닌가?)
그럼 예를 들어 Window(A)를 owner로 하는 Window(B)가 있다고 하자. JRE 1.4 이하에서는 어떤 Window가 focus를 가지든 항상 tooltip이 뜬다. 심지어 두 Window 모두 focus를 잃는다 해도 tooltip은 꿋꿋이 뜬다.
하지만 JRE 1.5에서는 상황이 다르다. 오로지 focus를 가진 Window만 tooltip을 띄울 수 있다. Window(A)가 focus를 가진 경우, Window(B)는 tooltip이 뜨지 않으며, Window(B)가 focus를 가진 경우는 Window(A)의 tooltip이 뜨지 않게 된다.
따라서 이와 같은 구성의 UI를 작성시, 두 Window 중 하나만 focus를 가지더라도 두 Window 모두 tooltip을 띄울 수 있도록 하려면...
1. Window(B)를 Window가 아닌 다른 component로 구성하든지... (Window가 아니면 안되는 경우가 있겠다)
2. ToolTipManager를 override하든지... (위험하다)
3. 강제로 tooltip을 띄우든지... (귀찮고 위험하다)

흠... 별로다. 좀 더 좋은 방법 없을까?

6. References
- [J2SE 1.4.2 API document] ToolTipManager (http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/ToolTipManager.html)
- [J2SE 1.4.2 API document] JToolTip (http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JToolTip.html)
- [J2SE 1.4.2 API document] JComponent (http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JComponent.html)
- [Java Tutorial] How to Use Tool Tips (http://java.sun.com/docs/books/tutorial/uiswing/components/tooltip.html)
- [SDN Java Bug Database] Bug ID: 4148057 Using ToolTips... (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4148057)

신고
Posted by roguebean

티스토리 툴바