├── .gitignore
├── README
├── doc
├── README
└── build.xml
├── scala
└── swing
│ ├── AbstractButton.scala
│ ├── Action.scala
│ ├── Adjustable.scala
│ ├── Alignment.scala
│ ├── Applet.scala
│ ├── BorderPanel.scala
│ ├── BoxPanel.scala
│ ├── BufferWrapper.scala
│ ├── Button.scala
│ ├── ButtonGroup.scala
│ ├── CheckBox.scala
│ ├── ComboBox.scala
│ ├── Component.scala
│ ├── Container.scala
│ ├── EditorPane.scala
│ ├── FileChooser.scala
│ ├── FlowPanel.scala
│ ├── Font.scala.disabled
│ ├── FormattedTextField.scala
│ ├── GUIApplication.scala
│ ├── GridBagPanel.scala
│ ├── GridPanel.scala
│ ├── Label.scala
│ ├── LayoutContainer.scala
│ ├── ListView.scala
│ ├── MainFrame.scala
│ ├── Menu.scala
│ ├── Orientable.scala
│ ├── Orientation.scala
│ ├── Oriented.scala
│ ├── Panel.scala
│ ├── PasswordField.scala
│ ├── ProgressBar.scala
│ ├── Publisher.scala
│ ├── RadioButton.scala
│ ├── Reactions.scala
│ ├── Reactor.scala
│ ├── RichWindow.scala
│ ├── RootPanel.scala
│ ├── ScrollBar.scala
│ ├── ScrollPane.scala
│ ├── Scrollable.scala
│ ├── Separator.scala
│ ├── SequentialContainer.scala
│ ├── SimpleGUIApplication.scala
│ ├── SimpleSwingApplication.scala
│ ├── Slider.scala
│ ├── SplitPane.scala
│ ├── Swing.scala
│ ├── SwingActor.scala
│ ├── SwingApplication.scala
│ ├── SwingWorker.scala
│ ├── TabbedPane.scala
│ ├── Table.scala
│ ├── TextArea.scala
│ ├── TextComponent.scala
│ ├── TextField.scala
│ ├── ToggleButton.scala
│ ├── UIElement.scala
│ ├── Window.scala
│ ├── event
│ ├── ActionEvent.scala
│ ├── AdjustingEvent.scala
│ ├── BackgroundChanged.scala
│ ├── ButtonClicked.scala
│ ├── CaretUpdate.scala
│ ├── ComponentEvent.scala
│ ├── ContainerEvent.scala
│ ├── EditDone.scala
│ ├── Event.scala
│ ├── FocusEvent.scala
│ ├── FontChanged.scala
│ ├── ForegroundChanged.scala
│ ├── InputEvent.scala
│ ├── Key.scala
│ ├── KeyEvent.scala
│ ├── ListEvent.scala
│ ├── MouseEvent.scala
│ ├── SelectionEvent.scala
│ ├── TableEvent.scala
│ ├── UIEvent.scala
│ ├── ValueChanged.scala
│ ├── WindowActivated.scala
│ ├── WindowClosed.scala
│ ├── WindowClosing.scala
│ ├── WindowDeactivated.scala
│ ├── WindowDeiconified.scala
│ ├── WindowEvent.scala
│ ├── WindowIconified.scala
│ └── WindowOpened.scala
│ ├── model
│ └── Matrix.scala
│ ├── package.scala
│ └── test
│ ├── ButtonApp.scala
│ ├── CelsiusConverter.scala
│ ├── CelsiusConverter2.scala
│ ├── ComboBoxes.scala
│ ├── CountButton.scala
│ ├── Dialogs.scala
│ ├── GridBagDemo.scala
│ ├── HelloWorld.scala
│ ├── LabelTest.scala
│ ├── LinePainting.scala
│ ├── ListViewDemo.scala
│ ├── SimpleApplet.scala
│ ├── SwingApp.scala
│ ├── TableSelection.scala
│ ├── UIDemo.scala
│ └── images
│ ├── banana.jpg
│ ├── margarita1.jpg
│ ├── margarita2.jpg
│ └── rose.jpg
└── swing.version.properties
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | lib_managed/
3 | src_managed/
4 | project/boot/
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | The scala.swing package
2 |
3 | This is a UI library that will wrap most of Java Swing for Scala in a straightforward manner.
4 | The widget class hierarchy loosely resembles that of Java Swing.
5 |
6 | The library comprises three main packages:
7 |
8 | scala.swing
9 | All widget classes and traits.
10 |
11 | scala.swing.event
12 | The event hierarchy.
13 |
14 | scala.swing.test
15 | A set of demos.
16 |
17 | An incubator project can be found on http://github.com/ingoem/scala-swing.
--------------------------------------------------------------------------------
/doc/README:
--------------------------------------------------------------------------------
1 | scala.swing BETA
2 |
3 | This is a UI library that will wrap most of Java Swing for Scala in a straightforward manner.
4 | The widget class hierarchy loosely resembles that of Java Swing. The main differences are:
5 |
6 | In Java Swing all components are containers per default. This doesn't make much sense for
7 | a number of components, like TextField, CheckBox, RadioButton, and so on. Our guess is that
8 | this architecture was chosen because Java lacks multiple inheritance.
9 | In scala.swing, components that can have child components extend the Container trait.
10 |
11 | Layout managers and panels are coupled. There is no way to exchange the layout manager
12 | of a panel. As a result, the layout constraints for widgets can be typed.
13 | (Note that you gain more type-safety and don't loose much flexibility here. Besides
14 | being not a common operation, exchanging the layout manager of a panel in Java
15 | Swing almost always leads to exchanging the layout constraints for every of the panel's
16 | child component. In the end, it is not more work to move all children to a newly created
17 | panel.)
18 |
19 | The event system. TODO
20 |
21 |
22 | The library comprises three main packages:
23 |
24 | scala.swing
25 | All widget classes and traits.
26 |
27 | scala.swing.event
28 | The event hierarchy.
29 |
30 | scala.swing.test
31 | A set of demos.
32 |
33 |
34 | Notes:
35 |
36 | Visual appearance of combo boxes using the GTK LaF is broken on JDKs < 1.7b30.
37 | This is a Java Swing problem.
38 |
39 | To download the latest version, go to http://lamp.epfl.ch/~imaier or use sbaz.
40 |
--------------------------------------------------------------------------------
/doc/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | None
. For various buttons.
149 | */
150 | 1.6: def selected: Option[Boolean] = Option(peer.getValue(javax.swing.Action.SELECTED_KEY))
151 | def selected_=(b: Option[Boolean]) {
152 | peer.putValue(javax.swing.Action.SELECTED_KEY,
153 | if (b == None) null else new java.lang.Boolean(b.get))
154 | }*/
155 |
156 | def apply()
157 | }
158 |
--------------------------------------------------------------------------------
/scala/swing/Adjustable.scala:
--------------------------------------------------------------------------------
1 | package scala.swing
2 |
3 | import java.awt.{Adjustable => JAdjustable}
4 |
5 | object Adjustable {
6 | trait Wrapper extends Oriented.Wrapper with Adjustable {
7 | def peer: JAdjustable with OrientedMixin
8 |
9 | def unitIncrement = peer.getUnitIncrement
10 | def unitIncrement_=(i: Int) = peer.setUnitIncrement(i)
11 | def blockIncrement = peer.getBlockIncrement
12 | def blockIncrement_=(i: Int) = peer.setBlockIncrement(i)
13 |
14 | def value = peer.getValue
15 | def value_=(v: Int) = peer.setValue(v)
16 |
17 | def visibleAmount = peer.getVisibleAmount
18 | def visibleAmount_=(v: Int) = peer.setVisibleAmount(v)
19 |
20 | def minimum = peer.getMinimum
21 | def minimum_=(m: Int) = peer.setMinimum(m)
22 | def maximum = peer.getMaximum
23 | def maximum_=(m: Int) = peer.setMaximum(m)
24 | }
25 | }
26 |
27 | trait Adjustable extends Oriented {
28 | def unitIncrement: Int
29 | def unitIncrement_=(i: Int)
30 | def blockIncrement: Int
31 | def blockIncrement_=(i: Int)
32 |
33 | def value: Int
34 | def value_=(v : Int)
35 |
36 | def visibleAmount: Int
37 | def visibleAmount_=(v: Int)
38 |
39 | def minimum: Int
40 | def minimum_=(m: Int)
41 | def maximum: Int
42 | def maximum_=(m: Int)
43 |
44 | // Needs implementation of AdjustmentEvent
45 | //
46 | // val adjustments: Publisher = new Publisher {
47 | // peer.addAdjustmentListener(new AdjustmentListener {
48 | // def adjustmentValueChanged(e: java.awt.event.AdjustmentEvent) {
49 | // publish(new AdjustmentEvent(e))
50 | // }
51 | // })
52 | // }
53 | }
54 |
--------------------------------------------------------------------------------
/scala/swing/Alignment.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import javax.swing.SwingConstants._
14 |
15 | /**
16 | * Horizontal and vertical alignments. We sacrifice a bit of type-safety
17 | * for simplicity here.
18 | *
19 | * @see javax.swing.SwingConstants
20 | */
21 | object Alignment extends Enumeration {
22 | val Left = Value(LEFT)
23 | val Right = Value(RIGHT)
24 | val Center = Value(CENTER)
25 | val Top = Value(TOP)
26 | val Bottom = Value(BOTTOM)
27 | //1.6: val Baseline = Value(BASELINE)
28 |
29 | val Leading = Value(LEADING)
30 | val Trailing = Value(TRAILING)
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/scala/swing/Applet.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import javax.swing.JApplet
14 |
15 | /**
16 | * Clients should implement the ui field. See the SimpleApplet
17 | * demo for an example.
18 | *
20 | * Note: Applet
extends javax.swing.JApplet
21 | * to satisfy Java's applet loading mechanism. The usual component wrapping
22 | * scheme doesn't work here.
23 | *
BorderPanel
18 | */
19 | object Position extends Enumeration {
20 | val North = Value(BorderLayout.NORTH)
21 | val South = Value(BorderLayout.SOUTH)
22 | val West = Value(BorderLayout.WEST)
23 | val East = Value(BorderLayout.EAST)
24 | val Center = Value(BorderLayout.CENTER)
25 | }
26 | private[swing] def wrapPosition(s: String): Position.Value = s match {
27 | case BorderLayout.NORTH => Position.North
28 | case BorderLayout.SOUTH => Position.South
29 | case BorderLayout.WEST => Position.West
30 | case BorderLayout.EAST => Position.East
31 | case BorderLayout.CENTER => Position.Center
32 | }
33 | }
34 |
35 | /**
36 | * A container that arranges its children around a central component that
37 | * takes most of the space. The other children are placed on one of four
38 | * borders: north, east, south, west.
39 | *
40 | * @see javax.swing.BorderLayout
41 | */
42 | class BorderPanel extends Panel with LayoutContainer {
43 | import BorderPanel._
44 | def layoutManager = peer.getLayout.asInstanceOf[BorderLayout]
45 | override lazy val peer = new javax.swing.JPanel(new BorderLayout) with SuperMixin
46 |
47 | type Constraints = Position.Value
48 |
49 | protected def constraintsFor(comp: Component) =
50 | wrapPosition(layoutManager.getConstraints(comp.peer).asInstanceOf[String])
51 |
52 | protected def areValid(c: Constraints): (Boolean, String) = (true, "")
53 | protected def add(c: Component, l: Constraints) {
54 | // we need to remove previous components with the same constraints as the new one,
55 | // otherwise the layout manager loses track of the old one
56 | val old = layoutManager.getLayoutComponent(l.toString)
57 | if(old != null) peer.remove(old)
58 | peer.add(c.peer, l.toString)
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/scala/swing/BoxPanel.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | /**
14 | * A panel that lays out its contents one after the other,
15 | * either horizontally or vertically.
16 | *
17 | * @see javax.swing.BoxLayout
18 | */
19 | class BoxPanel(orientation: Orientation.Value) extends Panel with SequentialContainer.Wrapper {
20 | override lazy val peer = {
21 | val p = new javax.swing.JPanel with SuperMixin
22 | val l = new javax.swing.BoxLayout(p, orientation.id)
23 | p.setLayout(l)
24 | p
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/scala/swing/BufferWrapper.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import scala.collection.mutable.Buffer
14 |
15 | /**
16 | * Default partial implementation for buffer adapters.
17 | */
18 | protected[swing] abstract class BufferWrapper[A] extends Buffer[A] { outer =>
19 | def clear() { for (i <- 0 until length) remove(0) }
20 | def update(n: Int, a: A) {
21 | remove(n)
22 | insertAt(n, a)
23 | }
24 | def insertAll(n: Int, elems: scala.collection.Traversable[A]) {
25 | var i = n
26 | for (el <- elems) {
27 | insertAt(i, el)
28 | i += 1
29 | }
30 | }
31 | protected def insertAt(n: Int, a: A)
32 |
33 | def +=:(a: A): this.type = { insertAt(0, a); this }
34 | def iterator = Iterator.range(0,length).map(apply(_))
35 | }
36 |
--------------------------------------------------------------------------------
/scala/swing/Button.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import event._
14 | import javax.swing._
15 |
16 | object Button {
17 | def apply(text0: String)(op: => Unit) = new Button(Action(text0)(op))
18 | }
19 |
20 | /**
21 | * A button that can be clicked, usually to perform some action.
22 | *
23 | * @see javax.swing.JButton
24 | */
25 | class Button(text0: String) extends AbstractButton with Publisher {
26 | override lazy val peer: JButton = new JButton(text0) with SuperMixin
27 | def this() = this("")
28 | def this(a: Action) = {
29 | this("")
30 | action = a
31 | }
32 |
33 | def defaultButton: Boolean = peer.isDefaultButton
34 |
35 | def defaultCapable: Boolean = peer.isDefaultCapable
36 | def defaultCapable_=(capable: Boolean) { peer.setDefaultCapable(capable) }
37 | }
38 |
--------------------------------------------------------------------------------
/scala/swing/ButtonGroup.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import event._
14 | import javax.swing.{AbstractButton => JAbstractButton,Icon}
15 | import scala.collection._
16 | import scala.collection.mutable.Buffer
17 |
18 | /**
19 | * A button mutex. At most one of its associated buttons is selected
20 | * at a time.
21 | *
22 | * @see javax.swing.ButtonGroup
23 | */
24 | class ButtonGroup(initialButtons: AbstractButton*) {
25 | val peer: javax.swing.ButtonGroup = new javax.swing.ButtonGroup
26 |
27 | val buttons: mutable.Set[AbstractButton] = new mutable.Set[AbstractButton] {
28 | def -=(b: AbstractButton): this.type = { peer.remove(b.peer); this }
29 | def +=(b: AbstractButton): this.type = { peer.add(b.peer); this }
30 | def contains(b: AbstractButton) = this.iterator.contains(b)
31 | override def size = peer.getButtonCount
32 | def iterator: Iterator[AbstractButton] = new Iterator[AbstractButton] {
33 | val enum = peer.getElements
34 | def next = UIElement.cachedWrapper[AbstractButton](enum.nextElement)
35 | def hasNext = enum.hasMoreElements
36 | }
37 | }
38 | buttons ++= initialButtons
39 |
40 | //1.6: def deselectAll() { peer.clearSelection }
41 | def selected: Option[AbstractButton] = buttons.find(_.selected)
42 | def select(b: AbstractButton) { peer.setSelected(b.peer.getModel, true) }
43 | }
44 |
--------------------------------------------------------------------------------
/scala/swing/CheckBox.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import javax.swing._
14 |
15 | /**
16 | * Two state button that can either be checked or unchecked.
17 | *
18 | * @see javax.swing.JCheckBox
19 | */
20 | class CheckBox(text: String) extends ToggleButton {
21 | override lazy val peer: JCheckBox = new JCheckBox(text) with SuperMixin
22 | def this() = this("")
23 |
24 | def borderPaintedFlat: Boolean = peer.isBorderPaintedFlat
25 | def borderPaintedFlat_=(flat: Boolean) { peer.setBorderPaintedFlat(flat) }
26 | }
27 |
--------------------------------------------------------------------------------
/scala/swing/ComboBox.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import event._
14 | import javax.swing.{JList, JComponent, JComboBox, JTextField, ComboBoxModel, AbstractListModel, ListCellRenderer}
15 | import java.awt.event.ActionListener
16 |
17 | object ComboBox {
18 | /**
19 | * An editor for a combo box. Let's you edit the currently selected item.
20 | * It is highly recommended to use the BuiltInEditor class. For anything
21 | * else, one cannot guarantee that it integrates nicely with the current
22 | * LookAndFeel.
23 | *
24 | * Publishes action events.
25 | */
26 | trait Editor[A] extends Publisher {
27 | lazy val comboBoxPeer: javax.swing.ComboBoxEditor = new javax.swing.ComboBoxEditor with Publisher {
28 | def addActionListener(l: ActionListener) {
29 | this match {
30 | // TODO case w: Action.Trigger.Wrapper =>
31 | // w.peer.addActionListener(l)
32 | case _ =>
33 | this.subscribe(new Reactions.Wrapper(l) ({
34 | case ActionEvent(c) => l.actionPerformed(new java.awt.event.ActionEvent(c.peer, 0, ""))
35 | }))
36 | }
37 | }
38 | def removeActionListener(l: ActionListener) {
39 | this match {
40 | // TODO case w: Action.Trigger.Wrapper =>
41 | // w.peer.removeActionListener(l)
42 | case _ =>
43 | this.unsubscribe(new Reactions.Wrapper(l)({ case _ => }))
44 | }
45 | }
46 | def getEditorComponent: JComponent = Editor.this.component.peer
47 | def getItem(): AnyRef = item.asInstanceOf[AnyRef]
48 | def selectAll() { startEditing() }
49 | def setItem(a: Any) { item = a.asInstanceOf[A] }
50 | }
51 | def component: Component
52 | def item: A
53 | def item_=(a: A)
54 | def startEditing()
55 | }
56 |
57 | /**
58 | * Use this editor, if you want to reuse the builtin editor supplied by the current
59 | * Look and Feel. This is restricted to a text field as the editor widget. The
60 | * conversion from and to a string is done by the supplied functions.
61 | *
62 | * It's okay if string2A throws exceptions. They are caught by an input verifier.
63 | */
64 | class BuiltInEditor[A](comboBox: ComboBox[A])(string2A: String => A,
65 | a2String: A => String) extends ComboBox.Editor[A] {
66 | protected[swing] class DelegatedEditor(editor: javax.swing.ComboBoxEditor) extends javax.swing.ComboBoxEditor {
67 | var value: A = {
68 | val v = comboBox.peer.getSelectedItem
69 | try {
70 | v match {
71 | case s: String => string2A(s)
72 | case _ => v.asInstanceOf[A]
73 | }
74 | } catch {
75 | case _: Exception =>
76 | throw new IllegalArgumentException("ComboBox not initialized with a proper value, was '" + v + "'.")
77 | }
78 | }
79 | def addActionListener(l: ActionListener) {
80 | editor.addActionListener(l)
81 | }
82 | def removeActionListener(l: ActionListener) {
83 | editor.removeActionListener(l)
84 | }
85 |
86 | def getEditorComponent: JComponent = editor.getEditorComponent.asInstanceOf[JComponent]
87 | def selectAll() { editor.selectAll() }
88 | def getItem(): AnyRef = { verifier.verify(getEditorComponent); value.asInstanceOf[AnyRef] }
89 | def setItem(a: Any) { editor.setItem(a) }
90 |
91 | val verifier = new javax.swing.InputVerifier {
92 | // TODO: should chain with potentially existing verifier in editor
93 | def verify(c: JComponent) = try {
94 | value = string2A(c.asInstanceOf[JTextField].getText)
95 | true
96 | }
97 | catch {
98 | case e: Exception => false
99 | }
100 | }
101 |
102 | def textEditor = getEditorComponent.asInstanceOf[JTextField]
103 | textEditor.setInputVerifier(verifier)
104 | textEditor.addActionListener(Swing.ActionListener{ a =>
105 | getItem() // make sure our value is updated
106 | textEditor.setText(a2String(value))
107 | })
108 | }
109 |
110 | override lazy val comboBoxPeer: javax.swing.ComboBoxEditor = new DelegatedEditor(comboBox.peer.getEditor)
111 |
112 | def component = Component.wrap(comboBoxPeer.getEditorComponent.asInstanceOf[JComponent])
113 | def item: A = { comboBoxPeer.asInstanceOf[DelegatedEditor].value }
114 | def item_=(a: A) { comboBoxPeer.setItem(a2String(a)) }
115 | def startEditing() { comboBoxPeer.selectAll() }
116 | }
117 |
118 | implicit def stringEditor(c: ComboBox[String]): Editor[String] = new BuiltInEditor(c)(s => s, s => s)
119 | implicit def intEditor(c: ComboBox[Int]): Editor[Int] = new BuiltInEditor(c)(s => s.toInt, s => s.toString)
120 | implicit def floatEditor(c: ComboBox[Float]): Editor[Float] = new BuiltInEditor(c)(s => s.toFloat, s => s.toString)
121 | implicit def doubleEditor(c: ComboBox[Double]): Editor[Double] = new BuiltInEditor(c)(s => s.toDouble, s => s.toString)
122 |
123 | def newConstantModel[A](items: Seq[A]): ComboBoxModel = {
124 | new AbstractListModel with ComboBoxModel {
125 | private var selected = items(0)
126 | def getSelectedItem: AnyRef = selected.asInstanceOf[AnyRef]
127 | def setSelectedItem(a: Any) {
128 | if ((selected != null && selected != a) ||
129 | selected == null && a != null) {
130 | selected = a.asInstanceOf[A]
131 | fireContentsChanged(this, -1, -1)
132 | }
133 | }
134 | def getElementAt(n: Int) = items(n).asInstanceOf[AnyRef]
135 | def getSize = items.size
136 | }
137 | }
138 |
139 | /*def newMutableModel[A, Self](items: Seq[A] with scala.collection.mutable.Publisher[scala.collection.mutable.Message[A], Self]): ComboBoxModel = {
140 | new AbstractListModel with ComboBoxModel {
141 | private var selected = items(0)
142 | def getSelectedItem: AnyRef = selected.asInstanceOf[AnyRef]
143 | def setSelectedItem(a: Any) { selected = a.asInstanceOf[A] }
144 | def getElementAt(n: Int) = items(n).asInstanceOf[AnyRef]
145 | def getSize = items.size
146 | }
147 | }
148 |
149 | def newConstantModel[A](items: Seq[A]): ComboBoxModel = items match {
150 | case items: Seq[A] with scala.collection.mutable.Publisher[scala.collection.mutable.Message[A], Self] => newMutableModel
151 | case _ => newConstantModel(items)
152 | }*/
153 | }
154 |
155 | /**
156 | * Let's the user make a selection from a list of predefined items. Visually,
157 | * this is implemented as a button-like component with a pull-down menu.
158 | *
159 | * @see javax.swing.JComboBox
160 | */
161 | class ComboBox[A](items: Seq[A]) extends Component with Publisher {
162 | override lazy val peer: JComboBox = new JComboBox(ComboBox.newConstantModel(items)) with SuperMixin
163 |
164 | object selection extends Publisher {
165 | def index: Int = peer.getSelectedIndex
166 | def index_=(n: Int) { peer.setSelectedIndex(n) }
167 | def item: A = peer.getSelectedItem.asInstanceOf[A]
168 | def item_=(a: A) { peer.setSelectedItem(a) }
169 |
170 | peer.addActionListener(Swing.ActionListener { e =>
171 | publish(event.SelectionChanged(ComboBox.this))
172 | })
173 | }
174 |
175 | /**
176 | * Sets the renderer for this combo box's items. Index -1 is
177 | * passed to the renderer for the selected item (not in the pull-down menu).
178 | *
179 | * The underlying combo box renders all items in a ListView
180 | * (both, in the pull-down menu as well as in the box itself), hence the
181 | * ListView.Renderer
.
182 | *
183 | * Note that the UI peer of a combo box usually changes the colors
184 | * of the component to its own defaults _after_ the renderer has been
185 | * configured. That's Swing's principle of most suprise.
186 | */
187 | def renderer: ListView.Renderer[A] = ListView.Renderer.wrap(peer.getRenderer)
188 | def renderer_=(r: ListView.Renderer[A]) { peer.setRenderer(r.peer) }
189 |
190 | /* XXX: currently not safe to expose:
191 | def editor: ComboBox.Editor[A] =
192 | def editor_=(r: ComboBox.Editor[A]) { peer.setEditor(r.comboBoxPeer) }
193 | */
194 | def editable: Boolean = peer.isEditable
195 |
196 | /**
197 | * Makes this combo box editable. In order to do so, this combo needs an
198 | * editor which is supplied by the implicit argument. For default
199 | * editors, see ComboBox companion object.
200 | */
201 | def makeEditable()(implicit editor: ComboBox[A] => ComboBox.Editor[A]) {
202 | peer.setEditable(true)
203 | peer.setEditor(editor(this).comboBoxPeer)
204 | }
205 |
206 | def prototypeDisplayValue: Option[A] = toOption[A](peer.getPrototypeDisplayValue)
207 | def prototypeDisplayValue_=(v: Option[A]) {
208 | peer.setPrototypeDisplayValue(v map toAnyRef orNull)
209 | }
210 | }
211 |
--------------------------------------------------------------------------------
/scala/swing/Container.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import event._
14 | import scala.collection.mutable.Buffer
15 |
16 | object Container {
17 | /**
18 | * Utility trait for wrapping containers. Provides an immutable
19 | * implementation of the contents member.
20 | */
21 | trait Wrapper extends Container with Publisher {
22 | override def peer: javax.swing.JComponent
23 |
24 | protected val _contents = new Content
25 | def contents: Seq[Component] = _contents
26 |
27 | protected class Content extends BufferWrapper[Component] {
28 | override def clear { peer.removeAll() }
29 | override def remove(n: Int): Component = {
30 | val c = peer.getComponent(n)
31 | peer.remove(n)
32 | UIElement.cachedWrapper[Component](c)
33 | }
34 | protected def insertAt(n: Int, c: Component) { peer.add(c.peer, n) }
35 | def +=(c: Component): this.type = { peer.add(c.peer) ; this }
36 | def length = peer.getComponentCount
37 | def apply(n: Int) = UIElement.cachedWrapper[Component](peer.getComponent(n))
38 | }
39 |
40 | peer.addContainerListener(new java.awt.event.ContainerListener {
41 | def componentAdded(e: java.awt.event.ContainerEvent) {
42 | publish(ComponentAdded(Wrapper.this,
43 | UIElement.cachedWrapper[Component](e.getChild.asInstanceOf[javax.swing.JComponent])))
44 | }
45 | def componentRemoved(e: java.awt.event.ContainerEvent) {
46 | publish(ComponentRemoved(Wrapper.this,
47 | UIElement.cachedWrapper[Component](e.getChild.asInstanceOf[javax.swing.JComponent])))
48 | }
49 | })
50 | }
51 | }
52 |
53 | /**
54 | * The base traits for UI elements that can contain Component
s.
55 | *
56 | * @note [Java Swing] This is not the wrapper for java.awt.Container but a trait
57 | * that extracts a common interface for components, menus, and windows.
58 | */
59 | trait Container extends UIElement {
60 | /**
61 | * The child components of this container.
62 | */
63 | def contents: Seq[Component]
64 | }
65 |
--------------------------------------------------------------------------------
/scala/swing/EditorPane.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 | package scala.swing
11 |
12 | import event._
13 | import javax.swing._
14 | import javax.swing.text._
15 | import java.awt.event._
16 |
17 | /**
18 | * A text component that allows multiline text input and display.
19 | *
20 | * @see javax.swing.JEditorPane
21 | */
22 | class EditorPane(contentType0: String, text0: String) extends TextComponent {
23 | override lazy val peer: JEditorPane = new JEditorPane(contentType0, text0) with SuperMixin
24 | def this() = this("text/plain", "")
25 |
26 | def contentType: String = peer.getContentType
27 | def contentType_=(t: String) = peer.setContentType(t)
28 |
29 | def editorKit: EditorKit = peer.getEditorKit
30 | def editorKit_=(k: EditorKit) = peer.setEditorKit(k)
31 | }
32 |
--------------------------------------------------------------------------------
/scala/swing/FileChooser.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import java.io.File
14 | import javax.swing._
15 | import javax.swing.filechooser._
16 |
17 | object FileChooser {
18 | /**
19 | * The result of a file dialog. The precise meaning of the Approve
20 | * result depends on the specific dialog type. Could be "save" or "open" for
21 | * example.
22 | */
23 | object Result extends Enumeration {
24 | val Cancel = Value(JFileChooser.CANCEL_OPTION)
25 | val Approve = Value(JFileChooser.APPROVE_OPTION)
26 | val Error = Value(JFileChooser.ERROR_OPTION)
27 | }
28 |
29 | /**
30 | * The kind of elements a user can select in a file dialog.
31 | */
32 | object SelectionMode extends Enumeration {
33 | val FilesOnly = Value(JFileChooser.FILES_ONLY)
34 | val DirectoriesOnly = Value(JFileChooser.DIRECTORIES_ONLY)
35 | val FilesAndDirectories = Value(JFileChooser.FILES_AND_DIRECTORIES)
36 | }
37 | }
38 |
39 | /**
40 | * Used to open file dialogs.
41 | *
42 | * @see javax.swing.JFileChooser
43 | */
44 | class FileChooser(dir: File) {
45 | import FileChooser._
46 | lazy val peer: JFileChooser = new JFileChooser(dir)
47 |
48 | def this() = this(null)
49 |
50 | import Swing._
51 | def showOpenDialog(over: Component): Result.Value = Result(peer.showOpenDialog(nullPeer(over)))
52 | def showSaveDialog(over: Component): Result.Value = Result(peer.showSaveDialog(nullPeer(over)))
53 | def showDialog(over: Component, approveText: String): Result.Value = Result(peer.showDialog(nullPeer(over), approveText))
54 |
55 | def controlButtonsAreShown: Boolean = peer.getControlButtonsAreShown
56 | def controlButtonsAreShown_=(b: Boolean) { peer.setControlButtonsAreShown(b) }
57 |
58 | def title: String = peer.getDialogTitle
59 | def title_=(t: String) { peer.setDialogTitle(t) }
60 |
61 | def accessory: Component = UIElement.cachedWrapper[Component](peer.getAccessory)
62 | def accessory_=(c: Component) { peer.setAccessory(c.peer) }
63 |
64 | def fileHidingEnabled: Boolean = peer.isFileHidingEnabled
65 | def fileHidingEnabled_=(b: Boolean) { peer.setFileHidingEnabled(b) }
66 | def fileSelectionMode: SelectionMode.Value = SelectionMode(peer.getFileSelectionMode)
67 | def fileSelectionMode_=(s: SelectionMode.Value) { peer.setFileSelectionMode(s.id) }
68 | def fileFilter: FileFilter = peer.getFileFilter
69 | def fileFilter_=(f: FileFilter) { peer.setFileFilter(f) }
70 |
71 | def selectedFile: File = peer.getSelectedFile
72 | def selectedFile_=(file: File) { peer.setSelectedFile(file) }
73 | def selectedFiles: Seq[File] = peer.getSelectedFiles
74 | def selectedFiles_=(files: File*) { peer.setSelectedFiles(files.toArray) }
75 |
76 | def multiSelectionEnabled: Boolean = peer.isMultiSelectionEnabled
77 | def multiSelectionEnabled_=(b: Boolean) { peer.setMultiSelectionEnabled(b) }
78 |
79 | def iconFor(f: File) = peer.getIcon(f)
80 | def descriptionFor(f: File) = peer.getDescription(f)
81 | def nameFor(f: File) = peer.getName(f)
82 | def typeDescriptionFor(f: File) = peer.getTypeDescription(f)
83 | def traversable(f: File) = peer.isTraversable(f)
84 |
85 | def acceptAllFileFilter = peer.getAcceptAllFileFilter
86 |
87 | /*peer.addPropertyChangeListener(new java.beans.PropertyChangeListener {
88 | def propertyChange(e: java.beans.PropertyChangeEvent) {
89 | import JFileChooser._
90 | e.getPropertyName match {
91 | case APPROVE_BUTTON_TEXT_CHANGED_PROPERTY =>
92 | case ACCESSORY_CHANGED_PROPERTY =>
93 | case APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY =>
94 | case APPROVE_BUTTON_TEXT_CHANGED_PROPERTY =>
95 | case APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY =>
96 | case CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY =>
97 | case CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY =>
98 | case DIALOG_TITLE_CHANGED_PROPERTY =>
99 | case DIALOG_TYPE_CHANGED_PROPERTY =>
100 | case DIRECTORY_CHANGED_PROPERTY =>
101 | case FILE_FILTER_CHANGED_PROPERTY =>
102 | case FILE_HIDING_CHANGED_PROPERTY =>
103 | case FILE_SELECTION_MODE_CHANGED_PROPERTY =>
104 | case FILE_SYSTEM_VIEW_CHANGED_PROPERTY =>
105 | case FILE_VIEW_CHANGED_PROPERTY =>
106 | case MULTI_SELECTION_ENABLED_CHANGED_PROPERTY =>
107 | case SELECTED_FILE_CHANGED_PROPERTY =>
108 | case SELECTED_FILES_CHANGED_PROPERTY =>
109 | case _ =>
110 | }
111 | }
112 | })*/
113 | }
114 |
--------------------------------------------------------------------------------
/scala/swing/FlowPanel.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import java.awt.FlowLayout
14 | import javax.swing.JPanel
15 |
16 | object FlowPanel {
17 | object Alignment extends Enumeration {
18 | val Leading = Value(FlowLayout.LEADING)
19 | val Trailing = Value(FlowLayout.TRAILING)
20 | val Left = Value(FlowLayout.LEFT)
21 | val Right = Value(FlowLayout.RIGHT)
22 | val Center = Value(FlowLayout.CENTER)
23 | }
24 | }
25 |
26 | /**
27 | * A panel that arranges its contents horizontally, one after the other.
28 | * If they don't fit, this panel will try to insert line breaks.
29 | *
30 | * @see java.awt.FlowLayout
31 | */
32 | class FlowPanel(alignment: FlowPanel.Alignment.Value)(contents0: Component*) extends Panel with SequentialContainer.Wrapper {
33 | override lazy val peer: JPanel =
34 | new JPanel(new java.awt.FlowLayout(alignment.id)) with SuperMixin
35 | def this(contents0: Component*) = this(FlowPanel.Alignment.Center)(contents0: _*)
36 | def this() = this(FlowPanel.Alignment.Center)()
37 |
38 | contents ++= contents0
39 |
40 | private def layoutManager = peer.getLayout.asInstanceOf[java.awt.FlowLayout]
41 |
42 | def vGap: Int = layoutManager.getVgap
43 | def vGap_=(n: Int) { layoutManager.setVgap(n) }
44 | def hGap: Int = layoutManager.getHgap
45 | def hGap_=(n: Int) { layoutManager.setHgap(n) }
46 | }
47 |
--------------------------------------------------------------------------------
/scala/swing/Font.scala.disabled:
--------------------------------------------------------------------------------
1 | package scala.swing
2 |
3 | /*object Font {
4 | def apply(fontFormat: Int, fontFile: java.io.File) = java.awt.Font.createFont(fontFormat, fontFile)
5 | def apply(fontFormat: Int, fontStream: java.io.InputStream) = java.awt.Font.createFont(fontFormat, fontStream)
6 | def decode(str: String) = java.awt.Font.decode(str)
7 |
8 | /* TODO: finish implementation
9 | /**
10 | * See [java.awt.Font.getFont].
11 | */
12 | def get(attributes: Map[_ <: java.text.AttributedCharacterIterator.Attribute, _]) =
13 | java.awt.Font.getFont(ImmutableMapWrapper(attributes))
14 |
15 | import java.{util => ju}
16 | private case class ImmutableMapWrapper[A, B](underlying : Map[A, B])(m : ClassManifest[A]) extends ju.AbstractMap[A, B] {
17 | self =>
18 | override def size = underlying.size
19 |
20 | override def put(k : A, v : B) =
21 | throw new UnsupportedOperationException("This is a wrapper that does not support mutation")
22 | override def remove(k : AnyRef) =
23 | throw new UnsupportedOperationException("This is a wrapper that does not support mutation")
24 |
25 | override def entrySet : ju.Set[ju.Map.Entry[A, B]] = new ju.AbstractSet[ju.Map.Entry[A, B]] {
26 | def size = self.size
27 |
28 | def iterator = new ju.Iterator[ju.Map.Entry[A, B]] {
29 | val ui = underlying.iterator
30 | var prev : Option[A] = None
31 |
32 | def hasNext = ui.hasNext
33 |
34 | def next = {
35 | val (k, v) = ui.next
36 | prev = Some(k)
37 | new ju.Map.Entry[A, B] {
38 | def getKey = k
39 | def getValue = v
40 | def setValue(v1 : B) = self.put(k, v1)
41 | override def equals(other : Any) = other match {
42 | case e : ju.Map.Entry[_, _] => k == e.getKey && v == e.getValue
43 | case _ => false
44 | }
45 | }
46 | }
47 |
48 | def remove = prev match {
49 | case Some(k) => val v = self.remove(k.asInstanceOf[AnyRef]) ; prev = None ; v
50 | case _ => throw new IllegalStateException("next must be called at least once before remove")
51 | }
52 | }
53 | }
54 | }
55 | */
56 |
57 | /**
58 | * See [java.awt.Font.getFont].
59 | */
60 | def get(nm: String) = java.awt.Font.getFont(nm)
61 | /**
62 | * See [java.awt.Font.getFont].
63 | */
64 | def get(nm: String, font: Font) = java.awt.Font.getFont(nm, font)
65 |
66 | def Insets(x: Int, y: Int, width: Int, height: Int) = new Insets(x, y, width, height)
67 | def Rectangle(x: Int, y: Int, width: Int, height: Int) = new Insets(x, y, width, height)
68 | def Point(x: Int, y: Int) = new Point(x, y)
69 | def Dimension(x: Int, y: Int) = new Dimension(x, y)
70 | }*/
--------------------------------------------------------------------------------
/scala/swing/FormattedTextField.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import event._
14 | import javax.swing._
15 | import java.awt.event._
16 |
17 | object FormattedTextField {
18 | /**
19 | * The behavior of a formatted text field when it loses its focus.
20 | */
21 | object FocusLostBehavior extends Enumeration {
22 | val Commit = Value(JFormattedTextField.COMMIT)
23 | val CommitOrRevert = Value(JFormattedTextField.COMMIT_OR_REVERT)
24 | val Persist = Value(JFormattedTextField.PERSIST)
25 | val Revert = Value(JFormattedTextField.REVERT)
26 | }
27 | }
28 |
29 | /**
30 | * A text field with formatted input.
31 | *
32 | * @see javax.swing.JFormattedTextField
33 | */
34 | class FormattedTextField(format: java.text.Format) extends TextComponent {
35 | override lazy val peer: JFormattedTextField = new JFormattedTextField(format) with SuperMixin
36 |
37 | import FormattedTextField._
38 |
39 | def commitEdit() { peer.commitEdit() }
40 | def editValid: Boolean = peer.isEditValid
41 |
42 | def focusLostBehavior: FocusLostBehavior.Value = FocusLostBehavior(peer.getFocusLostBehavior)
43 | def focusLostBehavior_=(b: FocusLostBehavior.Value) { peer.setFocusLostBehavior(b.id) }
44 | }
45 |
--------------------------------------------------------------------------------
/scala/swing/GUIApplication.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import event.Event
14 | import javax.swing._
15 |
16 | /**
17 | * Convenience class with utility methods for GUI applications.
18 | */
19 | @deprecated("Use SwingApplication instead") class GUIApplication {
20 |
21 | /**
22 | * Called before the GUI is created. Override to customize.
23 | */
24 | def init() {}
25 |
26 | /**
27 | * Initializes the framework and runs the given program.
28 | */
29 | def run(prog: => Unit) = Swing.onEDT { init(); prog }
30 | }
31 |
--------------------------------------------------------------------------------
/scala/swing/GridBagPanel.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import java.awt.{GridBagConstraints, GridBagLayout}
14 |
15 |
16 | object GridBagPanel {
17 | object Fill extends Enumeration {
18 | val None = Value(GridBagConstraints.NONE)
19 | val Horizontal = Value(GridBagConstraints.HORIZONTAL)
20 | val Vertical = Value(GridBagConstraints.VERTICAL)
21 | val Both = Value(GridBagConstraints.BOTH)
22 | }
23 | object Anchor extends Enumeration {
24 | val North = Value(GridBagConstraints.NORTH)
25 | val NorthEast = Value(GridBagConstraints.NORTHEAST)
26 | val East = Value(GridBagConstraints.EAST)
27 | val SouthEast = Value(GridBagConstraints.SOUTHEAST)
28 | val South = Value(GridBagConstraints.SOUTH)
29 | val SouthWest = Value(GridBagConstraints.SOUTHWEST)
30 | val West = Value(GridBagConstraints.WEST)
31 | val NorthWest = Value(GridBagConstraints.NORTHWEST)
32 | val Center = Value(GridBagConstraints.CENTER)
33 |
34 | val PageStart = Value(GridBagConstraints.PAGE_START)
35 | val PageEnd = Value(GridBagConstraints.PAGE_END)
36 | val LineStart = Value(GridBagConstraints.LINE_START)
37 | val LineEnd = Value(GridBagConstraints.LINE_END)
38 | val FirstLineStart = Value(GridBagConstraints.FIRST_LINE_START)
39 | val FirstLineEnd = Value(GridBagConstraints.FIRST_LINE_END)
40 | val LastLineStart = Value(GridBagConstraints.LAST_LINE_START)
41 | val LastLineEnd = Value(GridBagConstraints.LAST_LINE_END)
42 | }
43 | }
44 |
45 | /**
46 | * A panel that arranges its children in a grid. Layout details can be
47 | * given for each cell of the grid.
48 | *
49 | * @see java.awt.GridBagLayout
50 | */
51 | class GridBagPanel extends Panel with LayoutContainer {
52 | override lazy val peer = new javax.swing.JPanel(new GridBagLayout) with SuperMixin
53 | import GridBagPanel._
54 |
55 | private def layoutManager = peer.getLayout.asInstanceOf[GridBagLayout]
56 |
57 | /**
58 | * Convenient conversion from xy-coords given as pairs to
59 | * grid bag constraints.
60 | */
61 | implicit def pair2Constraints(p: (Int, Int)): Constraints = {
62 | val c = new Constraints
63 | c.gridx = p._1
64 | c.gridy = p._2
65 | c
66 | }
67 |
68 | class Constraints(val peer: GridBagConstraints) extends Proxy {
69 | def self = peer
70 | def this(gridx: Int, gridy: Int,
71 | gridwidth: Int, gridheight: Int,
72 | weightx: Double, weighty: Double,
73 | anchor: Int, fill: Int, insets: Insets,
74 | ipadx: Int, ipady: Int) =
75 | this(new GridBagConstraints(gridx, gridy,
76 | gridwidth, gridheight,
77 | weightx, weighty,
78 | anchor, fill, insets,
79 | ipadx, ipady))
80 | def this() = this(new GridBagConstraints())
81 | def gridx: Int = peer.gridx
82 | def gridx_=(x: Int) { peer.gridx = x }
83 | def gridy: Int = peer.gridy
84 | def gridy_=(y: Int) { peer.gridy = y }
85 | def grid: (Int, Int) = (gridx, gridy)
86 | def grid_=(c: (Int, Int)) = {
87 | gridx = c._1
88 | gridy = c._2
89 | }
90 |
91 | def gridwidth: Int = peer.gridwidth
92 | def gridwidth_=(w: Int) { peer.gridwidth = w }
93 | def gridheight: Int = peer.gridheight
94 | def gridheight_=(h: Int) { peer.gridheight = h }
95 | def weightx: Double = peer.weightx
96 | def weightx_=(x: Double) { peer.weightx = x }
97 | def weighty: Double = peer.weighty
98 | def weighty_=(y: Double) { peer.weighty = y }
99 | def anchor: Anchor.Value = Anchor(peer.anchor)
100 | def anchor_=(a: Anchor.Value) { peer.anchor = a.id }
101 | def fill: Fill.Value = Fill(peer.fill)
102 | def fill_=(f: Fill.Value) { peer.fill = f.id }
103 | def insets: Insets = peer.insets
104 | def insets_=(i: Insets) { peer.insets = i }
105 | def ipadx: Int = peer.ipadx
106 | def ipadx_=(x: Int) { peer.ipadx = x }
107 | def ipady: Int = peer.ipady
108 | def ipady_=(y: Int) { peer.ipady = y }
109 | }
110 |
111 | protected def constraintsFor(comp: Component) =
112 | new Constraints(layoutManager.getConstraints(comp.peer))
113 |
114 | protected def areValid(c: Constraints): (Boolean, String) = (true, "")
115 | protected def add(c: Component, l: Constraints) { peer.add(c.peer, l.peer) }
116 | }
117 |
--------------------------------------------------------------------------------
/scala/swing/GridPanel.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | object GridPanel {
14 | val Adapt = 0
15 | }
16 |
17 | /**
18 | * A panel that lays out its contents in a uniform grid.
19 | *
20 | * @see java.awt.GridLayout
21 | */
22 | class GridPanel(rows0: Int, cols0: Int) extends Panel with SequentialContainer.Wrapper {
23 | override lazy val peer =
24 | new javax.swing.JPanel(new java.awt.GridLayout(rows0, cols0)) with SuperMixin
25 |
26 | /*type Constraints = (Int, Int)
27 |
28 | protected def constraintsFor(comp: Component) = {
29 | assert(peer.getComponentOrientation.isHorizontal)
30 | val idx = contents.indexOf(comp)
31 | val (r, c) = (((idx-1)/columns)+1, ((idx-1)%columns)+1)
32 | if (peer.getComponentOrientation.isLeftToRight) (r, c)
33 | else (r, columns-c+1)
34 | }
35 |
36 | protected def add(c: Component, l: Constraints) { peer.add(c.peer, (l._1-1)*columns+l._2) }
37 | protected def areValid(c: Constraints): (Boolean, String) =
38 | ((c._1 > 0 && c._2 > 0), "Grid coordinates (row,col) must be >= 1 but where " + c)*/
39 |
40 | private def layoutManager = peer.getLayout.asInstanceOf[java.awt.GridLayout]
41 |
42 | def rows: Int = layoutManager.getRows
43 | def rows_=(n: Int) { layoutManager.setRows(n) }
44 | def columns: Int = layoutManager.getColumns
45 | def columns_=(n: Int) { layoutManager.setColumns(n) }
46 |
47 | def vGap: Int = layoutManager.getVgap
48 | def vGap_=(n: Int) { layoutManager.setVgap(n) }
49 | def hGap: Int = layoutManager.getHgap
50 | def hGap_=(n: Int) { layoutManager.setHgap(n) }
51 | }
52 |
--------------------------------------------------------------------------------
/scala/swing/Label.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import javax.swing._
14 | import scala.swing.Swing._
15 |
16 | /**
17 | * A label component that display either a text, an icon, or both.
18 | *
19 | * @see javax.swing.JLabel
20 | */
21 | class Label(text0: String, icon0: Icon, align: Alignment.Value) extends Component {
22 | override lazy val peer: JLabel =
23 | new JLabel(text0, toNullIcon(icon0), align.id) with SuperMixin
24 |
25 | def this() = this("", EmptyIcon, Alignment.Center)
26 | def this(s: String) = this(s, EmptyIcon, Alignment.Center)
27 | def text: String = peer.getText
28 | def text_=(s: String) = peer.setText(s)
29 | def icon: Icon = peer.getIcon
30 | def icon_=(i: Icon) = peer.setIcon(i)
31 |
32 | /**
33 | * The alignment of the label's contents relative to its bounding box.
34 | */
35 | def xAlignment: Alignment.Value = Alignment(peer.getHorizontalAlignment)
36 | def xAlignment_=(x: Alignment.Value) { peer.setHorizontalAlignment(x.id) }
37 | def yAlignment: Alignment.Value = Alignment(peer.getVerticalAlignment)
38 | def yAlignment_=(x: Alignment.Value) { peer.setVerticalAlignment(x.id) }
39 |
40 | /** @see javax.swing.JLabel#getHorizontalAlignment() */
41 | def horizontalAlignment: Alignment.Value = Alignment(peer.getHorizontalAlignment)
42 | /** @see javax.swing.JLabel#setHorizontalAlignment() */
43 | def horizontalAlignment_=(x: Alignment.Value) { peer.setHorizontalAlignment(x.id) }
44 |
45 | def verticalAlignment: Alignment.Value = Alignment(peer.getVerticalAlignment)
46 | def verticalAlignment_=(x: Alignment.Value) { peer.setVerticalAlignment(x.id) }
47 |
48 | def horizontalTextPosition: Alignment.Value = Alignment(peer.getHorizontalTextPosition)
49 | def horizontalTextPosition_=(x: Alignment.Value) { peer.setHorizontalTextPosition(x.id) }
50 |
51 | def verticalTextPosition: Alignment.Value = Alignment(peer.getVerticalTextPosition)
52 | def verticalTextPosition_=(x: Alignment.Value) { peer.setVerticalTextPosition(x.id) }
53 |
54 | def disabledIcon: Icon = peer.getDisabledIcon
55 | def disabledIcon_=(icon: Icon) { peer.setDisabledIcon(icon) }
56 |
57 | def iconTextGap: Int = peer.getIconTextGap
58 | def iconTextGap_=(gap: Int) { peer.setIconTextGap(gap) }
59 |
60 | def displayedMnemonicIndex: Int = peer.getDisplayedMnemonicIndex
61 | def displayedMnemonicIndex_=(index: Int) { peer.setDisplayedMnemonicIndex(index) }
62 | }
63 |
--------------------------------------------------------------------------------
/scala/swing/LayoutContainer.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import javax.swing.JComponent
14 | import scala.collection.mutable.Map
15 |
16 | /**
17 | * A container that associates layout constraints of member type
18 | * Constraints
with its children. See GridBagPanel
19 | * for an example container with custom constraints.
20 | *
Oriented
whose orientation can be changed.
21 | */
22 | trait Orientable extends Oriented {
23 | def orientation_=(o: Orientation.Value)
24 | }
25 |
--------------------------------------------------------------------------------
/scala/swing/Orientation.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import java.awt.Adjustable._
14 |
15 | object Orientation extends Enumeration {
16 | val Horizontal = Value(HORIZONTAL)
17 | val Vertical = Value(VERTICAL)
18 | val NoOrientation = Value(NO_ORIENTATION)
19 | }
20 |
--------------------------------------------------------------------------------
/scala/swing/Oriented.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | object Oriented {
14 | trait Wrapper extends Oriented {
15 | def peer: OrientedMixin
16 |
17 | /*
18 | * Need to revert to structural type, since scroll bars are oriented
19 | * and these are created by scroll panes. Shouldn't be a bootleneck.
20 | */
21 | protected type OrientedMixin = {
22 | def getOrientation(): Int
23 | def setOrientation(n: Int)
24 | }
25 | def orientation: Orientation.Value = Orientation(peer.getOrientation)
26 | }
27 | }
28 |
29 | /**
30 | * Something that can have an orientation.
31 | */
32 | trait Oriented {
33 | def orientation: Orientation.Value
34 | }
35 |
--------------------------------------------------------------------------------
/scala/swing/Panel.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | /**
14 | * A component that can contain other components.
15 | *
16 | * @see javax.swing.JPanel
17 | */
18 | abstract class Panel extends Component with Container.Wrapper {
19 | override lazy val peer: javax.swing.JPanel = new javax.swing.JPanel with SuperMixin
20 | }
21 |
--------------------------------------------------------------------------------
/scala/swing/PasswordField.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import event._
14 | import javax.swing._
15 | import java.awt.event._
16 |
17 | /**
18 | * A password field, that displays a replacement character for each character in the password.
19 | *
20 | * @see javax.swing.JPasswordField
21 | */
22 | class PasswordField(text0: String, columns0: Int) extends TextField(text0, columns0) {
23 | override lazy val peer: JPasswordField = new JPasswordField(text0, columns0) with SuperMixin
24 | def this(text: String) = this(text, 0)
25 | def this(columns: Int) = this("", columns)
26 | def this() = this("")
27 |
28 | def echoChar: Char = peer.getEchoChar
29 | def echoChar_=(c: Char) = peer.setEchoChar(c)
30 |
31 | /**
32 | * The text property should not be used on a password field for
33 | * security reasons.
34 | */
35 | override def text: String = ""
36 | override def text_=(s: String) {}
37 | def password: Array[Char] = peer.getPassword
38 | }
39 |
--------------------------------------------------------------------------------
/scala/swing/ProgressBar.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import event._
14 |
15 | /**
16 | * A bar indicating progress of some action. Can be in indeterminate mode,
17 | * in which it indicates that the action is in progress (usually by some
18 | * animation) but does not indicate the amount of work done or to be done.
19 | *
20 | * @see javax.swing.JProgressBar
21 | */
22 | class ProgressBar extends Component with Orientable.Wrapper {
23 | override lazy val peer: javax.swing.JProgressBar =
24 | new javax.swing.JProgressBar with SuperMixin
25 |
26 | def min: Int = peer.getMinimum
27 | def min_=(v: Int) { peer.setMinimum(v) }
28 | def max: Int = peer.getMaximum
29 | def max_=(v: Int) { peer.setMaximum(v) }
30 | def value: Int = peer.getValue
31 | def value_=(v: Int) { peer.setValue(v) }
32 |
33 | def labelPainted: Boolean = peer.isStringPainted
34 | def labelPainted_=(v: Boolean) { peer.setStringPainted(v) }
35 |
36 | def label: String = peer.getString
37 | def label_=(v: String) = peer.setString(v)
38 |
39 | def indeterminate: Boolean = peer.isIndeterminate
40 | def indeterminate_=(v: Boolean) { peer.setIndeterminate(v) }
41 |
42 | def paintBorder: Boolean = peer.isBorderPainted
43 | def paintBorder(v: Boolean) { peer.setBorderPainted(v) }
44 | }
45 |
--------------------------------------------------------------------------------
/scala/swing/Publisher.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import scala.collection._
14 | import scala.collection.mutable.{Buffer, HashSet, Set}
15 | import event.Event
16 |
17 | /** 18 | * Notifies registered reactions when an event is published. Publishers are 19 | * also reactors and listen to themselves per default as a convenience. 20 | *
21 | *
22 | * In order to reduce memory leaks, reactions are weakly referenced by default,
23 | * unless they implement Reactions.StronglyReferenced
. That way,
24 | * the lifetime of reactions are more easily bound to the registering object,
25 | * which are reactors in common client code and hold strong references to their
26 | * reactions. As a result, reactors can be garbage collected even though they
27 | * still have reactions registered at some publisher, but not vice versa
28 | * since reactors (strongly) reference publishers they are interested in.
29 | *
ButtonGroup
17 | * together with other RadioButton
s, in order to indicate
18 | * that at most one of them can be selected.
19 | *
20 | * @see javax.swing.JRadioButton
21 | */
22 | class RadioButton(text0: String) extends ToggleButton {
23 | override lazy val peer: JRadioButton = new JRadioButton(text0) with SuperMixin
24 | def this() = this("")
25 | }
26 |
--------------------------------------------------------------------------------
/scala/swing/Reactions.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import event.Event
14 | import scala.collection.mutable.{Buffer, ListBuffer}
15 |
16 | object Reactions {
17 | import scala.ref._
18 |
19 | class Impl extends Reactions {
20 | private val parts: Buffer[Reaction] = new ListBuffer[Reaction]
21 | def isDefinedAt(e: Event) = parts.exists(_ isDefinedAt e)
22 | def += (r: Reaction): this.type = { parts += r; this }
23 | def -= (r: Reaction): this.type = { parts -= r; this }
24 | def apply(e: Event) {
25 | for (p <- parts) if (p isDefinedAt e) p(e)
26 | }
27 | }
28 |
29 | type Reaction = PartialFunction[Event, Unit]
30 |
31 | /**
32 | * A Reaction implementing this trait is strongly referenced in the reaction list
33 | */
34 | trait StronglyReferenced
35 |
36 | class Wrapper(listener: Any)(r: Reaction) extends Reaction with StronglyReferenced with Proxy {
37 | def self = listener
38 | def isDefinedAt(e: Event) = r.isDefinedAt(e)
39 | def apply(e: Event) { r(e) }
40 | }
41 | }
42 |
43 | /**
44 | * Used by reactors to let clients register custom event reactions.
45 | */
46 | abstract class Reactions extends Reactions.Reaction {
47 | /**
48 | * Add a reaction.
49 | */
50 | def += (r: Reactions.Reaction): this.type
51 |
52 | /**
53 | * Remove the given reaction.
54 | */
55 | def -= (r: Reactions.Reaction): this.type
56 | }
57 |
--------------------------------------------------------------------------------
/scala/swing/Reactor.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | /**
14 | * The counterpart to publishers. Listens to events from registered publishers.
15 | */
16 | trait Reactor {
17 | /**
18 | * All reactions of this reactor.
19 | */
20 | val reactions: Reactions = new Reactions.Impl
21 | /**
22 | * Listen to the given publisher as long as deafTo
isn't called for
23 | * them.
24 | */
25 | def listenTo(ps: Publisher*) = for (p <- ps) p.subscribe(reactions)
26 | /**
27 | * Installed reaction won't receive events from the given publisher anylonger.
28 | */
29 | def deafTo(ps: Publisher*) = for (p <- ps) p.unsubscribe(reactions)
30 | }
31 |
--------------------------------------------------------------------------------
/scala/swing/RichWindow.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import java.awt.{Window => AWTWindow, Frame => AWTFrame}
14 | import javax.swing._
15 | import Swing._
16 |
17 | object RichWindow {
18 | /**
19 | * Mixin this trait if you want an undecorated window.
20 | */
21 | trait Undecorated extends RichWindow {
22 | // we do a mixin here, since setUndecorated is only allowed to be called
23 | // when the component is not displayable.
24 | peer.setUndecorated(true)
25 | }
26 | }
27 |
28 | /**
29 | * A window that adds some functionality to the plain Window class and serves as
30 | * the common base class for frames and dialogs.
31 | *
32 | * Implementation note: this class is sealed since we need to know that a rich
33 | * window is either a dialog or a frame at some point.
34 | */
35 | sealed trait RichWindow extends Window {
36 | def peer: AWTWindow with InterfaceMixin
37 |
38 | trait InterfaceMixin extends super.InterfaceMixin {
39 | def getJMenuBar: JMenuBar
40 | def setJMenuBar(b: JMenuBar)
41 | def setUndecorated(b: Boolean)
42 | def setTitle(s: String)
43 | def getTitle: String
44 | def setResizable(b: Boolean)
45 | def isResizable: Boolean
46 | }
47 |
48 | def title: String = peer.getTitle
49 | def title_=(s: String) = peer.setTitle(s)
50 |
51 | /**
52 | * The menu bar of this frame or `NoMenuBar` if no menu bar is set.
53 | */
54 | def menuBar: MenuBar = {
55 | val m = UIElement.cachedWrapper[MenuBar](peer.getJMenuBar)
56 | if (m != null) m else MenuBar.NoMenuBar
57 | }
58 | /**
59 | * Set the current menu bar of this frame. Pass `NoMenuBar` if this frame
60 | * should not show a menu bar.
61 | */
62 | def menuBar_=(m: MenuBar) =
63 | peer.setJMenuBar(if(m == MenuBar.NoMenuBar) null else m.peer)
64 |
65 | def resizable_=(b: Boolean) { peer.setResizable(b) }
66 | def resizable = peer.isResizable
67 | }
68 |
69 | /**
70 | * A window with decoration such as a title, border, and action buttons.
71 | *
72 | * An AWT window cannot be wrapped dynamically with this class, i.e., you cannot
73 | * write something like new Window { def peer = myAWTWindow }
74 | *
75 | * @see javax.swing.JFrame
76 | */
77 | class Frame extends RichWindow {
78 | override lazy val peer: JFrame with InterfaceMixin = new JFrame with InterfaceMixin with SuperMixin
79 |
80 | protected trait SuperMixin extends JFrame {
81 | override protected def processWindowEvent(e: java.awt.event.WindowEvent) {
82 | super.processWindowEvent(e)
83 | if (e.getID() == java.awt.event.WindowEvent.WINDOW_CLOSING)
84 | closeOperation()
85 | }
86 | }
87 |
88 | def iconify() { peer.setExtendedState(peer.getExtendedState | AWTFrame.ICONIFIED) }
89 | def uniconify() { peer.setExtendedState(peer.getExtendedState & ~AWTFrame.ICONIFIED) }
90 | def iconified() { (peer.getExtendedState & AWTFrame.ICONIFIED) != 0 }
91 | def maximize() { peer.setExtendedState(peer.getExtendedState | AWTFrame.MAXIMIZED_BOTH) }
92 | def unmaximize() { peer.setExtendedState(peer.getExtendedState & ~AWTFrame.MAXIMIZED_BOTH) }
93 | def maximized() { (peer.getExtendedState & AWTFrame.MAXIMIZED_BOTH) != 0 }
94 |
95 | def iconImage: Image = peer.getIconImage
96 | def iconImage_=(i: Image) { peer.setIconImage(i) }
97 | }
98 |
99 | /**
100 | * Simple predefined dialogs.
101 | *
102 | * @see javax.swing.JOptionPane
103 | */
104 | object Dialog {
105 | /**
106 | * The message type of a dialog.
107 | */
108 | object Message extends Enumeration {
109 | val Error = Value(JOptionPane.ERROR_MESSAGE)
110 | val Info = Value(JOptionPane.INFORMATION_MESSAGE)
111 | val Warning = Value(JOptionPane.WARNING_MESSAGE)
112 | val Question = Value(JOptionPane.QUESTION_MESSAGE)
113 | val Plain = Value(JOptionPane.PLAIN_MESSAGE)
114 | }
115 |
116 | /**
117 | * The possible answers a user can select.
118 | */
119 | object Options extends Enumeration {
120 | val Default = Value(JOptionPane.DEFAULT_OPTION)
121 | val YesNo = Value(JOptionPane.YES_NO_OPTION)
122 | val YesNoCancel = Value(JOptionPane.YES_NO_CANCEL_OPTION)
123 | val OkCancel = Value(JOptionPane.OK_CANCEL_OPTION)
124 | }
125 |
126 | /**
127 | * The selected result of dialog.
128 | */
129 | object Result extends Enumeration {
130 | val Yes = Value(JOptionPane.YES_OPTION)
131 | val Ok = Yes
132 | val No = Value(JOptionPane.NO_OPTION)
133 | val Cancel = Value(JOptionPane.CANCEL_OPTION)
134 | val Closed = Value(JOptionPane.CLOSED_OPTION)
135 | }
136 |
137 | private def uiString(txt: String) = UIManager.getString(txt)
138 |
139 | def showConfirmation(parent: Component = null,
140 | message: Any,
141 | title: String = uiString("OptionPane.titleText"),
142 | optionType: Options.Value = Options.YesNo,
143 | messageType: Message.Value = Message.Question,
144 | icon: Icon = EmptyIcon): Result.Value =
145 | Result(JOptionPane.showConfirmDialog(nullPeer(parent), message, title,
146 | optionType.id, messageType.id, Swing.wrapIcon(icon)))
147 |
148 | def showOptions(parent: Component = null,
149 | message: Any,
150 | title: String = uiString("OptionPane.titleText"),
151 | optionType: Options.Value = Options.YesNo,
152 | messageType: Message.Value = Message.Question,
153 | icon: Icon = EmptyIcon,
154 | entries: Seq[Any],
155 | initial: Int): Result.Value = {
156 | val r = JOptionPane.showOptionDialog(nullPeer(parent), message, title,
157 | optionType.id, messageType.id, Swing.wrapIcon(icon),
158 | entries map toAnyRef toArray, entries(initial))
159 | Result(r)
160 | }
161 |
162 | def showInput[A](parent: Component = null,
163 | message: Any,
164 | title: String = uiString("OptionPane.inputDialogTitle"),
165 | messageType: Message.Value = Message.Question,
166 | icon: Icon = EmptyIcon,
167 | entries: Seq[A] = Nil,
168 | initial: A): Option[A] = {
169 | val e = if (entries.isEmpty) null
170 | else entries map toAnyRef toArray
171 | val r = JOptionPane.showInputDialog(nullPeer(parent), message, title,
172 | messageType.id, Swing.wrapIcon(icon),
173 | e, initial)
174 |
175 | toOption[A](r)
176 | }
177 | def showMessage(parent: Component = null,
178 | message: Any,
179 | title: String = uiString("OptionPane.messageDialogTitle"),
180 | messageType: Message.Value = Message.Info,
181 | icon: Icon = EmptyIcon) {
182 | JOptionPane.showMessageDialog(nullPeer(parent), message, title,
183 | messageType.id, Swing.wrapIcon(icon))
184 | }
185 | }
186 |
187 | /**
188 | * A dialog window.
189 | *
190 | * @see javax.swing.JDialog
191 | */
192 | class Dialog(owner: Window) extends RichWindow {
193 | override lazy val peer: JDialog with InterfaceMixin =
194 | if (owner == null) new JDialog with InterfaceMixin
195 | else owner match {
196 | case f: Frame => new JDialog(f.peer) with InterfaceMixin
197 | case d: Dialog => new JDialog(d.peer) with InterfaceMixin
198 | }
199 |
200 | def this() = this(null)
201 |
202 | def modal_=(b: Boolean) { peer.setModal(b) }
203 | def modal = peer.isModal
204 | }
205 |
206 |
--------------------------------------------------------------------------------
/scala/swing/RootPanel.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | /**
14 | * The root of a component hierarchy. Contains at most one component.
15 | *
16 | * @see javax.swing.RootPaneContainer
17 | */
18 | trait RootPanel extends Container {
19 | def peer: java.awt.Component with javax.swing.RootPaneContainer
20 |
21 | /**
22 | * At most one component.
23 | */
24 | def contents: Seq[Component] =
25 | if (peer.getContentPane.getComponentCount == 0) Nil
26 | else {
27 | val c = peer.getContentPane.getComponent(0).asInstanceOf[javax.swing.JComponent]
28 | List(UIElement.cachedWrapper[Component](c))
29 | }
30 |
31 | def contents_=(c: Component) {
32 | if (peer.getContentPane.getComponentCount > 0) {
33 | val old = peer.getContentPane.getComponent(0)
34 | peer.getContentPane.remove(old)
35 | }
36 | peer.getContentPane.add(c.peer)
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/scala/swing/ScrollBar.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import javax.swing.{JScrollBar, BoundedRangeModel}
14 | import java.awt.event.{AdjustmentListener}
15 |
16 | object ScrollBar {
17 | def wrap(c: JScrollBar): ScrollBar = {
18 | val w = UIElement.cachedWrapper[ScrollBar](c)
19 | if (w != null) w
20 | else new ScrollBar { override lazy val peer = c }
21 | }
22 | }
23 |
24 | class ScrollBar extends Component with Orientable.Wrapper with Adjustable.Wrapper {
25 | override lazy val peer: JScrollBar = new JScrollBar with SuperMixin
26 |
27 | def valueIsAjusting = peer.getValueIsAdjusting
28 | def valueIsAjusting_=(b : Boolean) = peer.setValueIsAdjusting(b)
29 |
30 | // TODO: can we find a better interface?
31 | //def setValues(value: Int = this.value, visible: Int = visibleAmount,
32 | // min: Int = minimum, max: Int = maximum) =
33 | // peer.setValues(value, visible, min, max)
34 |
35 | // Not currently needed, requires wrapper for BoundedRangeModel
36 | //
37 | // def model = peer.getModel
38 | // def model_=(m : BoundedRangeModel) = peer.setModel(m)
39 | }
40 |
--------------------------------------------------------------------------------
/scala/swing/ScrollPane.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import javax.swing.{JScrollPane, ScrollPaneConstants}
14 |
15 | object ScrollPane {
16 | object BarPolicy extends Enumeration {
17 | import ScrollPaneConstants._
18 | val AsNeeded = new Value(HORIZONTAL_SCROLLBAR_AS_NEEDED,
19 | VERTICAL_SCROLLBAR_AS_NEEDED)
20 | val Never = new Value(HORIZONTAL_SCROLLBAR_NEVER,
21 | VERTICAL_SCROLLBAR_NEVER)
22 | val Always = new Value(HORIZONTAL_SCROLLBAR_ALWAYS,
23 | VERTICAL_SCROLLBAR_ALWAYS)
24 |
25 | def wrap(id: Int) = id match {
26 | case HORIZONTAL_SCROLLBAR_AS_NEEDED | VERTICAL_SCROLLBAR_AS_NEEDED => AsNeeded
27 | case HORIZONTAL_SCROLLBAR_NEVER | VERTICAL_SCROLLBAR_NEVER => Never
28 | case HORIZONTAL_SCROLLBAR_ALWAYS | VERTICAL_SCROLLBAR_ALWAYS => Always
29 | }
30 | class Value(val horizontalPeer: Int, val verticalPeer: Int) extends super.Val {
31 | override def id = horizontalPeer
32 | }
33 | }
34 | }
35 |
36 | /**
37 | * Can have at most a single child component, which will be put inside a canvas (the viewport)
38 | * that can be scrolled.
39 | *
40 | * @see javax.swing.JScrollPane
41 | */
42 | class ScrollPane extends Component with Container {
43 | import ScrollPane._
44 |
45 | override lazy val peer: JScrollPane = new JScrollPane with SuperMixin
46 | def this(c: Component) = {
47 | this()
48 | contents = c
49 | }
50 | def contents: Seq[Component] =
51 | List(UIElement.cachedWrapper[Component](peer.getViewport.getView.asInstanceOf[javax.swing.JComponent]))
52 |
53 | /**
54 | * Sets the single child.
55 | */
56 | def contents_=(c: Component) { peer.setViewportView(c.peer) }
57 |
58 | /**
59 | * The component being displayed in this pane's row header.
60 | *
61 | * If you want to create a row header for lists or tables, you probably
62 | * want to let the row header be a list view with the same row height as
63 | * the viewport component.
64 | */
65 | def rowHeaderView: Option[Component] =
66 | Option(peer.getRowHeader.getView) map UIElement.cachedWrapper[Component]
67 | def rowHeaderView_=(c: Component) = peer.setRowHeaderView(c.peer)
68 | def rowHeaderView_=(c: Option[Component]) = peer.setRowHeaderView(c map (_.peer) orNull)
69 |
70 | def columnHeaderView: Option[Component] =
71 | Option(peer.getColumnHeader.getView) map UIElement.cachedWrapper[Component]
72 | def columnHeaderView_=(c: Component) = peer.setColumnHeaderView(c.peer)
73 | def columnHeaderView_=(c: Option[Component]) = peer.setColumnHeaderView(c map (_.peer) orNull)
74 |
75 | def viewportView: Option[Component] =
76 | Option(peer.getViewport.getView) map UIElement.cachedWrapper[Component]
77 | def viewportView_=(c: Component) = peer.setViewportView(c.peer)
78 | def viewportView_=(c: Option[Component]) = peer.setViewportView(c map (_.peer) orNull)
79 |
80 | def verticalScrollBarPolicy = BarPolicy.wrap(peer.getVerticalScrollBarPolicy)
81 | def verticalScrollBarPolicy_=(p: BarPolicy.Value) = peer.setVerticalScrollBarPolicy(p.verticalPeer)
82 |
83 | def horizontalScrollBarPolicy = BarPolicy.wrap(peer.getHorizontalScrollBarPolicy)
84 | def horizontalScrollBarPolicy_=(p: BarPolicy.Value) = peer.setHorizontalScrollBarPolicy(p.horizontalPeer)
85 |
86 | def horizontalScrollBar = ScrollBar.wrap(peer.getHorizontalScrollBar)
87 | def verticalScrollBar = ScrollBar.wrap(peer.getVerticalScrollBar)
88 | }
89 |
--------------------------------------------------------------------------------
/scala/swing/Scrollable.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | object Scrollable {
14 | trait Wrapper extends Scrollable {
15 | protected def scrollablePeer: javax.swing.Scrollable
16 | def preferredViewportSize = scrollablePeer.getPreferredScrollableViewportSize
17 |
18 | def tracksViewportHeight: Boolean = scrollablePeer.getScrollableTracksViewportHeight
19 | def tracksViewportWidth: Boolean = scrollablePeer.getScrollableTracksViewportWidth
20 |
21 | def blockIncrement(visibleRect: Rectangle, orientation: Orientation.Value, direction: Int): Int =
22 | scrollablePeer.getScrollableBlockIncrement(visibleRect, orientation.id, direction)
23 |
24 | def unitIncrement(visibleRect: Rectangle, orientation: Orientation.Value, direction: Int): Int =
25 | scrollablePeer.getScrollableUnitIncrement(visibleRect, orientation.id, direction)
26 | }
27 | }
28 |
29 | /**
30 | * A component that is specially suitable for being placed inside a
31 | * ScrollPane
.
32 | *
33 | * @see javax.swing.Scrollable
34 | */
35 | trait Scrollable extends Component {
36 | def preferredViewportSize: Dimension
37 |
38 | def tracksViewportHeight: Boolean
39 | def tracksViewportWidth: Boolean
40 |
41 | def blockIncrement(visibleRect: Rectangle, orientation: Orientation.Value, direction: Int): Int
42 | def unitIncrement(visibleRect: Rectangle, orientation: Orientation.Value, direction: Int): Int
43 | }
44 |
--------------------------------------------------------------------------------
/scala/swing/Separator.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import javax.swing._
14 |
15 | /**
16 | * A bar that can be used a separator, most commonly in menus.
17 | *
18 | * @see javax.swing.JSeparator
19 | */
20 | class Separator(o: Orientation.Value) extends Component with Oriented.Wrapper {
21 | override lazy val peer: JSeparator = new JSeparator(o.id) with SuperMixin
22 | def this() = this(Orientation.Horizontal)
23 | }
24 |
--------------------------------------------------------------------------------
/scala/swing/SequentialContainer.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import scala.collection.mutable.Buffer
14 |
15 | object SequentialContainer {
16 | /**
17 | * Utility trait for wrapping sequential containers.
18 | */
19 | trait Wrapper extends SequentialContainer with Container.Wrapper {
20 | override val contents: Buffer[Component] = new Content
21 | //def contents_=(c: Component*) { contents.clear(); contents ++= c }
22 | }
23 | }
24 |
25 | /**
26 | * A container for which a sequential order of children makes sense, such as
27 | * flow panels, or menus. Its contents are mutable.
28 | */
29 | trait SequentialContainer extends Container {
30 | /**
31 | * The mutable child components of this container. The order matters and
32 | * usually indicates the layout of the children.
33 | */
34 | override def contents: Buffer[Component]
35 | //def contents_=(c: Component*)
36 | }
37 |
--------------------------------------------------------------------------------
/scala/swing/SimpleGUIApplication.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import javax.swing._
14 |
15 | /**
16 | * Extend this class for most simple UI applications. Clients need to implement the
17 | * top
method. Framework initialization is done by this class.
18 | *
19 | * In order to conform to Swing's threading policy, never implement top or any additional
20 | * member that created Swing components as a value unless component creation happens on
21 | * the EDT (see Swing.onEDT and Swing.onEDTWait). Lazy values are okay for the same reason
22 | * if they are initialized on the EDT always.
23 | */
24 | @deprecated("Use SimpleSwingApplication instead") abstract class SimpleGUIApplication extends GUIApplication {
25 |
26 | /**
27 | * A GUI application's version of the main method. Called by the default
28 | * main method implementation provided by this class.
29 | * Implement to return the top-level frame of this application.
30 | */
31 | def top: Frame
32 |
33 | /**
34 | * Calls top, packs the frame, and displays it.
35 | */
36 | def main(args: Array[String]) = run {
37 | val t = top
38 | t.pack()
39 | t.visible = true
40 | }
41 |
42 | def resourceFromClassloader(path: String): java.net.URL =
43 | this.getClass.getResource(path)
44 |
45 | def resourceFromUserDirectory(path: String): java.io.File =
46 | new java.io.File(util.Properties.userDir, path)
47 | }
48 |
--------------------------------------------------------------------------------
/scala/swing/SimpleSwingApplication.scala:
--------------------------------------------------------------------------------
1 | package scala.swing
2 |
3 | abstract class SimpleSwingApplication extends SwingApplication {
4 | def top: Frame
5 |
6 | override def startup(args: Array[String]) {
7 | val t = top
8 | if (t.size == new Dimension(0,0)) t.pack()
9 | t.visible = true
10 | }
11 |
12 | def resourceFromClassloader(path: String): java.net.URL =
13 | this.getClass.getResource(path)
14 |
15 | def resourceFromUserDirectory(path: String): java.io.File =
16 | new java.io.File(util.Properties.userDir, path)
17 | }
18 |
--------------------------------------------------------------------------------
/scala/swing/Slider.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import javax.swing.{JSlider, JLabel}
14 | import event._
15 |
16 | /**
17 | * Lets users select a value from a given range. Visually, this is represented
18 | * as a draggable knob on a horizontal or vertical bar.
19 | *
20 | * Fires a ValueChanged event whenever the slider's value changes and
21 | * when the knob is released.
22 | *
23 | * @see javax.swing.JSlider
24 | */
25 | class Slider extends Component with Orientable.Wrapper with Publisher {
26 | override lazy val peer: JSlider = new JSlider with SuperMixin
27 |
28 | def min: Int = peer.getMinimum
29 | def min_=(v: Int) { peer.setMinimum(v) }
30 | def max: Int = peer.getMaximum
31 | def max_=(v: Int) { peer.setMaximum(v) }
32 | def value: Int = peer.getValue
33 | def value_=(v: Int) { peer.setValue(v) }
34 | def extent: Int = peer.getExtent
35 | def extent_=(v: Int) { peer.setExtent(v) }
36 |
37 | def paintLabels: Boolean = peer.getPaintLabels
38 | def paintLabels_=(v: Boolean) { peer.setPaintLabels(v) }
39 | def paintTicks: Boolean = peer.getPaintTicks
40 | def paintTicks_=(v: Boolean) { peer.setPaintTicks(v) }
41 | def paintTrack: Boolean = peer.getPaintTrack
42 | def paintTrack_=(v: Boolean) { peer.setPaintTrack(v) }
43 |
44 | def snapToTicks: Boolean = peer.getSnapToTicks
45 | def snapToTicks_=(v: Boolean) { peer.setSnapToTicks(v) }
46 |
47 | def minorTickSpacing: Int = peer.getMinorTickSpacing
48 | def minorTickSpacing_=(v: Int) { peer.setMinorTickSpacing(v) }
49 | def majorTickSpacing: Int = peer.getMajorTickSpacing
50 | def majorTickSpacing_=(v: Int) { peer.setMajorTickSpacing(v) }
51 |
52 | def adjusting = peer.getValueIsAdjusting
53 |
54 | def labels: scala.collection.Map[Int, Label] = {
55 | val labelTable = peer.getLabelTable.asInstanceOf[java.util.Hashtable[Int, JLabel]]
56 | new scala.collection.JavaConversions.JMapWrapper(labelTable)
57 | .mapValues(v => UIElement.cachedWrapper[Label](v))
58 | }
59 | def labels_=(l: scala.collection.Map[Int, Label]) {
60 | // TODO: do some lazy wrapping
61 | val table = new java.util.Hashtable[Any, Any]
62 | for ((k,v) <- l) table.put(k, v.peer)
63 | peer.setLabelTable(table)
64 | }
65 |
66 | peer.addChangeListener(new javax.swing.event.ChangeListener {
67 | def stateChanged(e: javax.swing.event.ChangeEvent) {
68 | publish(new ValueChanged(Slider.this))
69 | }
70 | })
71 | }
72 |
--------------------------------------------------------------------------------
/scala/swing/SplitPane.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import event._
14 | import Swing._
15 |
16 | /**
17 | * A container with exactly two children. Arranges them side by side, either
18 | * horizontally or vertically. Displays a draggable divider component between
19 | * them that lets the user adjust the size ratio of the children.
20 | *
21 | * @see javax.swing.JSplitPane
22 | */
23 | class SplitPane(o: Orientation.Value, left: Component, right: Component) extends Component with Container with Orientable.Wrapper {
24 | override lazy val peer: javax.swing.JSplitPane =
25 | new javax.swing.JSplitPane(o.id, left.peer, right.peer) with SuperMixin
26 | def this(o: Orientation.Value) = this(o, new Component {}, new Component {})
27 | def this() = this(Orientation.Horizontal)
28 |
29 | def contents: Seq[Component] = List(leftComponent, rightComponent)
30 | def contents_=(left: Component, right: Component) {
31 | peer.setLeftComponent(left.peer)
32 | peer.setRightComponent(right.peer)
33 | }
34 |
35 | def topComponent: Component =
36 | UIElement.cachedWrapper[Component](peer.getTopComponent.asInstanceOf[javax.swing.JComponent])
37 | def topComponent_=(c: Component) { peer.setTopComponent(c.peer) }
38 | def bottomComponent: Component =
39 | UIElement.cachedWrapper[Component](peer.getBottomComponent.asInstanceOf[javax.swing.JComponent])
40 | def bottomComponent_=(c: Component) { peer.setBottomComponent(c.peer) }
41 |
42 | def leftComponent: Component = topComponent
43 | def leftComponent_=(c: Component) { topComponent = c }
44 | def rightComponent: Component = bottomComponent
45 | def rightComponent_=(c: Component) { bottomComponent = c }
46 |
47 | def dividerLocation: Int = peer.getDividerLocation
48 | def dividerLocation_=(n: Int) { peer.setDividerLocation(n) }
49 |
50 | /*def proportionalDividerLocation: Double =
51 | if (orientation == Orientation.Vertical) dividerLocation / (size.height - dividerSize)
52 | else dividerLocation / (size.width - dividerSize)*/
53 | def dividerLocation_=(f: Double) { peer.setDividerLocation(f) }
54 |
55 | def dividerSize: Int = peer.getDividerSize
56 | def dividerSize_=(n: Int) { peer.setDividerSize(n) }
57 | def resizeWeight: Double = peer.getResizeWeight
58 | def resizeWeight_=(n: Double) { peer.setResizeWeight(n) }
59 |
60 | def resetToPreferredSizes() { peer.resetToPreferredSizes() }
61 |
62 | def oneTouchExpandable: Boolean = peer.isOneTouchExpandable
63 | def oneTouchExpandable_=(b: Boolean) { peer.setOneTouchExpandable(b) }
64 | def continuousLayout: Boolean = peer.isContinuousLayout
65 | def continuousLayout_=(b: Boolean) { peer.setContinuousLayout(b) }
66 | }
67 |
--------------------------------------------------------------------------------
/scala/swing/Swing.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import java.awt.event._
14 | import javax.swing.event._
15 | import javax.swing.border._
16 | import javax.swing.{JComponent, Icon, BorderFactory, SwingUtilities}
17 |
18 | /**
19 | * Helpers for this package.
20 | */
21 | object Swing {
22 | protected[swing] def toNoIcon(i: Icon): Icon = if(i == null) EmptyIcon else i
23 | protected[swing] def toNullIcon(i: Icon): Icon = if(i == EmptyIcon) null else i
24 | protected[swing] def nullPeer(c: Component) = if (c != null) c.peer else null
25 |
26 | implicit def pair2Dimension(p: (Int, Int)): Dimension = new Dimension(p._1, p._2)
27 | implicit def pair2Point(p: (Int, Int)): Point = new Point(p._1, p._2)
28 | implicit def pair2Point(p: (Int, Int, Int, Int)): Rectangle = new Rectangle(p._1, p._2, p._3, p._4)
29 |
30 | @inline final def Runnable(@inline block: =>Unit) = new Runnable {
31 | def run = block
32 | }
33 | final def ChangeListener(f: ChangeEvent => Unit) = new ChangeListener {
34 | def stateChanged(e: ChangeEvent) { f(e) }
35 | }
36 | final def ActionListener(f: ActionEvent => Unit) = new ActionListener {
37 | def actionPerformed(e: ActionEvent) { f(e) }
38 | }
39 |
40 | def Box(min: Dimension, pref: Dimension, max: Dimension) = new Component {
41 | override lazy val peer = new javax.swing.Box.Filler(min, pref, max)
42 | }
43 | def HGlue = new Component {
44 | override lazy val peer = javax.swing.Box.createHorizontalGlue.asInstanceOf[JComponent]
45 | }
46 | def VGlue = new Component {
47 | override lazy val peer = javax.swing.Box.createVerticalGlue.asInstanceOf[JComponent]
48 | }
49 | def Glue = new Component {
50 | override lazy val peer = javax.swing.Box.createGlue.asInstanceOf[JComponent]
51 | }
52 | def RigidBox(dim: Dimension) = new Component {
53 | override lazy val peer = javax.swing.Box.createRigidArea(dim).asInstanceOf[JComponent]
54 | }
55 | def HStrut(width: Int) = new Component {
56 | override lazy val peer = javax.swing.Box.createHorizontalStrut(width).asInstanceOf[JComponent]
57 | }
58 | def VStrut(height: Int) = new Component {
59 | override lazy val peer = javax.swing.Box.createVerticalStrut(height).asInstanceOf[JComponent]
60 | }
61 |
62 | def Icon(image: java.awt.Image) = new javax.swing.ImageIcon(image)
63 | def Icon(filename: String) = new javax.swing.ImageIcon(filename)
64 | def Icon(url: java.net.URL) = new javax.swing.ImageIcon(url)
65 |
66 | /**
67 | * The empty icon. Use this icon instead of null
to indicate
68 | * that you don't want an icon.
69 | */
70 | case object EmptyIcon extends Icon {
71 | def getIconHeight: Int = 0
72 | def getIconWidth: Int = 0
73 | def paintIcon(c: java.awt.Component, g: java.awt.Graphics, x: Int, y: Int) {}
74 | }
75 |
76 | def unwrapIcon(icon: Icon): Icon = if (icon == null) EmptyIcon else icon
77 | def wrapIcon(icon: Icon): Icon = if (icon == EmptyIcon) null else icon
78 |
79 | def EmptyBorder = BorderFactory.createEmptyBorder()
80 | def EmptyBorder(weight: Int) =
81 | BorderFactory.createEmptyBorder(weight, weight, weight, weight)
82 | def EmptyBorder(top: Int, left: Int, bottom: Int, right: Int) =
83 | BorderFactory.createEmptyBorder(top, left, bottom, right)
84 |
85 | def LineBorder(c: Color) = BorderFactory.createLineBorder(c)
86 | def LineBorder(c: Color, weight: Int) = BorderFactory.createLineBorder(c, weight)
87 |
88 | def BeveledBorder(kind: Embossing) = BorderFactory.createBevelBorder(kind.bevelPeer)
89 | def BeveledBorder(kind: Embossing, highlight: Color, shadow: Color) =
90 | BorderFactory.createBevelBorder(kind.bevelPeer, highlight, shadow)
91 | def BeveledBorder(kind: Embossing,
92 | highlightOuter: Color, highlightInner: Color,
93 | shadowOuter: Color, shadowInner: Color) =
94 | BorderFactory.createBevelBorder(kind.bevelPeer,
95 | highlightOuter, highlightInner,
96 | shadowOuter, shadowInner)
97 |
98 | sealed abstract class Embossing {
99 | def bevelPeer: Int
100 | def etchPeer: Int
101 | }
102 | case object Lowered extends Embossing {
103 | def bevelPeer = BevelBorder.LOWERED
104 | def etchPeer = javax.swing.border.EtchedBorder.LOWERED
105 | }
106 | case object Raised extends Embossing {
107 | def bevelPeer = BevelBorder.RAISED
108 | def etchPeer = javax.swing.border.EtchedBorder.RAISED
109 | }
110 |
111 | def EtchedBorder = BorderFactory.createEtchedBorder()
112 | def EtchedBorder(kind: Embossing) =
113 | BorderFactory.createEtchedBorder(kind.etchPeer)
114 | def EtchedBorder(kind: Embossing, highlight: Color, shadow: Color) =
115 | BorderFactory.createEtchedBorder(kind.etchPeer, highlight, shadow)
116 |
117 | def MatteBorder(top: Int, left: Int, bottom: Int, right: Int, color: Color) =
118 | BorderFactory.createMatteBorder(top, left, bottom, right, color)
119 | def MatteBorder(top: Int, left: Int, bottom: Int, right: Int, icon: Icon) =
120 | BorderFactory.createMatteBorder(top, left, bottom, right, icon)
121 |
122 | def CompoundBorder(outside: Border, inside: Border) =
123 | BorderFactory.createCompoundBorder(outside, inside)
124 |
125 | def TitledBorder(border: Border, title: String) =
126 | BorderFactory.createTitledBorder(border, title)
127 |
128 | /**
129 | * Schedule the given code to be executed on the Swing event dispatching
130 | * thread (EDT). Returns immediately.
131 | */
132 | @inline final def onEDT(op: =>Unit) = SwingUtilities invokeLater Runnable(op)
133 |
134 | /**
135 | * Schedule the given code to be executed on the Swing event dispatching
136 | * thread (EDT). Blocks until after the code has been run.
137 | */
138 | @inline final def onEDTWait(op: =>Unit) = SwingUtilities invokeAndWait Runnable(op)
139 | }
140 |
--------------------------------------------------------------------------------
/scala/swing/SwingActor.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import scala.actors._
14 |
15 | // Dummy to keep ant from recompiling on every run.
16 | trait SwingActor { }
17 |
18 | /*object SwingActor {
19 | /**
20 | * Similar to Actor.actor, but creates an instance of a SwingActor.
21 | */
22 | def apply(body: => Unit): Actor =
23 | new SwingActor { def act() = body }.start()
24 | }
25 |
26 | /**
27 | * An actor that runs on the Swing event dispatching thread (EDT).
28 | */
29 | abstract class SwingActor extends Actor {
30 | override val scheduler = new SchedulerAdapter {
31 | def execute(op: =>Unit) = Swing onEDT op
32 | def onTerminate(a: Actor)(op: => Unit) {}
33 | def terminated(a: Actor) {}
34 | }
35 | }*/
36 |
--------------------------------------------------------------------------------
/scala/swing/SwingApplication.scala:
--------------------------------------------------------------------------------
1 | package scala.swing
2 |
3 | abstract class SwingApplication extends Reactor {
4 | def main(args: Array[String]) = Swing.onEDT { startup(args) }
5 |
6 | def startup(args: Array[String])
7 | def quit() { shutdown(); System.exit(0) }
8 | def shutdown() {}
9 | }
10 |
--------------------------------------------------------------------------------
/scala/swing/SwingWorker.scala:
--------------------------------------------------------------------------------
1 | package scala.swing
2 |
3 | import scala.actors._
4 |
5 | object SwingWorker {
6 |
7 | }
8 |
9 | abstract class SwingWorker extends Actor {
10 | def queue() {
11 |
12 | }
13 |
14 | def done() {
15 |
16 | }
17 |
18 | private var _cancelled = false
19 | def cancelled: Boolean = _cancelled
20 | def cancelled_=(b: Boolean) { _cancelled = b }
21 | }
--------------------------------------------------------------------------------
/scala/swing/TabbedPane.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import event._
14 | import scala.collection.mutable.Buffer
15 | import javax.swing.{JTabbedPane, JComponent}
16 |
17 |
18 | object TabbedPane {
19 | object Layout extends Enumeration {
20 | val Wrap = Value(JTabbedPane.WRAP_TAB_LAYOUT)
21 | val Scroll = Value(JTabbedPane.SCROLL_TAB_LAYOUT)
22 | }
23 |
24 | class Page protected[TabbedPane](parent0: TabbedPane, title0: String, content0: Component, tip0: String) extends Proxy {
25 | def self = content0
26 |
27 | def this(title0: String, content0: Component, tip0: String) =
28 | this(null, title0, content0, tip0)
29 | def this(title0: String, content0: Component) =
30 | this(title0, content0, "")
31 | content = content0 // first add component, *then* set other things
32 | title = title0
33 | tip = tip0
34 |
35 | protected[TabbedPane] var parent: TabbedPane = parent0
36 |
37 | protected var _title = title0
38 | def title: String = _title
39 | def title_=(t: String) {
40 | // beware to keep this order since, index depends on the _old_ title
41 | if (parent != null) parent.peer.setTitleAt(index, t)
42 | _title = t
43 | }
44 | protected var _content = content0
45 | def content: Component = _content//UIElement.cachedWrapper(peer.getComponentAt(index).asInstanceOf[JComponent])
46 | def content_=(c: Component) { _content = c; if (parent != null) parent.peer.setComponentAt(index, c.peer) }
47 | protected var _tip = tip0
48 | def tip: String = _tip//peer.getToolTipTextAt(index)
49 | def tip_=(t: String) { _tip = t; if (parent != null) parent.peer.setToolTipTextAt(index, t) }
50 | protected var _enabled = true
51 | def enabled: Boolean = _enabled//peer.isEnabledAt(index)
52 | def enabled_=(b: Boolean) { _enabled = b; if (parent != null) parent.peer.setEnabledAt(index, b) }
53 | protected var _mnemonic = -1
54 | def mnemonic: Int = _mnemonic//peer.getMnemonicAt(index)
55 | def mnemonic_=(k: Int) { _mnemonic = k; if (parent != null) parent.peer.setMnemonicAt(index, k)}
56 | protected var _foreground: Color = null
57 | def foreground: Color = _foreground//peer.getForegroundAt(index)
58 | def foreground_=(c: Color) { _foreground = c; if (parent != null) parent.peer.setForegroundAt(index, c)}
59 | protected var _background: Color = null
60 | def background: Color = _background //peer.getBackgroundAt(index)
61 | def background_=(c: Color) { _background = c; if (parent != null) parent.peer.setBackgroundAt(index, c)}
62 | def bounds: Rectangle = parent.peer.getBoundsAt(index)
63 |
64 | // TODO: icon, disabledIcon
65 |
66 | def index = if(parent != null) parent.peer.indexOfTab(title) else 0//_index
67 | //protected[TabbedPane] var _index: Int = index0
68 | }
69 | }
70 |
71 | /**
72 | * Displays the contents of one of several pages at a time. For each page a tab is
73 | * visible at all times. The user can click on one of these tabs to move the
74 | * corresponding page to the front.
75 | *
76 | * @see javax.swing.JTabbedPane
77 | */
78 | class TabbedPane extends Component with Publisher {
79 | override lazy val peer: JTabbedPane = new JTabbedPane with SuperMixin
80 | import TabbedPane._
81 |
82 | object pages extends BufferWrapper[Page] {
83 | def runCount: Int = peer.getTabRunCount
84 |
85 | def remove(n: Int): Page = {
86 | val t = apply(n)
87 | peer.removeTabAt(n)
88 | t.parent = null
89 | //for(i <- n to length) apply(i)._index -= 1
90 | t
91 | }
92 | protected def insertAt(n: Int, t: Page) {
93 | //for(i <- n to length) apply(i)._index += 1
94 | t.parent = TabbedPane.this
95 | peer.insertTab(t.title, null, t.content.peer, t.tip, n)
96 | }
97 |
98 | def +=(t: Page): this.type = { t.parent = TabbedPane.this; peer.addTab(t.title, null, t.content.peer, t.tip); this }
99 | def length = peer.getTabCount
100 | def apply(n: Int) = new Page(TabbedPane.this, peer.getTitleAt(n),
101 | UIElement.cachedWrapper[Component](peer.getComponentAt(n).asInstanceOf[javax.swing.JComponent]),
102 | peer.getToolTipTextAt(n))
103 | }
104 |
105 | def tabLayoutPolicy: Layout.Value = Layout(peer.getTabLayoutPolicy)
106 | def tabLayoutPolicy_=(p: Layout.Value) { peer.setTabLayoutPolicy(p.id) }
107 |
108 |
109 | def tabPlacement: Alignment.Value = Alignment(peer.getTabPlacement)
110 | /**
111 | * Possible values are Left, Right, Top, Bottom.
112 | */
113 | def tabPlacement(b: Alignment.Value) { peer.setTabPlacement(b.id) }
114 |
115 | /**
116 | * The current page selection
117 | */
118 | object selection extends Publisher {
119 | def page: Page = pages(index)
120 | def page_=(p: Page) { index = p.index }
121 |
122 | def index: Int = peer.getSelectedIndex
123 | def index_=(n: Int) { peer.setSelectedIndex(n) }
124 |
125 | peer.addChangeListener(new javax.swing.event.ChangeListener {
126 | def stateChanged(e: javax.swing.event.ChangeEvent) {
127 | publish(SelectionChanged(TabbedPane.this))
128 | }
129 | })
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/scala/swing/TextArea.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import event._
14 | import javax.swing._
15 | import java.awt.event._
16 |
17 | /**
18 | * A text component that allows multiline text input and display.
19 | *
20 | * @see javax.swing.JTextArea
21 | */
22 | class TextArea(text0: String, rows0: Int, columns0: Int) extends TextComponent
23 | with TextComponent.HasColumns with TextComponent.HasRows {
24 | override lazy val peer: JTextArea = new JTextArea(text0, rows0, columns0) with SuperMixin
25 | def this(text: String) = this(text, 0, 0)
26 | def this(rows: Int, columns: Int) = this("", rows, columns)
27 | def this() = this("", 0, 0)
28 |
29 | // TODO: we could make contents StringBuilder-like
30 | def append(t: String) { peer.append(t) }
31 |
32 | def rows: Int = peer.getRows
33 | def rows_=(n: Int) = peer.setRows(n)
34 | def columns: Int = peer.getColumns
35 | def columns_=(n: Int) = peer.setColumns(n)
36 |
37 | def tabSize: Int = peer.getTabSize
38 | def tabSize_=(n: Int) = peer.setTabSize(n)
39 | def lineCount: Int = peer.getLineCount
40 |
41 | def lineWrap: Boolean = peer.getLineWrap
42 | def lineWrap_=(w: Boolean) = peer.setLineWrap(w)
43 | def wordWrap: Boolean = peer.getWrapStyleWord
44 | def wordWrap_=(w: Boolean) = peer.setWrapStyleWord(w)
45 | def charWrap: Boolean = !peer.getWrapStyleWord
46 | def charWrap_=(w: Boolean) = peer.setWrapStyleWord(!w)
47 | }
48 |
--------------------------------------------------------------------------------
/scala/swing/TextComponent.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import event._
14 | import javax.swing._
15 | import javax.swing.text._
16 | import javax.swing.event._
17 |
18 | object TextComponent {
19 | trait HasColumns extends TextComponent {
20 | def columns: Int
21 | def columns_=(n: Int)
22 | }
23 | trait HasRows extends TextComponent {
24 | def rows: Int
25 | def rows_=(n: Int)
26 | }
27 | }
28 |
29 | /**
30 | * A component that allows some kind of text input and display.
31 | *
32 | * @see javax.swing.JTextComponent
33 | */
34 | class TextComponent extends Component with Publisher {
35 | override lazy val peer: JTextComponent = new JTextComponent with SuperMixin {}
36 | def text: String = peer.getText
37 | def text_=(t: String) = peer.setText(t)
38 |
39 | class Caret extends Publisher {
40 | def dot: Int = peer.getCaret.getDot
41 | def dot_=(n: Int) { peer.getCaret.setDot(n) }
42 | def mark: Int = peer.getCaret.getMark
43 | def moveDot(n: Int) { peer.getCaret.moveDot(n) }
44 | def visible: Boolean = peer.getCaret.isVisible
45 | def visible_=(b: Boolean) { peer.getCaret.setVisible(b) }
46 | def selectionVisible: Boolean = peer.getCaret.isSelectionVisible
47 | def selectionVisible_=(b: Boolean) { peer.getCaret.setSelectionVisible(b) }
48 | def blinkRate: Int = peer.getCaret.getBlinkRate
49 | def blinkRate_=(n: Int) { peer.getCaret.setBlinkRate(n) }
50 | def color: Color = peer.getCaretColor
51 | def color_=(c: Color) = peer.setCaretColor(c)
52 | def position: Int = peer.getCaretPosition
53 | def position_=(p: Int) = peer.setCaretPosition(p)
54 |
55 | peer.addCaretListener {
56 | new CaretListener {
57 | def caretUpdate(e: CaretEvent) { publish(CaretUpdate(TextComponent.this)) }
58 | }
59 | }
60 | }
61 |
62 | object caret extends Caret
63 |
64 | def editable: Boolean = peer.isEditable
65 | def editable_=(x: Boolean) = peer.setEditable(x)
66 | def cut() { peer.cut() }
67 | def copy() { peer.copy() }
68 | def paste() { peer.paste() }
69 | def selected: String = peer.getSelectedText
70 |
71 | def selectAll() { peer.selectAll() }
72 |
73 | peer.getDocument.addDocumentListener(new DocumentListener {
74 | def changedUpdate(e:DocumentEvent) { publish(new ValueChanged(TextComponent.this)) }
75 | def insertUpdate(e:DocumentEvent) { publish(new ValueChanged(TextComponent.this)) }
76 | def removeUpdate(e:DocumentEvent) { publish(new ValueChanged(TextComponent.this)) }
77 | })
78 | }
79 |
--------------------------------------------------------------------------------
/scala/swing/TextField.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import event._
14 | import javax.swing._
15 | import java.awt.event._
16 |
17 |
18 | /*object TextField {
19 | object FocusLostBehavior extends Enumeration {
20 | val Revert = Value(JFormattedTextField.REVERT)
21 | val Commit = Value(JFormattedTextField.REVERT)
22 | val CommitOrRevert = Value(JFormattedTextField.REVERT)
23 | val Persist = Value(JFormattedTextField.REVERT)
24 | }
25 | }*/
26 |
27 | /**
28 | * A text component that allows single line text input and display.
29 | *
30 | * @see javax.swing.JTextField
31 | */
32 | class TextField(text0: String, columns0: Int) extends TextComponent with TextComponent.HasColumns with Action.Trigger.Wrapper {
33 | override lazy val peer: JTextField = new JTextField(text0, columns0) with SuperMixin
34 | def this(text: String) = this(text, 0)
35 | def this(columns: Int) = this("", columns)
36 | def this() = this("")
37 |
38 | def columns: Int = peer.getColumns
39 | def columns_=(n: Int) = peer.setColumns(n)
40 |
41 | /** @see javax.swing.JTextField#getHorizontalAlignment() */
42 | def horizontalAlignment: Alignment.Value = Alignment(peer.getHorizontalAlignment)
43 | /** @see javax.swing.JTextField#setHorizontalAlignment() */
44 | def horizontalAlignment_=(x: Alignment.Value) { peer.setHorizontalAlignment(x.id) }
45 |
46 | private lazy val actionListener = Swing.ActionListener { e =>
47 | publish(EditDone(TextField.this))
48 | }
49 |
50 | protected override def onFirstSubscribe {
51 | super.onFirstSubscribe
52 | peer.addActionListener(actionListener)
53 | peer.addFocusListener(new FocusAdapter {
54 | override def focusLost(e: java.awt.event.FocusEvent) { publish(EditDone(TextField.this)) }
55 | })
56 | }
57 |
58 | protected override def onLastUnsubscribe {
59 | super.onLastUnsubscribe
60 | peer.removeActionListener(actionListener)
61 | }
62 |
63 | def verifier: String => Boolean = s => peer.getInputVerifier.verify(peer)
64 | def verifier_=(v: String => Boolean) {
65 | peer.setInputVerifier(new InputVerifier {
66 | private val old = peer.getInputVerifier
67 | def verify(c: JComponent) = v(text)
68 | override def shouldYieldFocus(c: JComponent) = old.shouldYieldFocus(c)
69 | })
70 | }
71 | def shouldYieldFocus: String=>Boolean = s => peer.getInputVerifier.shouldYieldFocus(peer)
72 | def shouldYieldFocus_=(y: String=>Boolean) {
73 | peer.setInputVerifier(new InputVerifier {
74 | private val old = peer.getInputVerifier
75 | def verify(c: JComponent) = old.verify(c)
76 | override def shouldYieldFocus(c: JComponent) = y(text)
77 | })
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/scala/swing/ToggleButton.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import event._
14 | import javax.swing._
15 |
16 | /**
17 | * A two state button with a push button like user interface.
18 | * Usually used in tool bars.
19 | *
20 | * @see javax.swing.JToggleButton
21 | */
22 | class ToggleButton(text0: String) extends AbstractButton {
23 | override lazy val peer: JToggleButton = new JToggleButton(text0) with SuperMixin
24 | def this() = this("")
25 | }
26 |
--------------------------------------------------------------------------------
/scala/swing/UIElement.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import java.awt.Cursor
14 | import event._
15 | import scala.collection.mutable.HashMap
16 | import scala.ref._
17 | import java.util.WeakHashMap
18 |
19 | object UIElement {
20 | private val ClientKey = "scala.swingWrapper"
21 | private[this] val wrapperCache = new WeakHashMap[java.awt.Component, WeakReference[UIElement]]
22 |
23 | private def cache(e: UIElement) = e.peer match {
24 | case p: javax.swing.JComponent => p.putClientProperty(ClientKey, e)
25 | case _ => wrapperCache.put(e.peer, new WeakReference(e))
26 | }
27 |
28 | /**
29 | * Looks up the internal component cache for a wrapper of the given
30 | * Java Swing peer. If this method finds one of the given type `C`,
31 | * it will return that wrapper. Otherwise it returns `null`. This
32 | * method never throws an exception.
33 | *
34 | * Clients should be extremely careful with type parameter `C` and
35 | * its interaction with type inference. Better err on the side of caution
36 | * and explicitly specify `C`.
37 | */
38 | private[swing] def cachedWrapper[C>:Null<:UIElement](c: java.awt.Component): C = {
39 | val w = c match {
40 | case c: javax.swing.JComponent => c.getClientProperty(ClientKey)
41 | case _ => wrapperCache.get(c)
42 | }
43 | try { w.asInstanceOf[C] } catch { case _ => null }
44 | }
45 |
46 | /**
47 | * Returns a wrapper for a given Java Swing peer. If there is a
48 | * compatible wrapper in use, this method will return it.
49 | *
50 | * `wrap` methods in companion objects of subclasses of UIElement have the
51 | * same behavior, except that they return more specific wrappers.
52 | */
53 | def wrap(c: java.awt.Component): UIElement = {
54 | val w = cachedWrapper[UIElement](c)
55 | if (w != null) w
56 | else new UIElement { def peer = c }
57 | }
58 | }
59 |
60 | /**
61 | * The base trait of all user interface elements. Subclasses belong to one
62 | * of two groups: top-level elements such as windows and dialogs, or
63 | * Component
s.
64 | *
65 | * @note [Java Swing] This trait does not have an exact counterpart in
66 | * Java Swing. The peer is of type java.awt.Component since this is the
67 | * least common upper bound of possible underlying peers.
68 | *
69 | * @note [Implementation] A UIElement automatically adds itself to the
70 | * component cache on creation.
71 | *
72 | * @see java.awt.Component
73 | */
74 | trait UIElement extends Proxy with LazyPublisher {
75 | /**
76 | * The underlying Swing peer.
77 | */
78 | def peer: java.awt.Component
79 | def self = peer
80 |
81 | UIElement.cache(this)
82 |
83 | def foreground: Color = peer.getForeground
84 | def foreground_=(c: Color) = peer.setForeground(c)
85 | def background: Color = peer.getBackground
86 | def background_=(c: Color) = peer.setBackground(c)
87 |
88 | def minimumSize = peer.getMinimumSize
89 | def minimumSize_=(x: Dimension) = peer.setMinimumSize(x)
90 | def maximumSize = peer.getMaximumSize
91 | def maximumSize_=(x: Dimension) = peer.setMaximumSize(x)
92 | def preferredSize = peer.getPreferredSize
93 | def preferredSize_=(x: Dimension) = peer.setPreferredSize(x)
94 |
95 | def font: Font = peer.getFont
96 | def font_=(f: Font) = peer.setFont(f)
97 |
98 | def locationOnScreen = peer.getLocationOnScreen
99 | def location = peer.getLocation
100 | def bounds = peer.getBounds
101 | def size = peer.getSize
102 | @deprecated("Explicit size assignement for UIElements is not supported anymore. " +
103 | "Use a layout manager or subclass Window.")
104 | def size_=(dim: Dimension) = peer.setSize(dim)
105 |
106 | def locale = peer.getLocale
107 | def toolkit = peer.getToolkit
108 |
109 | def cursor: Cursor = peer.getCursor
110 | def cursor_=(c: Cursor) { peer.setCursor(c) }
111 |
112 | def visible: Boolean = peer.isVisible
113 | def visible_=(b: Boolean) { peer.setVisible(b) }
114 | def showing: Boolean = peer.isShowing
115 | def displayable: Boolean = peer.isDisplayable
116 |
117 | def repaint() { peer.repaint }
118 | def repaint(rect: Rectangle) { peer.repaint(rect.x, rect.y, rect.width, rect.height) }
119 | def ignoreRepaint: Boolean = peer.getIgnoreRepaint
120 | def ignoreRepaint_=(b: Boolean) { peer.setIgnoreRepaint(b) }
121 |
122 | protected def onFirstSubscribe {
123 | peer.addComponentListener(new java.awt.event.ComponentListener {
124 | def componentHidden(e: java.awt.event.ComponentEvent) {
125 | publish(UIElementHidden(UIElement.this))
126 | }
127 | def componentShown(e: java.awt.event.ComponentEvent) {
128 | publish(UIElementShown(UIElement.this))
129 | }
130 | def componentMoved(e: java.awt.event.ComponentEvent) {
131 | publish(UIElementMoved(UIElement.this))
132 | }
133 | def componentResized(e: java.awt.event.ComponentEvent) {
134 | publish(UIElementResized(UIElement.this))
135 | }
136 | })
137 | }
138 | protected def onLastUnsubscribe {}
139 | }
140 |
--------------------------------------------------------------------------------
/scala/swing/Window.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 |
13 | import java.awt.{Window => AWTWindow}
14 | import event._
15 | import javax.swing._
16 |
17 | /**
18 | * A window with decoration such as a title, border, and action buttons.
19 | *
20 | * An AWT window cannot be wrapped dynamically with this class, i.e., you cannot
21 | * write something like new Window { def peer = myAWTWindow }
22 | *
23 | * @see javax.swing.JFrame
24 | */
25 | abstract class Window extends UIElement with RootPanel with Publisher { outer =>
26 | def peer: AWTWindow with InterfaceMixin
27 |
28 | protected trait InterfaceMixin extends javax.swing.RootPaneContainer
29 |
30 | /**
31 | * This method is called when the window is closing, after all other window
32 | * event listeners have been processed.
33 | */
34 | def closeOperation() {}
35 |
36 | override def contents_=(c: Component) {
37 | super.contents_=(c)
38 | peer.pack() // pack also validates, which is generally required after an add
39 | }
40 | def defaultButton: Option[Button] =
41 | toOption(peer.getRootPane.getDefaultButton) map UIElement.cachedWrapper[Button]
42 | def defaultButton_=(b: Button) {
43 | peer.getRootPane.setDefaultButton(b.peer)
44 | }
45 | def defaultButton_=(b: Option[Button]) {
46 | peer.getRootPane.setDefaultButton(b map (_.peer) orNull)
47 | }
48 |
49 | def dispose() { peer.dispose() }
50 |
51 | def pack(): this.type = { peer.pack(); this }
52 |
53 | def setLocationRelativeTo(c: UIElement) { peer.setLocationRelativeTo(c.peer) }
54 | def centerOnScreen() { peer.setLocationRelativeTo(null) }
55 | def location_=(p: Point) { peer.setLocation(p) }
56 | override def size_=(size: Dimension) { peer.setSize(size) }
57 | def bounds_=(rect: Rectangle) { peer.setBounds(rect) }
58 |
59 | def owner: Window = UIElement.cachedWrapper[Window](peer.getOwner)
60 |
61 | def open() { peer setVisible true }
62 | def close() { peer setVisible false }
63 |
64 | peer.addWindowListener(new java.awt.event.WindowListener {
65 | def windowActivated(e: java.awt.event.WindowEvent) { publish(WindowActivated(outer)) }
66 | def windowClosed(e: java.awt.event.WindowEvent) { publish(WindowClosed(outer)) }
67 | def windowClosing(e: java.awt.event.WindowEvent) { publish(WindowClosing(outer)) }
68 | def windowDeactivated(e: java.awt.event.WindowEvent) { publish(WindowDeactivated(outer)) }
69 | def windowDeiconified(e: java.awt.event.WindowEvent) { publish(WindowDeiconified(outer)) }
70 | def windowIconified(e: java.awt.event.WindowEvent) { publish(WindowIconified(outer)) }
71 | def windowOpened(e: java.awt.event.WindowEvent) { publish(WindowOpened(outer)) }
72 | })
73 | }
74 |
--------------------------------------------------------------------------------
/scala/swing/event/ActionEvent.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 | package event
13 |
14 | object ActionEvent {
15 | def unapply(a: ActionEvent): Option[Component] = Some(a.source)
16 | }
17 |
18 | class ActionEvent(override val source: Component) extends ComponentEvent
19 |
--------------------------------------------------------------------------------
/scala/swing/event/AdjustingEvent.scala:
--------------------------------------------------------------------------------
1 | /* __ *\
2 | ** ________ ___ / / ___ Scala API **
3 | ** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL **
4 | ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5 | ** /____/\___/_/ |_/____/_/ | | **
6 | ** |/ **
7 | \* */
8 |
9 |
10 |
11 | package scala.swing
12 | package event
13 |
14 | /**
15 | * An event that indicates some editing operation that can be still in
16 | * progress.
17 | * Example: dragging a slider creates a number of AdjustmentEvents
18 | * with adjusting == true
until the user finally releases the
19 | * mouse button.
20 | *