blob: a83496fff0632177fc2d094d2a3445cf19c2f999 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala.swing
import java.awt.Cursor
import event._
import scala.ref._
import java.util.WeakHashMap
object UIElement {
private val ClientKey = "scala.swingWrapper"
private[this] val wrapperCache = new WeakHashMap[java.awt.Component, WeakReference[UIElement]]
private def cache(e: UIElement) = e.peer match {
case p: javax.swing.JComponent => p.putClientProperty(ClientKey, e)
case _ => wrapperCache.put(e.peer, new WeakReference(e))
}
/**
* Looks up the internal component cache for a wrapper of the given
* Java Swing peer. If this method finds one of the given type `C`,
* it will return that wrapper. Otherwise it returns `null`. This
* method never throws an exception.
*
* Clients should be extremely careful with type parameter `C` and
* its interaction with type inference. Better err on the side of caution
* and explicitly specify `C`.
*/
private[swing] def cachedWrapper[C>:Null<:UIElement](c: java.awt.Component): C = {
val w = c match {
case c: javax.swing.JComponent => c.getClientProperty(ClientKey)
case _ => wrapperCache.get(c)
}
try { w.asInstanceOf[C] } catch { case _: Exception => null }
}
/**
* Returns a wrapper for a given Java Swing peer. If there is a
* compatible wrapper in use, this method will return it.
*
* `wrap` methods in companion objects of subclasses of `UIElement` have
* the same behavior, except that they return more specific wrappers.
*/
def wrap(c: java.awt.Component): UIElement = {
val w = cachedWrapper[UIElement](c)
if (w != null) w
else new UIElement { def peer = c }
}
}
/**
* The base trait of all user interface elements. Subclasses belong to one
* of two groups: top-level elements such as windows and dialogs, or
* `Component`s.
*
* @note [Java Swing] This trait does not have an exact counterpart in
* Java Swing. The peer is of type java.awt.Component since this is the
* least common upper bound of possible underlying peers.
*
* @note [Implementation] A UIElement automatically adds itself to the
* component cache on creation.
*
* @see java.awt.Component
*/
trait UIElement extends Proxy with LazyPublisher {
/**
* The underlying Swing peer.
*/
def peer: java.awt.Component
def self = peer
UIElement.cache(this)
def foreground: Color = peer.getForeground
def foreground_=(c: Color) = peer setForeground c
def background: Color = peer.getBackground
def background_=(c: Color) = peer setBackground c
def minimumSize = peer.getMinimumSize
def minimumSize_=(x: Dimension) = peer setMinimumSize x
def maximumSize = peer.getMaximumSize
def maximumSize_=(x: Dimension) = peer setMaximumSize x
def preferredSize = peer.getPreferredSize
def preferredSize_=(x: Dimension) = peer setPreferredSize x
def font: Font = peer.getFont
def font_=(f: Font) = peer setFont f
def locationOnScreen = peer.getLocationOnScreen
def location = peer.getLocation
def bounds = peer.getBounds
def size = peer.getSize
def locale = peer.getLocale
def toolkit = peer.getToolkit
def cursor: Cursor = peer.getCursor
def cursor_=(c: Cursor) { peer.setCursor(c) }
def visible: Boolean = peer.isVisible
def visible_=(b: Boolean) { peer.setVisible(b) }
def showing: Boolean = peer.isShowing
def displayable: Boolean = peer.isDisplayable
def repaint() { peer.repaint }
def repaint(rect: Rectangle) { peer.repaint(rect.x, rect.y, rect.width, rect.height) }
def ignoreRepaint: Boolean = peer.getIgnoreRepaint
def ignoreRepaint_=(b: Boolean) { peer.setIgnoreRepaint(b) }
protected def onFirstSubscribe() {
peer.addComponentListener(new java.awt.event.ComponentListener {
def componentHidden(e: java.awt.event.ComponentEvent) {
publish(UIElementHidden(UIElement.this))
}
def componentShown(e: java.awt.event.ComponentEvent) {
publish(UIElementShown(UIElement.this))
}
def componentMoved(e: java.awt.event.ComponentEvent) {
publish(UIElementMoved(UIElement.this))
}
def componentResized(e: java.awt.event.ComponentEvent) {
publish(UIElementResized(UIElement.this))
}
})
}
protected def onLastUnsubscribe() {}
}
|