summaryrefslogtreecommitdiff
path: root/src/swing
diff options
context:
space:
mode:
authorNAME <USER@epfl.ch>2008-04-18 14:25:30 +0000
committerNAME <USER@epfl.ch>2008-04-18 14:25:30 +0000
commit7d3d4982251ec8b713bceaaba8c0afe5c504e3a1 (patch)
tree24ad8d35a05340d4843ab1dae08b48642a355b9a /src/swing
parent8ebd73e6d786f11a195fc53d18f9f230eb89a2c7 (diff)
downloadscala-7d3d4982251ec8b713bceaaba8c0afe5c504e3a1.tar.gz
scala-7d3d4982251ec8b713bceaaba8c0afe5c504e3a1.tar.bz2
scala-7d3d4982251ec8b713bceaaba8c0afe5c504e3a1.zip
scala.swing update
Diffstat (limited to 'src/swing')
-rw-r--r--src/swing/scala/swing/Action.scala110
-rw-r--r--src/swing/scala/swing/BoxPanel.scala3
-rw-r--r--src/swing/scala/swing/BufferAdapter.scala30
-rw-r--r--src/swing/scala/swing/ButtonMutex.scala27
-rw-r--r--src/swing/scala/swing/CheckBox.scala8
-rw-r--r--src/swing/scala/swing/Component.scala17
-rw-r--r--src/swing/scala/swing/ComponentList.scala10
-rw-r--r--src/swing/scala/swing/Container.scala28
-rw-r--r--src/swing/scala/swing/FlowPanel.scala24
-rw-r--r--src/swing/scala/swing/Frame.scala30
-rw-r--r--src/swing/scala/swing/GridBagPanel.scala80
-rw-r--r--src/swing/scala/swing/GridPanel.scala18
-rw-r--r--src/swing/scala/swing/IndexedContainer.scala8
-rw-r--r--src/swing/scala/swing/IndexedPanel.scala8
-rw-r--r--src/swing/scala/swing/LayoutContainer.scala20
-rw-r--r--src/swing/scala/swing/Menu.scala40
-rw-r--r--src/swing/scala/swing/Orientation.scala22
-rw-r--r--src/swing/scala/swing/Oriented.scala13
-rw-r--r--src/swing/scala/swing/Panel.scala2
-rw-r--r--src/swing/scala/swing/ProgressBar.scala5
-rw-r--r--src/swing/scala/swing/PushButton.scala15
-rw-r--r--src/swing/scala/swing/RadioButton.scala8
-rw-r--r--src/swing/scala/swing/Reactions.scala3
-rw-r--r--src/swing/scala/swing/ScrollPane.scala2
-rw-r--r--src/swing/scala/swing/Scrollable.scala17
-rw-r--r--src/swing/scala/swing/Selectable.scala11
-rw-r--r--src/swing/scala/swing/Separator.scala10
-rw-r--r--src/swing/scala/swing/SimpleGUIApplication.scala2
-rw-r--r--src/swing/scala/swing/Slider.scala5
-rw-r--r--src/swing/scala/swing/Swing.scala5
-rw-r--r--src/swing/scala/swing/TabbedPane.scala76
-rw-r--r--src/swing/scala/swing/Table.scala102
-rw-r--r--src/swing/scala/swing/TextArea.scala31
-rw-r--r--src/swing/scala/swing/TextComponent.scala23
-rw-r--r--src/swing/scala/swing/TextField.scala6
-rw-r--r--src/swing/scala/swing/ToggleButton.scala9
-rw-r--r--src/swing/scala/swing/event/ButtonClicked.scala4
-rw-r--r--src/swing/scala/swing/event/ButtonPressed.scala3
-rw-r--r--src/swing/scala/swing/event/LiveEvent.scala5
-rw-r--r--src/swing/scala/swing/event/MouseEvent.scala2
-rw-r--r--src/swing/scala/swing/event/SelectionEvent.scala5
-rw-r--r--src/swing/scala/swing/event/TableChanged.scala5
-rw-r--r--src/swing/scala/swing/event/TableEvent.scala10
-rw-r--r--src/swing/scala/swing/event/TableResized.scala3
-rw-r--r--src/swing/scala/swing/geometry/Dimension.scala (renamed from src/swing/scala/swing/Dimension.scala)2
-rw-r--r--src/swing/scala/swing/geometry/Point.scala (renamed from src/swing/scala/swing/Point.scala)2
-rw-r--r--src/swing/scala/swing/geometry/Rectangle.scala19
-rw-r--r--src/swing/scala/swing/model/Matrix.scala2
-rw-r--r--src/swing/scala/swing/test/CelsiusConverter.scala9
-rw-r--r--src/swing/scala/swing/test/CelsiusConverter2.scala12
-rw-r--r--src/swing/scala/swing/test/GridBagDemo.scala62
-rw-r--r--src/swing/scala/swing/test/MenuDemo.scala32
-rw-r--r--src/swing/scala/swing/test/SimpleApplet.scala6
-rw-r--r--src/swing/scala/swing/test/SwingApp.scala7
-rw-r--r--src/swing/scala/swing/test/TableSelection.scala99
55 files changed, 994 insertions, 123 deletions
diff --git a/src/swing/scala/swing/Action.scala b/src/swing/scala/swing/Action.scala
new file mode 100644
index 0000000000..627d9468b9
--- /dev/null
+++ b/src/swing/scala/swing/Action.scala
@@ -0,0 +1,110 @@
+package scala.swing
+
+import javax.swing.{KeyStroke, Icon}
+
+object Action {
+ case object NoAction extends Action("") { def apply() {} }
+
+ /**
+ * Anything that triggers an action.
+ */
+ trait Trigger {
+ def action: Action
+ def action_=(a: Action)
+
+ def hideActionText: Boolean
+ def hideActionText_=(b: Boolean)
+ }
+}
+
+/**
+ * Not every action component will honor every property of its action.
+ * An action itself can generally be configured so that certain properties
+ * should be ignored and instead taken from the component directly. In the
+ * end, it is up to a component, which property it uses in which way.
+ *
+ * @see javax.swing.Action
+ */
+abstract class Action(title0: String) {
+ import Swing._
+
+ lazy val peer: javax.swing.Action = new javax.swing.AbstractAction(title0) {
+ def actionPerformed(a: java.awt.event.ActionEvent) = apply()
+ }
+
+ /**
+ * Title is not optional.
+ */
+ def title: String = ifNull(peer.getValue(javax.swing.Action.NAME),"")
+ def title_=(t: String) { peer.putValue(javax.swing.Action.NAME, t) }
+
+ /**
+ * None if large icon and small icon are not equal.
+ */
+ def icon: Option[Icon] = if(largeIcon == smallIcon) largeIcon else None
+ def icon_=(i: Option[Icon]) { largeIcon = i; smallIcon = i }
+ def largeIcon: Option[Icon] = toOption(peer.getValue(javax.swing.Action.LARGE_ICON_KEY))
+ def largeIcon_=(i: Option[Icon]) { peer.putValue(javax.swing.Action.LARGE_ICON_KEY, toNull(i)) }
+ def smallIcon: Option[Icon] = toOption(peer.getValue(javax.swing.Action.SMALL_ICON))
+ def smallIcon_=(i: Option[Icon]) { peer.putValue(javax.swing.Action.SMALL_ICON, toNull(i)) }
+
+ /**
+ * For all components.
+ */
+ def toolTip: String =
+ ifNull(peer.getValue(javax.swing.Action.SHORT_DESCRIPTION), "")
+ def toolTip_=(t: String) {
+ peer.putValue(javax.swing.Action.SHORT_DESCRIPTION, t)
+ }
+ /**
+ * Can be used for status bars, for example.
+ */
+ def longDescription: String =
+ ifNull(peer.getValue(javax.swing.Action.LONG_DESCRIPTION), "")
+ def longDescription_=(t: String) {
+ peer.putValue(javax.swing.Action.LONG_DESCRIPTION, t)
+ }
+
+ /**
+ * Default: java.awt.event.KeyEvent.VK_UNDEFINED, i.e., no mnemonic key.
+ * For all buttons and thus menu items.
+ */
+ def mnemonic: Int = ifNull(peer.getValue(javax.swing.Action.MNEMONIC_KEY),
+ java.awt.event.KeyEvent.VK_UNDEFINED)
+ def mnemonic_=(m: Int) { peer.putValue(javax.swing.Action.MNEMONIC_KEY, m) }
+
+ /**
+ * Indicates which character of the title should be underlined to indicate the mnemonic key.
+ * Ignored if out of bounds of the title string. Default: -1, i.e., ignored.
+ * For all buttons and thus menu items.
+ */
+ def mnemonicIndex: Int =
+ ifNull(peer.getValue(javax.swing.Action.DISPLAYED_MNEMONIC_INDEX_KEY), -1)
+ def mnemonicIndex_=(n: Int) { peer.putValue(javax.swing.Action.DISPLAYED_MNEMONIC_INDEX_KEY, n) }
+
+ /**
+ * For menus.
+ */
+ def accelerator: Option[KeyStroke] =
+ toOption(peer.getValue(javax.swing.Action.ACCELERATOR_KEY))
+ def accelerator_=(k: Option[KeyStroke]) {
+ peer.putValue(javax.swing.Action.ACCELERATOR_KEY, toNull(k))
+ }
+
+ /**
+ * For all components.
+ */
+ def enabled: Boolean = peer.isEnabled
+ def enabled_=(b: Boolean) { peer.setEnabled(b) }
+
+ /**
+ * Only honored if not <code>None</code>. For various buttons.
+ */
+ def selected: Option[Boolean] = toOption(peer.getValue(javax.swing.Action.SELECTED_KEY))
+ def selected_=(b: Option[Boolean]) {
+ peer.putValue(javax.swing.Action.SELECTED_KEY,
+ if (b == None) null else new java.lang.Boolean(b.get))
+ }
+
+ def apply()
+}
diff --git a/src/swing/scala/swing/BoxPanel.scala b/src/swing/scala/swing/BoxPanel.scala
index d8af118ef9..6520224f04 100644
--- a/src/swing/scala/swing/BoxPanel.scala
+++ b/src/swing/scala/swing/BoxPanel.scala
@@ -1,11 +1,10 @@
package scala.swing
-class BoxPanel(orientation: Orientation)(content0: Component*) extends IndexedPanel {
+class BoxPanel(orientation: Orientation) extends Panel with IndexedContainer {
override lazy val peer = {
val p = new javax.swing.JPanel
val l = new javax.swing.BoxLayout(p, orientation.peer)
p.setLayout(l)
p
}
- content ++ content0
}
diff --git a/src/swing/scala/swing/BufferAdapter.scala b/src/swing/scala/swing/BufferAdapter.scala
new file mode 100644
index 0000000000..4e0c4b9d09
--- /dev/null
+++ b/src/swing/scala/swing/BufferAdapter.scala
@@ -0,0 +1,30 @@
+package scala.swing
+
+import scala.collection.mutable.Buffer
+
+/**
+ * Default partial implementation for buffer adapters.
+ */
+protected[swing] abstract class BufferAdapter[A] extends Buffer[A] { outer =>
+ def clear { for (i <- 0 to length) remove(0) }
+ def update(n: Int, a: A) {
+ remove(0)
+ insertAt(n, a)
+ }
+ def insertAll(n: Int, iter: Iterable[A]) {
+ var i = n
+ for(el <- iter) {
+ insertAt(i, el)
+ i += 1
+ }
+ }
+ protected def insertAt(n: Int, a: A)
+
+ def readOnly : RandomAccessSeq[A] = new RandomAccessSeq[A] {
+ def length = outer.length
+ def apply(idx : Int) = outer.apply(idx)
+ override def stringPrefix = outer.stringPrefix + "RO"
+ }
+ def +:(a: A): this.type = { insertAt(0, a); this }
+ def elements = Iterator.range(0,length).map(apply(_))
+}
diff --git a/src/swing/scala/swing/ButtonMutex.scala b/src/swing/scala/swing/ButtonMutex.scala
new file mode 100644
index 0000000000..4edae73b9d
--- /dev/null
+++ b/src/swing/scala/swing/ButtonMutex.scala
@@ -0,0 +1,27 @@
+package scala.swing
+
+import javax.swing.{AbstractButton => JAbstractButton,Icon}
+import event._
+import scala.collection._
+
+
+class ButtonMutex(initialButtons: Button*) {
+ val peer: javax.swing.ButtonGroup = new javax.swing.ButtonGroup
+
+ val buttons: mutable.Set[Button] = new mutable.Set[Button] {
+ def -=(b: Button) { peer.remove(b.peer) }
+ def +=(b: Button) { peer.add(b.peer) }
+ def contains(b: Button) = elements.contains(b)
+ def size = peer.getButtonCount
+ def elements: Iterator[Button] = new Iterator[Button] {
+ val enum = peer.getElements
+ def next = Component.wrapperFor[Button](enum.nextElement)
+ def hasNext = enum.hasMoreElements
+ }
+ }
+ buttons ++= initialButtons
+
+ def deselectAll() { peer.clearSelection }
+ def selected: Option[Selectable] = buttons.find(_.selected)
+ def select(b: Selectable) { b.selected = true }
+}
diff --git a/src/swing/scala/swing/CheckBox.scala b/src/swing/scala/swing/CheckBox.scala
new file mode 100644
index 0000000000..7851c8c75d
--- /dev/null
+++ b/src/swing/scala/swing/CheckBox.scala
@@ -0,0 +1,8 @@
+package scala.swing
+
+import javax.swing._
+
+class CheckBox(override val peer: JCheckBox) extends ToggleButton {
+ def this(txt: String) = this(new JCheckBox(txt))
+ def this() = this(new JCheckBox)
+} \ No newline at end of file
diff --git a/src/swing/scala/swing/Component.scala b/src/swing/scala/swing/Component.scala
index 2d3a319b0b..bb9c76f1f9 100644
--- a/src/swing/scala/swing/Component.scala
+++ b/src/swing/scala/swing/Component.scala
@@ -1,6 +1,7 @@
package scala.swing
import event._
+import geometry._
import java.awt.Font
import java.awt.event._
import javax.swing.JComponent
@@ -11,7 +12,6 @@ object Component {
def wrapperFor[C<:Component](c: javax.swing.JComponent): C = c.getClientProperty(ClientKey).asInstanceOf[C]
}
-
abstract class Component extends UIElement with Showable.Swing with Publisher {
lazy val peer: javax.swing.JComponent = new javax.swing.JComponent {}
peer.putClientProperty(Component.ClientKey, this)
@@ -26,19 +26,22 @@ abstract class Component extends UIElement with Showable.Swing with Publisher {
def xAlignment: Double = peer.getAlignmentX
def xAlignment_=(x: Double) = peer.setAlignmentX(x.toFloat)
def yAlignment: Double = peer.getAlignmentY
- def yAlignment_=(x: Double) = peer.setAlignmentY(x.toFloat)
+ def yAlignment_=(y: Double) = peer.setAlignmentY(y.toFloat)
def foreground: Color = new Color(peer.getForeground)
- def foreground_=(x: Color) = peer.setForeground(x)
+ def foreground_=(c: Color) = peer.setForeground(c)
def background: Color = new Color(peer.getBackground)
- def background_=(x: Color) = peer.setBackground(x)
+ def background_=(c: Color) = peer.setBackground(c)
def border: Border = peer.getBorder
- def border_=(x: Border) { peer.setBorder(x) }
+ def border_=(b: Border) { peer.setBorder(b) }
def font: Font = peer.getFont
- def font_=(x: Font) = peer.setFont(x)
+ def font_=(f: Font) = peer.setFont(f)
def opaque: Boolean = peer.isOpaque
- def opaque_=(x: Boolean) = peer.setOpaque(x)
+ def opaque_=(b: Boolean) = peer.setOpaque(b)
+
+ def enabled: Boolean = peer.isEnabled
+ def enabled_=(b: Boolean) = peer.setEnabled(b)
def tooltip: String = peer.getToolTipText
def tooltip_=(t: String) = peer.setToolTipText(t)
diff --git a/src/swing/scala/swing/ComponentList.scala b/src/swing/scala/swing/ComponentList.scala
index 6582b08b5a..31e48e65b1 100644
--- a/src/swing/scala/swing/ComponentList.scala
+++ b/src/swing/scala/swing/ComponentList.scala
@@ -3,13 +3,13 @@ package scala.swing
import javax.swing._
import event._
-class ComponentList(val jlist: JList) extends Container(jlist) with Publisher {
+class ComponentList(override val peer: JList) extends Component with Container with Publisher {
def this() = this(new JList)
def this(elems: Seq[Object]) = this(new JList(elems.toArray))
- def fixedCellWidth = jlist.getFixedCellWidth
- def fixedCellWidth_=(x: Int) = jlist.setFixedCellWidth(x)
+ def fixedCellWidth = peer.getFixedCellWidth
+ def fixedCellWidth_=(x: Int) = peer.setFixedCellWidth(x)
- def fixedCellHeight = jlist.getFixedCellHeight
- def fixedCellHeight_=(x: Int) = jlist.setFixedCellHeight(x)
+ def fixedCellHeight = peer.getFixedCellHeight
+ def fixedCellHeight_=(x: Int) = peer.setFixedCellHeight(x)
}
diff --git a/src/swing/scala/swing/Container.scala b/src/swing/scala/swing/Container.scala
index 896ecc03d3..674fbee796 100644
--- a/src/swing/scala/swing/Container.scala
+++ b/src/swing/scala/swing/Container.scala
@@ -3,35 +3,21 @@ package scala.swing
import event._
import scala.collection.mutable.Buffer
-abstract class Container(override val peer: javax.swing.JComponent) extends Component {
- def this() = this(new javax.swing.JComponent {})
- def content: Seq[Component] = new Content
+trait Container extends Component {
+ protected val _contents = new Content
+ def contents: Seq[Component] = _contents
- protected class Content extends Buffer[Component] {
+ protected class Content extends BufferAdapter[Component] {
def wrap(c: java.awt.Component) = Component.wrapperFor(c.asInstanceOf[javax.swing.JComponent])
- def clear = peer.removeAll()
+ override def clear { peer.removeAll() }
def remove(n: Int): Component = {
val c = peer.getComponent(n)
peer.remove(n)
wrap(c)
}
- def update(n: Int, c: Component) { peer.add(c.peer, n) }
- def insertAll(n: Int, iter: Iterable[Component]) {
- var i = n
- for(el <- iter) {
- peer.add(el.peer, i)
- i += 1
- }
- }
- def readOnly : RandomAccessSeq[Component] = new RandomAccessSeq[Component] {
- def length = Content.this.length
- def apply(idx : Int) = Content.this.apply(idx)
- override def stringPrefix = Content.this.stringPrefix + "RO"
- }
- def +:(c: Component): Buffer[Component] = { update(0, c); this }
- def +=(c: Component) { peer.add(c.peer); this }
+ protected def insertAt(n: Int, c: Component) { peer.add(c.peer, n) }
+ def +=(c: Component) { peer.add(c.peer) }
def length = peer.getComponentCount
- def elements = peer.getComponents.projection.map(wrap(_)).elements
def apply(n: Int) = wrap(peer.getComponent(n))
}
diff --git a/src/swing/scala/swing/FlowPanel.scala b/src/swing/scala/swing/FlowPanel.scala
index 6d9a2189b5..8842d2fcf6 100644
--- a/src/swing/scala/swing/FlowPanel.scala
+++ b/src/swing/scala/swing/FlowPanel.scala
@@ -1,6 +1,24 @@
package scala.swing
-class FlowPanel(orientation: Orientation)(content0: Component*) extends IndexedPanel {
- override lazy val peer = new javax.swing.JPanel(new java.awt.FlowLayout(orientation.peer))
- content ++ content0
+import java.awt.FlowLayout
+
+object FlowPanel {
+ object Alignment extends Enumeration {
+ val Leading = Value(FlowLayout.LEADING)
+ val Trailing = Value(FlowLayout.TRAILING)
+ val Left = Value(FlowLayout.LEFT)
+ val Right = Value(FlowLayout.RIGHT)
+ val Center = Value(FlowLayout.CENTER)
+ }
+}
+
+class FlowPanel(alignment: FlowPanel.Alignment.Value) extends Panel with IndexedContainer {
+ def this() = this(FlowPanel.Alignment.Center)
+ override lazy val layoutManager = new java.awt.FlowLayout(alignment.id)
+ override lazy val peer = new javax.swing.JPanel(layoutManager)
+
+ def vGap: Int = layoutManager.getVgap
+ def vGap_=(n: Int) { layoutManager.setVgap(n) }
+ def hGap: Int = layoutManager.getHgap
+ def hGap_=(n: Int) { layoutManager.setHgap(n) }
}
diff --git a/src/swing/scala/swing/Frame.scala b/src/swing/scala/swing/Frame.scala
index 7a690a78f4..93e805e322 100644
--- a/src/swing/scala/swing/Frame.scala
+++ b/src/swing/scala/swing/Frame.scala
@@ -11,20 +11,22 @@ class Frame(val peer: JFrame) extends UIElement with RootPanel with Showable.Swi
override def content_=(c: Component) {
super.content_=(c)
- peer.pack() // pack also validates, which is generally required after an add}
+ peer.pack() // pack also validates, which is generally required after an add
}
- def defaultButton: Button = Component.wrapperFor(peer.getRootPane.getDefaultButton)
- def defaultButton_=(b: Button) { peer.getRootPane.setDefaultButton(b.peer) }
+ def defaultButton: PushButton = Component.wrapperFor(peer.getRootPane.getDefaultButton)
+ def defaultButton_=(b: PushButton) { peer.getRootPane.setDefaultButton(b.peer) }
def pack(): this.type = { peer.pack(); this }
- peer.addWindowListener {
- new java.awt.event.WindowListener {
- def windowActivated(e: java.awt.event.WindowEvent) = publish(WindowActivated(Frame.this))
- def windowClosed(e: java.awt.event.WindowEvent) = publish(WindowClosed(Frame.this))
- def windowClosing(e: java.awt.event.WindowEvent) = publish(WindowClosing(Frame.this))
- def windowDeactivated(e: java.awt.event.WindowEvent) = publish(WindowDeactivated(Frame.this))
- def windowDeiconified(e: java.awt.event.WindowEvent) = publish(WindowDeiconified(Frame.this))
- def windowIconified(e: java.awt.event.WindowEvent) = publish(WindowIconified(Frame.this))
- def windowOpened(e: java.awt.event.WindowEvent) = publish(WindowOpened(Frame.this))
- }
- }
+
+ def menuBar: MenuBar = Component.wrapperFor(peer.getJMenuBar)
+ def menuBar_=(m: MenuBar) = peer.setJMenuBar(m.peer)
+
+ peer.addWindowListener(new java.awt.event.WindowListener {
+ def windowActivated(e: java.awt.event.WindowEvent) { publish(WindowActivated(Frame.this)) }
+ def windowClosed(e: java.awt.event.WindowEvent) { publish(WindowClosed(Frame.this)) }
+ def windowClosing(e: java.awt.event.WindowEvent) { publish(WindowClosing(Frame.this)) }
+ def windowDeactivated(e: java.awt.event.WindowEvent) { publish(WindowDeactivated(Frame.this)) }
+ def windowDeiconified(e: java.awt.event.WindowEvent) { publish(WindowDeiconified(Frame.this)) }
+ def windowIconified(e: java.awt.event.WindowEvent) { publish(WindowIconified(Frame.this)) }
+ def windowOpened(e: java.awt.event.WindowEvent) { publish(WindowOpened(Frame.this)) }
+ })
}
diff --git a/src/swing/scala/swing/GridBagPanel.scala b/src/swing/scala/swing/GridBagPanel.scala
new file mode 100644
index 0000000000..874ad36840
--- /dev/null
+++ b/src/swing/scala/swing/GridBagPanel.scala
@@ -0,0 +1,80 @@
+package scala.swing
+
+import java.awt.{Insets, GridBagConstraints}
+
+object GridBagPanel {
+ object Fill extends Enumeration {
+ val None = Value(GridBagConstraints.NONE)
+ val Horizontal = Value(GridBagConstraints.HORIZONTAL)
+ val Vertical = Value(GridBagConstraints.VERTICAL)
+ val Both = Value(GridBagConstraints.BOTH)
+ }
+ object Anchor extends Enumeration {
+ val North = Value(GridBagConstraints.NORTH)
+ val NorthEast = Value(GridBagConstraints.NORTHEAST)
+ val East = Value(GridBagConstraints.EAST)
+ val SouthEast = Value(GridBagConstraints.SOUTHEAST)
+ val South = Value(GridBagConstraints.SOUTH)
+ val SouthWest = Value(GridBagConstraints.SOUTHWEST)
+ val West = Value(GridBagConstraints.WEST)
+ val NorthWest = Value(GridBagConstraints.NORTHWEST)
+ val CENTER = Value(GridBagConstraints.CENTER)
+
+ val PageStart = Value(GridBagConstraints.PAGE_START)
+ val PageEnd = Value(GridBagConstraints.PAGE_END)
+ val LineStart = Value(GridBagConstraints.LINE_START)
+ val LineEnd = Value(GridBagConstraints.LINE_END)
+ val FirstLineStart = Value(GridBagConstraints.FIRST_LINE_START)
+ val FirstLineEnd = Value(GridBagConstraints.FIRST_LINE_END)
+ val LastLineStart = Value(GridBagConstraints.LAST_LINE_START)
+ val LastLineEnd = Value(GridBagConstraints.LAST_LINE_END)
+ }
+}
+
+class GridBagPanel extends Panel with LayoutContainer {
+ import GridBagPanel._
+
+ override lazy val layoutManager = new java.awt.GridBagLayout
+ override lazy val peer = new javax.swing.JPanel(layoutManager)
+
+ class Constraints(val peer: GridBagConstraints) extends Proxy {
+ def self = peer
+ def this(gridx: Int, gridy: Int,
+ gridwidth: Int, gridheight: Int,
+ weightx: Double, weighty: Double,
+ anchor: Int, fill: Int, insets: Insets,
+ ipadx: Int, ipady: Int) =
+ this(new GridBagConstraints(gridx, gridy,
+ gridwidth, gridheight,
+ weightx, weighty,
+ anchor, fill, insets,
+ ipadx, ipady))
+ def this() = this(new GridBagConstraints())
+ def gridx: Int = peer.gridx
+ def gridx_=(x: Int) { peer.gridx = x }
+ def gridy: Int = peer.gridy
+ def gridy_=(y: Int) { peer.gridy = y }
+
+ def gridwidth: Int = peer.gridwidth
+ def gridwidth_=(w: Int) { peer.gridwidth = w }
+ def gridheight: Int = peer.gridheight
+ def gridheight_=(h: Int) { peer.gridheight = h }
+ def weightx: Double = peer.weightx
+ def weightx_=(x: Double) { peer.weightx = x }
+ def weighty: Double = peer.weighty
+ def weighty_=(y: Double) { peer.weighty = y }
+ def anchor: Anchor.Value = Anchor(peer.anchor)
+ def anchor_=(a: Anchor.Value) { peer.anchor = a.id }
+ def fill: Fill.Value = Fill(peer.fill)
+ def fill_=(f: Fill.Value) { peer.fill = f.id }
+ def insets: Insets = peer.insets
+ def insets_=(i: Insets) { peer.insets = i }
+ def ipadx: Int = peer.ipadx
+ def ipadx_=(x: Int) { peer.ipadx = x }
+ def ipady: Int = peer.ipady
+ def ipady_=(y: Int) { peer.ipady = y }
+ }
+
+ def constraintsFor(comp: Component) =
+ new Constraints(layoutManager.getConstraints(comp.peer))
+}
diff --git a/src/swing/scala/swing/GridPanel.scala b/src/swing/scala/swing/GridPanel.scala
index e6360aadbe..799e52d9ae 100644
--- a/src/swing/scala/swing/GridPanel.scala
+++ b/src/swing/scala/swing/GridPanel.scala
@@ -4,11 +4,17 @@ object GridPanel {
val Adapt = 0
}
-class GridPanel(rows0: Int, cols0: Int)(content0: Component*) extends IndexedPanel {
- override lazy val layout = new java.awt.GridLayout(rows0, cols0)
- override lazy val peer = new javax.swing.JPanel(layout)
- content ++ content0
+class GridPanel(rows0: Int, cols0: Int) extends Panel with IndexedContainer {
+ override lazy val layoutManager = new java.awt.GridLayout(rows0, cols0)
+ override lazy val peer = new javax.swing.JPanel(layoutManager)
- def rows: Int = layout.getRows
- def columns: Int = layout.getColumns
+ def rows: Int = layoutManager.getRows
+ def rows_=(n: Int) { layoutManager.setRows(n) }
+ def columns: Int = layoutManager.getColumns
+ def columns_=(n: Int) { layoutManager.setColumns(n) }
+
+ def vGap: Int = layoutManager.getVgap
+ def vGap_=(n: Int) { layoutManager.setVgap(n) }
+ def hGap: Int = layoutManager.getHgap
+ def hGap_=(n: Int) { layoutManager.setHgap(n) }
}
diff --git a/src/swing/scala/swing/IndexedContainer.scala b/src/swing/scala/swing/IndexedContainer.scala
new file mode 100644
index 0000000000..dd38479c17
--- /dev/null
+++ b/src/swing/scala/swing/IndexedContainer.scala
@@ -0,0 +1,8 @@
+package scala.swing
+
+import scala.collection.mutable.Buffer
+
+trait IndexedContainer extends Container {
+ override val contents: Buffer[Component] = new Content
+ def contents_=(c: Component*) { contents.clear(); contents ++= c }
+}
diff --git a/src/swing/scala/swing/IndexedPanel.scala b/src/swing/scala/swing/IndexedPanel.scala
deleted file mode 100644
index c2d0034184..0000000000
--- a/src/swing/scala/swing/IndexedPanel.scala
+++ /dev/null
@@ -1,8 +0,0 @@
-package scala.swing
-
-import scala.collection.mutable.Buffer
-
-abstract class IndexedPanel extends Panel {
- override val content: Buffer[Component] = new Content
- def content_=(c: Component*) { content.clear(); content ++= c }
-}
diff --git a/src/swing/scala/swing/LayoutContainer.scala b/src/swing/scala/swing/LayoutContainer.scala
new file mode 100644
index 0000000000..46cc0e2c10
--- /dev/null
+++ b/src/swing/scala/swing/LayoutContainer.scala
@@ -0,0 +1,20 @@
+package scala.swing
+
+import javax.swing.JComponent
+import scala.collection.mutable.Map
+
+trait LayoutContainer extends Container {
+ type Constraints <: { def peer: AnyRef }
+ protected def constraintsFor(c: Component): Constraints
+ def layout: Map[Component, Constraints] = new Map[Component, Constraints] {
+ def -=(c: Component) { _contents -= c }
+ def update(c: Component, l: Constraints) { peer.add(c.peer, l.peer) }
+ def get(c: Component) = Swing.toOption(constraintsFor(c))
+ def size = peer.getComponentCount
+ def elements: Iterator[(Component, Constraints)] =
+ Iterator.range(0,size).map { c =>
+ val comp = Component.wrapperFor[Component](peer.getComponent(c).asInstanceOf[JComponent])
+ (comp, constraintsFor(comp))
+ }
+ }
+}
diff --git a/src/swing/scala/swing/Menu.scala b/src/swing/scala/swing/Menu.scala
new file mode 100644
index 0000000000..fdb75229c1
--- /dev/null
+++ b/src/swing/scala/swing/Menu.scala
@@ -0,0 +1,40 @@
+package scala.swing
+
+import scala.collection.mutable._
+import javax.swing._
+
+class MenuBar extends IndexedContainer {
+ override lazy val peer = new JMenuBar
+
+ def menus: Seq[Menu] = contents.filter(_.isInstanceOf[Menu]).map(_.asInstanceOf[Menu])
+
+ // Not implemented by Swing
+ //def helpMenu: Menu = Component.wrapperFor(peer.getHelpMenu)
+ //def helpMenu_=(m: Menu) { peer.setHelpMenu(m.peer) }
+}
+
+/*trait MenuElement extends Component {
+ def peer: javax.swing.JComponent with javax.swing.MenuElement
+
+ def subElements: Seq[MenuElement] = peer.getSubElements.map(Component.wrapperFor(_))
+}*/
+
+class MenuItem(val title: String) extends Button {
+ def this(a: Action) = {
+ this("")
+ action = a
+ }
+ override lazy val peer = new JMenuItem(title)
+}
+
+class Menu(title: String) extends MenuItem(title) with IndexedContainer { self: Menu =>
+ override lazy val peer = new JMenu(title)
+}
+
+class RadioMenuItem(title: String) extends MenuItem(title) {
+ override lazy val peer = new JRadioButtonMenuItem(title)
+}
+
+class CheckMenuItem(title: String) extends MenuItem(title) {
+ override lazy val peer = new JCheckBoxMenuItem(title)
+} \ No newline at end of file
diff --git a/src/swing/scala/swing/Orientation.scala b/src/swing/scala/swing/Orientation.scala
index 7b73b15d22..dd38056ccb 100644
--- a/src/swing/scala/swing/Orientation.scala
+++ b/src/swing/scala/swing/Orientation.scala
@@ -1,6 +1,7 @@
package scala.swing
import javax.swing.SwingConstants._
+import javax.swing.JTabbedPane
object Orientation {
def wrap(n: Int): Orientation = n match {
@@ -12,6 +13,19 @@ sealed trait Orientation { def peer: Int }
case object Horizontal extends Orientation { def peer = HORIZONTAL }
case object Vertical extends Orientation { def peer = VERTICAL }
+object Edge {
+ def wrap(n: Int): Edge = n match {
+ case LEFT => Left
+ case RIGHT => Right
+ case TOP => Top
+ case BOTTOM => Bottom
+ }
+}
+
+sealed trait Edge {
+ def peer: Int
+}
+
object XAlignment {
def wrap(n: Int): XAlignment = n match {
case LEFT => Left
@@ -30,11 +44,11 @@ object YAlignment {
}
}
sealed trait YAlignment { def peer: Int }
-case object Left extends XAlignment { def peer = LEFT }
-case object Right extends XAlignment { def peer = RIGHT }
-case object Top extends YAlignment { def peer = TOP }
+case object Left extends XAlignment with Edge { def peer = LEFT }
+case object Right extends XAlignment with Edge { def peer = RIGHT }
+case object Top extends YAlignment with Edge { def peer = TOP }
//case object Baseline extends YAlignment { def peer = BASELINE }
-case object Bottom extends YAlignment { def peer = BOTTOM }
+case object Bottom extends YAlignment with Edge { def peer = BOTTOM }
case object Center extends XAlignment with YAlignment { def peer = CENTER }
/*object Orientation extends Enumeration {
diff --git a/src/swing/scala/swing/Oriented.scala b/src/swing/scala/swing/Oriented.scala
new file mode 100644
index 0000000000..39e2b0ba2a
--- /dev/null
+++ b/src/swing/scala/swing/Oriented.scala
@@ -0,0 +1,13 @@
+package scala.swing
+
+trait Oriented {
+ def peer: javax.swing.JComponent {
+ def getOrientation(): Int
+ def setOrientation(n: Int)
+ }
+ def orientation: Orientation = Orientation.wrap(peer.getOrientation)
+}
+
+trait Orientable extends Oriented {
+ def orientation_=(o: Orientation) { peer.setOrientation(o.peer) }
+}
diff --git a/src/swing/scala/swing/Panel.scala b/src/swing/scala/swing/Panel.scala
index 40c30dbfd6..5ff6cef0e3 100644
--- a/src/swing/scala/swing/Panel.scala
+++ b/src/swing/scala/swing/Panel.scala
@@ -3,5 +3,5 @@ package scala.swing
abstract class Panel extends Container {
override lazy val peer: javax.swing.JPanel = new javax.swing.JPanel
- def layout: java.awt.LayoutManager = peer.getLayout
+ def layoutManager: java.awt.LayoutManager = peer.getLayout
}
diff --git a/src/swing/scala/swing/ProgressBar.scala b/src/swing/scala/swing/ProgressBar.scala
index 07d48f168f..db80035058 100644
--- a/src/swing/scala/swing/ProgressBar.scala
+++ b/src/swing/scala/swing/ProgressBar.scala
@@ -2,12 +2,9 @@ package scala.swing
import event._
-class ProgressBar(override val peer: javax.swing.JProgressBar) extends Component {
+class ProgressBar(override val peer: javax.swing.JProgressBar) extends Component with Orientable {
def this() = this(new javax.swing.JProgressBar)
- def orientation: Orientation = Orientation.wrap(peer.getOrientation)
- def orientation_=(o: Orientation) { peer.setOrientation(o.peer) }
-
def min: Int = peer.getMinimum
def min_=(v: Int) { peer.setMinimum(v) }
def max: Int = peer.getMaximum
diff --git a/src/swing/scala/swing/PushButton.scala b/src/swing/scala/swing/PushButton.scala
new file mode 100644
index 0000000000..99e08e4e72
--- /dev/null
+++ b/src/swing/scala/swing/PushButton.scala
@@ -0,0 +1,15 @@
+package scala.swing
+
+import javax.swing._
+import event._
+
+/** A class for buttons; standard constructor wraps around a swing button */
+class PushButton(override val peer: JButton) extends Component with Publisher {
+ def this(txt: String) = this(new JButton(txt))
+ def this() = this(new JButton)
+ def text: String = peer.getText
+ def text_=(s: String) = peer.setText(s)
+ def icon: Icon = peer.getIcon
+ def icon_=(i: Icon) = peer.setIcon(i)
+
+}
diff --git a/src/swing/scala/swing/RadioButton.scala b/src/swing/scala/swing/RadioButton.scala
new file mode 100644
index 0000000000..4b0cd50087
--- /dev/null
+++ b/src/swing/scala/swing/RadioButton.scala
@@ -0,0 +1,8 @@
+package scala.swing
+
+import javax.swing._
+
+class RadioButton(override val peer: JRadioButton) extends ToggleButton(peer) {
+ def this(txt: String) = this(new JRadioButton(txt))
+ def this() = this(new JRadioButton)
+} \ No newline at end of file
diff --git a/src/swing/scala/swing/Reactions.scala b/src/swing/scala/swing/Reactions.scala
index af2ca7e2fa..7b94650976 100644
--- a/src/swing/scala/swing/Reactions.scala
+++ b/src/swing/scala/swing/Reactions.scala
@@ -21,7 +21,8 @@ class Reactions {
def sendTo(ps: List[Reaction]): Unit = ps match {
case Nil =>
case p :: ps =>
- if (p isDefinedAt e) p(e) else sendTo(ps)
+ if (p isDefinedAt e) p(e)
+ /*else*/ sendTo(ps)
}
sendTo(parts)
}
diff --git a/src/swing/scala/swing/ScrollPane.scala b/src/swing/scala/swing/ScrollPane.scala
index c794372edc..17fb5e8190 100644
--- a/src/swing/scala/swing/ScrollPane.scala
+++ b/src/swing/scala/swing/ScrollPane.scala
@@ -2,7 +2,7 @@ package scala.swing
import javax.swing.JScrollPane
-class ScrollPane(override val peer: JScrollPane) extends Container(peer) with Publisher {
+class ScrollPane(override val peer: JScrollPane) extends Component with Publisher {
def this() = this(new JScrollPane)
def this(contents: Component) = this(new JScrollPane(contents.peer))
diff --git a/src/swing/scala/swing/Scrollable.scala b/src/swing/scala/swing/Scrollable.scala
new file mode 100644
index 0000000000..d5ffe636b6
--- /dev/null
+++ b/src/swing/scala/swing/Scrollable.scala
@@ -0,0 +1,17 @@
+package scala.swing
+
+import geometry._
+
+trait Scrollable extends Component {
+ protected def scrollablePeer: javax.swing.Scrollable
+ def preferredViewportSize = scrollablePeer.getPreferredScrollableViewportSize
+
+ def tracksViewportHeight: Boolean = scrollablePeer.getScrollableTracksViewportHeight
+ def tracksViewportWidth: Boolean = scrollablePeer.getScrollableTracksViewportWidth
+
+ def blockIncrement(visibleRect: Rectangle, orientation: Orientation, direction: Int): Int =
+ scrollablePeer.getScrollableBlockIncrement(visibleRect.peer, orientation.peer, direction)
+
+ def unitIncrement(visibleRect: Rectangle, orientation: Orientation, direction: Int): Int =
+ scrollablePeer.getScrollableUnitIncrement(visibleRect.peer, orientation.peer, direction)
+}
diff --git a/src/swing/scala/swing/Selectable.scala b/src/swing/scala/swing/Selectable.scala
new file mode 100644
index 0000000000..38b86efb60
--- /dev/null
+++ b/src/swing/scala/swing/Selectable.scala
@@ -0,0 +1,11 @@
+package scala.swing
+
+trait Selectable {
+ def peer: javax.swing.JComponent {
+ def setSelected(b: Boolean)
+ def isSelected(): Boolean
+ }
+
+ def selected: Boolean = peer.isSelected
+ def selected_=(b: Boolean) = peer.setSelected(b)
+}
diff --git a/src/swing/scala/swing/Separator.scala b/src/swing/scala/swing/Separator.scala
new file mode 100644
index 0000000000..3be204a49f
--- /dev/null
+++ b/src/swing/scala/swing/Separator.scala
@@ -0,0 +1,10 @@
+package scala.swing
+
+import javax.swing._
+
+/**
+ * @see javax.swing.JSeparator
+ */
+class Separator extends Component with Oriented {
+ override lazy val peer = new JSeparator
+}
diff --git a/src/swing/scala/swing/SimpleGUIApplication.scala b/src/swing/scala/swing/SimpleGUIApplication.scala
index efbe580116..8995852b79 100644
--- a/src/swing/scala/swing/SimpleGUIApplication.scala
+++ b/src/swing/scala/swing/SimpleGUIApplication.scala
@@ -7,7 +7,7 @@ abstract class SimpleGUIApplication extends GUIApplication {
def main(args: Array[String]) = {
SwingUtilities.invokeLater {
- new Runnable { def run() { init(); top.pack.show() } }
+ new Runnable { def run() { init(); top.pack().show() } }
}
}
diff --git a/src/swing/scala/swing/Slider.scala b/src/swing/scala/swing/Slider.scala
index e4927709ca..0c0e4894a8 100644
--- a/src/swing/scala/swing/Slider.scala
+++ b/src/swing/scala/swing/Slider.scala
@@ -3,12 +3,9 @@ package scala.swing
import event._
import Swing._
-class Slider(override val peer: javax.swing.JSlider) extends Component with EditorComponent {
+class Slider(override val peer: javax.swing.JSlider) extends Component with Orientable with EditorComponent {
def this() = this(new javax.swing.JSlider)
- def orientation: Orientation = Orientation.wrap(peer.getOrientation)
- def orientation_=(o: Orientation) { peer.setOrientation(o.peer) }
-
def min: Int = peer.getMinimum
def min_=(v: Int) { peer.setMinimum(v) }
def max: Int = peer.getMaximum
diff --git a/src/swing/scala/swing/Swing.scala b/src/swing/scala/swing/Swing.scala
index 781e399794..f1dcfc7ebb 100644
--- a/src/swing/scala/swing/Swing.scala
+++ b/src/swing/scala/swing/Swing.scala
@@ -1,9 +1,14 @@
package scala.swing
+import geometry._
import javax.swing._
import javax.swing.event._
object Swing {
+ protected[swing] def ifNull[A](o: Object, a: A): A = if(o eq null) a else o.asInstanceOf[A]
+ protected[swing] def toOption[A](o: Object): Option[A] = if(o eq null) None else Some(o.asInstanceOf[A])
+ protected[swing] def toNull[A>:Null<:AnyRef](a: Option[A]): Object = if(a == None) null else a.get
+
implicit def block2Runnable(block: =>Unit): Runnable = new Runnable {
override def run = block
}
diff --git a/src/swing/scala/swing/TabbedPane.scala b/src/swing/scala/swing/TabbedPane.scala
new file mode 100644
index 0000000000..e3ff3ecc34
--- /dev/null
+++ b/src/swing/scala/swing/TabbedPane.scala
@@ -0,0 +1,76 @@
+package scala.swing
+
+import geometry._
+import scala.collection.mutable.Buffer
+import javax.swing.{JTabbedPane, JComponent}
+
+
+object TabbedPane {
+ object Layout extends Enumeration {
+ val Wrap = Value(JTabbedPane.WRAP_TAB_LAYOUT)
+ val Scroll = Value(JTabbedPane.SCROLL_TAB_LAYOUT)
+ }
+}
+
+class TabbedPane(override val peer: JTabbedPane) extends Component with Publisher {
+ import TabbedPane._
+
+ class Tab protected(title0: String, component0: Component, tip0: String, index0: Int) {
+ def this(title0: String, component0: Component, tip0: String) =
+ this(title0, component0, tip0, 0)
+ title = title0
+ component = component0
+ tip = tip0
+ def title: String = peer.getTitleAt(index)
+ def title_=(t: String) { peer.setTitleAt(index, t) }
+ def component: Component = Component.wrapperFor(peer.getComponentAt(index).asInstanceOf[JComponent])
+ def component_=(c: Component) { peer.setComponentAt(index, c.peer) }
+ def tip: String = peer.getToolTipTextAt(index)
+ def tip_=(t: String) { peer.setToolTipTextAt(index, t) }
+ def enabled: Boolean = peer.isEnabledAt(index)
+ def enabled_=(b: Boolean) { peer.setEnabledAt(index, b) }
+ def mnemonic: Int = peer.getMnemonicAt(index)
+ def mnemonic_=(k: Int) = peer.setMnemonicAt(index, k)
+ def foreground: Color = new Color(peer.getForegroundAt(index))
+ def foreground_=(c: Color) = peer.setForegroundAt(index, c)
+ def background: Color = new Color(peer.getBackgroundAt(index))
+ def background_=(c: Color) = peer.setBackgroundAt(index, c)
+ def bounds: Rectangle = Rectangle.wrap(peer.getBoundsAt(index))
+
+ // TODO: icon, disabledIcon
+
+ def index = _index
+ protected[TabbedPane] var _index: Int = index0
+ }
+
+ def this() = this(new JTabbedPane)
+
+ object tabs extends BufferAdapter[Tab] {
+ def runCount: Int = peer.getTabRunCount
+
+ def remove(n: Int): Tab = {
+ val t = apply(n)
+ peer.removeTabAt(n)
+ for(i <- n to length) apply(i)._index -= 1
+ t
+ }
+ protected def insertAt(n: Int, t: Tab) {
+ for(i <- n to length) apply(i)._index += 1
+ peer.insertTab(t.title, null, t.component.peer, t.tip, n)
+ }
+
+ def +=(t: Tab) { peer.addTab(t.title, null, t.component.peer, t.tip) }
+ def length = peer.getTabCount
+ def apply(n: Int) = new Tab(peer.getTitleAt(n),
+ Component.wrapperFor(peer.getComponentAt(n).asInstanceOf[javax.swing.JComponent]),
+ peer.getToolTipTextAt(n))
+ }
+
+ def tabLayoutPolicy: Layout.Value = Layout(peer.getTabLayoutPolicy)
+ def tabLayoutPolicy_=(p: Layout.Value) { peer.setTabLayoutPolicy(p.id) }
+
+ def tabPlacement: Edge = Edge.wrap(peer.getTabPlacement)
+ def tabPlacement(b: Edge) { peer.setTabPlacement(b.peer) }
+
+ def selected: Tab = tabs(peer.getSelectedIndex)
+}
diff --git a/src/swing/scala/swing/Table.scala b/src/swing/scala/swing/Table.scala
index 7358928568..a9078f26aa 100644
--- a/src/swing/scala/swing/Table.scala
+++ b/src/swing/scala/swing/Table.scala
@@ -1,10 +1,12 @@
package scala.swing
+import geometry._
import model.Matrix
import javax.swing._
import javax.swing.table._
import javax.swing.event._
import event._
+import scala.collection.mutable.Set
object Table {
object AutoResizeMode extends Enumeration {
@@ -15,9 +17,18 @@ object Table {
val LastColumn = Value(AUTO_RESIZE_LAST_COLUMN, "LastColumn")
val AllColumns = Value(AUTO_RESIZE_ALL_COLUMNS, "AllColumns")
}
+
+ object IntervalMode extends Enumeration {
+ val Single = Value(ListSelectionModel.SINGLE_SELECTION)
+ val SingleInterval = Value(ListSelectionModel.SINGLE_INTERVAL_SELECTION)
+ val MultiInterval = Value(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
+ }
+ object ElementMode extends Enumeration {
+ val Row, Column, Cell, None = Value
+ }
}
-class Table(override val peer: JTable) extends Component with Publisher {
+class Table(override val peer: JTable) extends Component with Scrollable with Publisher {
import Table._
def this() = this(new JTable())
def this(numRows: Int, numColumns: Int) = this(new JTable(numRows, numColumns))
@@ -28,6 +39,8 @@ class Table(override val peer: JTable) extends Component with Publisher {
def this(dm: TableModel, cm: TableColumnModel) = this(new JTable(dm, cm))
def this(dm: TableModel, cm: TableColumnModel, sm: ListSelectionModel) = this(new JTable(dm, cm, sm))
+ protected def scrollablePeer = peer
+
def rowHeight = peer.getRowHeight
def rowHeight_=(x: Int) = peer.setRowHeight(x)
@@ -45,8 +58,89 @@ class Table(override val peer: JTable) extends Component with Publisher {
def gridColor = new swing.Color(peer.getGridColor)
def gridColor_=(color: swing.Color) = peer.setGridColor(color)
+ def preferredViewportSize_=(dim: Dimension) = peer.setPreferredScrollableViewportSize(dim.peer)
+ def fillsViewportHeight: Boolean = peer.getFillsViewportHeight
+ def fillsViewportHeight_=(b: Boolean) = peer.setFillsViewportHeight(b)
+
+ // TODO: could be a sorted set
+ protected abstract class SelectionSet[A](a: =>Seq[A]) extends Set[A] {
+ def -=(n: A)
+ def +=(n: A)
+ def contains(n: A) = a.contains(n)
+ def size = a.length
+ def elements = a.elements
+ }
+
+ class Selection extends Publisher {
+ object rows extends SelectionSet(peer.getSelectedRows) {
+ def -=(n: Int) { peer.removeRowSelectionInterval(n,n) }
+ def +=(n: Int) { peer.addRowSelectionInterval(n,n) }
+
+ def leadIndex: Int = peer.getSelectionModel.getLeadSelectionIndex
+ def anchorIndex: Int = peer.getSelectionModel.getAnchorSelectionIndex
+ }
+
+ object columns extends SelectionSet(peer.getSelectedColumns) {
+ def -=(n: Int) { peer.removeColumnSelectionInterval(n,n) }
+ def +=(n: Int) { peer.addColumnSelectionInterval(n,n) }
+
+ def leadIndex: Int = peer.getColumnModel.getSelectionModel.getLeadSelectionIndex
+ def anchorIndex: Int = peer.getColumnModel.getSelectionModel.getAnchorSelectionIndex
+ }
+
+ def cells: Set[(Int, Int)] =
+ new SelectionSet[(Int, Int)]((for(r <- selection.rows; c <- selection.columns) yield (r,c)).toSeq) { outer =>
+ def -=(n: (Int, Int)) {
+ peer.removeRowSelectionInterval(n._1,n._1)
+ peer.removeColumnSelectionInterval(n._2,n._2)
+ }
+ def +=(n: (Int, Int)) {
+ peer.addRowSelectionInterval(n._1,n._1)
+ peer.addColumnSelectionInterval(n._2,n._2)
+ }
+ override def size = peer.getSelectedRowCount * peer.getSelectedColumnCount
+ }
+
+ /**
+ * From the JTable Swing tutorial:
+ * You can specify selection by cell in multiple interval selection mode,
+ * but the result is a table that does not produce useful selections.
+ */
+ def intervalMode: IntervalMode.Value = IntervalMode(peer.getSelectionModel.getSelectionMode)
+ def intervalMode_=(m: IntervalMode.Value) { peer.getSelectionModel.setSelectionMode(m.id) }
+ def elementMode: ElementMode.Value =
+ if(peer.getColumnSelectionAllowed && peer.getRowSelectionAllowed) ElementMode.Cell
+ else if(peer.getColumnSelectionAllowed) ElementMode.Column
+ else if(peer.getRowSelectionAllowed) ElementMode.Row
+ else ElementMode.None
+ def elementMode_=(m: ElementMode.Value) {
+ m match {
+ case ElementMode.Cell => peer.setCellSelectionEnabled(true)
+ case ElementMode.Column => peer.setRowSelectionAllowed(false); peer.setColumnSelectionAllowed(true)
+ case ElementMode.Row => peer.setRowSelectionAllowed(true); peer.setColumnSelectionAllowed(false)
+ case ElementMode.None => peer.setRowSelectionAllowed(false); peer.setColumnSelectionAllowed(false)
+ }
+ }
+
+ peer.getColumnModel.getSelectionModel.addListSelectionListener(new ListSelectionListener {
+ def valueChanged(e: ListSelectionEvent) {
+ publish(ColumnsSelected(Table.this, e.getValueIsAdjusting, e.getFirstIndex to e.getLastIndex))
+ }
+ })
+ peer.getSelectionModel.addListSelectionListener(new ListSelectionListener {
+ def valueChanged(e: ListSelectionEvent) {
+ publish(RowsSelected(Table.this, e.getValueIsAdjusting, e.getFirstIndex to e.getLastIndex))
+ }
+ })
+ }
+
+ val selection: Selection = new Selection
+
private val initialRenderer = peer.getDefaultRenderer(classOf[AnyRef])
+ /**
+ * Supplies a renderer component for a given cell.
+ */
protected def render(isSelected: Boolean, hasFocus: Boolean, row: Int, column: Int): Component =
new Component {
override lazy val peer = initialRenderer.getTableCellRendererComponent(Table.this.peer,
@@ -54,9 +148,9 @@ class Table(override val peer: JTable) extends Component with Publisher {
}
peer.setDefaultRenderer(classOf[AnyRef], new TableCellRenderer {
- def getTableCellRendererComponent(table: JTable, value: AnyRef, isSelected: Boolean, hasFocus: Boolean, row: Int, column: Int) =
- render(isSelected, hasFocus, row, column).peer
- })
+ def getTableCellRendererComponent(tabBlockIle: JTable, value: AnyRef, isSelected: Boolean, hasFocus: Boolean, row: Int, column: Int) =
+ render(isSelected, hasFocus, row, column).peer
+ })
def apply(row: Int, column: Int) = peer.getValueAt(row, column)
def update(row: Int, column: Int, value: AnyRef) = peer.setValueAt(value, row, column)
diff --git a/src/swing/scala/swing/TextArea.scala b/src/swing/scala/swing/TextArea.scala
new file mode 100644
index 0000000000..396f218d30
--- /dev/null
+++ b/src/swing/scala/swing/TextArea.scala
@@ -0,0 +1,31 @@
+package scala.swing
+
+import javax.swing._
+import java.awt.event._
+import event._
+
+class TextArea(override val peer: JTextArea) extends TextComponent(peer) with TextComponent.HasColumns with TextComponent.HasRows {
+ def this(text: String, rows: Int, columns: int) = this(new JTextArea(text, rows, columns))
+ def this(text: String) = this(new JTextArea(text))
+ def this(rows: Int, columns: int) = this(new JTextArea(rows, columns))
+ def this() = this(new JTextArea())
+
+ // TODO: we could make contents StringBuilder-like
+ def append(t: String) { peer.append(t) }
+
+ def rows: Int = peer.getRows
+ def rows_=(n: Int) = peer.setRows(n)
+ def columns: Int = peer.getColumns
+ def columns_=(n: Int) = peer.setColumns(n)
+
+ def tabSize: Int = peer.getTabSize
+ def tabSize_=(n: Int) = peer.setTabSize(n)
+ def lineCount: Int = peer.getLineCount
+
+ def lineWrap: Boolean = peer.getLineWrap
+ def lineWrap_=(w: Boolean) = peer.setLineWrap(w)
+ def wordWrap: Boolean = peer.getWrapStyleWord
+ def wordWrap_=(w: Boolean) = peer.setWrapStyleWord(w)
+ def charWrap: Boolean = !peer.getWrapStyleWord
+ def charWrap_=(w: Boolean) = peer.setWrapStyleWord(!w)
+} \ No newline at end of file
diff --git a/src/swing/scala/swing/TextComponent.scala b/src/swing/scala/swing/TextComponent.scala
index ae496a5ba5..fb06cb4023 100644
--- a/src/swing/scala/swing/TextComponent.scala
+++ b/src/swing/scala/swing/TextComponent.scala
@@ -5,14 +5,29 @@ import javax.swing.text._
import javax.swing.event._
import event._
+object TextComponent {
+ trait HasColumns extends TextComponent {
+ def columns: Int
+ def columns_=(n: Int)
+ }
+ trait HasRows extends TextComponent {
+ def rows: Int
+ def rows_=(n: Int)
+ }
+}
+
class TextComponent(override val peer: JTextComponent) extends Component with EditorComponent with Publisher {
- def text: String = peer.getText
- def text_=(x: String) = peer.setText(x)
+ def contents: String = peer.getText
+ def contents_=(t: String) = peer.setText(t)
val caret = new Caret(peer.getCaret)
- def content: String = peer.getText
- def content_=(v: String) { peer.setText(v) }
+ def editable: Boolean = peer.isEditable
+ def editable_=(x: Boolean) = peer.setEditable(x)
+
+ def cut() { peer.cut() }
+ def copy() { peer.copy() }
+ def selected: String = peer.getSelectedText
peer.addCaretListener {
new CaretListener {
diff --git a/src/swing/scala/swing/TextField.scala b/src/swing/scala/swing/TextField.scala
index 7604d2719b..9658230608 100644
--- a/src/swing/scala/swing/TextField.scala
+++ b/src/swing/scala/swing/TextField.scala
@@ -4,14 +4,14 @@ import javax.swing._
import java.awt.event._
import event._
-class TextField(override val peer: JTextField) extends TextComponent(peer) {
+class TextField(override val peer: JTextField) extends TextComponent(peer) with TextComponent.HasColumns {
def this(text: String, columns: int) = this(new JTextField(text, columns))
def this(text: String) = this(new JTextField(text))
def this(columns: int) = this(new JTextField(columns))
def this() = this(new JTextField())
- def columns: int = peer.getColumns()
- def columns_=(x: int) = peer.setColumns(x)
+ def columns: Int = peer.getColumns
+ def columns_=(n: Int) = peer.setColumns(n)
override lazy val contentModified = new Publisher {
peer.addActionListener {
diff --git a/src/swing/scala/swing/ToggleButton.scala b/src/swing/scala/swing/ToggleButton.scala
new file mode 100644
index 0000000000..eebf3f3675
--- /dev/null
+++ b/src/swing/scala/swing/ToggleButton.scala
@@ -0,0 +1,9 @@
+package scala.swing
+
+import javax.swing._
+import event._
+
+class ToggleButton(override val peer: JToggleButton) extends Button(peer) {
+ def this(txt: String) = this(new JToggleButton(txt))
+ def this() = this(new JToggleButton)
+} \ No newline at end of file
diff --git a/src/swing/scala/swing/event/ButtonClicked.scala b/src/swing/scala/swing/event/ButtonClicked.scala
new file mode 100644
index 0000000000..cf826a6ff6
--- /dev/null
+++ b/src/swing/scala/swing/event/ButtonClicked.scala
@@ -0,0 +1,4 @@
+package scala.swing.event
+
+case class ButtonClicked(override val source: Button) extends ComponentEvent(source)
+
diff --git a/src/swing/scala/swing/event/ButtonPressed.scala b/src/swing/scala/swing/event/ButtonPressed.scala
deleted file mode 100644
index b0d7dc05c9..0000000000
--- a/src/swing/scala/swing/event/ButtonPressed.scala
+++ /dev/null
@@ -1,3 +0,0 @@
-package scala.swing.event
-
-case class ButtonPressed(override val source: Button) extends ComponentEvent(source)
diff --git a/src/swing/scala/swing/event/LiveEvent.scala b/src/swing/scala/swing/event/LiveEvent.scala
new file mode 100644
index 0000000000..a68a616f90
--- /dev/null
+++ b/src/swing/scala/swing/event/LiveEvent.scala
@@ -0,0 +1,5 @@
+package scala.swing.event
+
+trait LiveEvent {
+ def live: Boolean
+}
diff --git a/src/swing/scala/swing/event/MouseEvent.scala b/src/swing/scala/swing/event/MouseEvent.scala
index 52f6731d1a..20a520c3a6 100644
--- a/src/swing/scala/swing/event/MouseEvent.scala
+++ b/src/swing/scala/swing/event/MouseEvent.scala
@@ -1,5 +1,7 @@
package scala.swing.event
+import geometry._
+
class MouseEvent(source: Component, point: Point, modifiers: Int) extends ComponentEvent(source)
class MouseButtonEvent(source: Component, point: Point, modifiers: Int,
diff --git a/src/swing/scala/swing/event/SelectionEvent.scala b/src/swing/scala/swing/event/SelectionEvent.scala
new file mode 100644
index 0000000000..5fea0a6f57
--- /dev/null
+++ b/src/swing/scala/swing/event/SelectionEvent.scala
@@ -0,0 +1,5 @@
+package scala.swing.event
+
+trait SelectionEvent {
+ def range: Range
+}
diff --git a/src/swing/scala/swing/event/TableChanged.scala b/src/swing/scala/swing/event/TableChanged.scala
deleted file mode 100644
index 92a6cd5881..0000000000
--- a/src/swing/scala/swing/event/TableChanged.scala
+++ /dev/null
@@ -1,5 +0,0 @@
-package scala.swing.event
-
-case class TableChanged(override val source: Table, firstRow: Int, lastRow: Int, column: Int) extends ComponentEvent(source) {
- println("table changed: "+source+"/"+firstRow+"-"+lastRow+":"+column)
-}
diff --git a/src/swing/scala/swing/event/TableEvent.scala b/src/swing/scala/swing/event/TableEvent.scala
new file mode 100644
index 0000000000..4a556fed20
--- /dev/null
+++ b/src/swing/scala/swing/event/TableEvent.scala
@@ -0,0 +1,10 @@
+package scala.swing.event
+
+class TableEvent(override val source: Table) extends ComponentEvent(source)
+
+case class TableChanged(override val source: Table, firstRow: Int, lastRow: Int, column: Int) extends TableEvent(source)
+case class TableResized(override val source: Table) extends TableEvent(source)
+//case class TextModified(override val source: TextComponent) extends ContentModified(source)
+
+case class ColumnsSelected(override val source: Table, live: Boolean, range: Range) extends TableEvent(source) with LiveEvent with SelectionEvent
+case class RowsSelected(override val source: Table, live: Boolean, range: Range) extends TableEvent(source) with LiveEvent with SelectionEvent \ No newline at end of file
diff --git a/src/swing/scala/swing/event/TableResized.scala b/src/swing/scala/swing/event/TableResized.scala
deleted file mode 100644
index c2d03dfa91..0000000000
--- a/src/swing/scala/swing/event/TableResized.scala
+++ /dev/null
@@ -1,3 +0,0 @@
-package scala.swing.event
-
-case class TableResized(override val source: Table) extends ComponentEvent(source)
diff --git a/src/swing/scala/swing/Dimension.scala b/src/swing/scala/swing/geometry/Dimension.scala
index 872f2022b2..abe48f8c0a 100644
--- a/src/swing/scala/swing/Dimension.scala
+++ b/src/swing/scala/swing/geometry/Dimension.scala
@@ -1,4 +1,4 @@
-package scala.swing
+package scala.swing.geometry
object Dimension {
def apply(w: Int, h: Int) = new Dimension {
diff --git a/src/swing/scala/swing/Point.scala b/src/swing/scala/swing/geometry/Point.scala
index 953f6bf3ab..352afb5985 100644
--- a/src/swing/scala/swing/Point.scala
+++ b/src/swing/scala/swing/geometry/Point.scala
@@ -1,4 +1,4 @@
-package scala.swing
+package scala.swing.geometry
object Point {
def apply(p: java.awt.Point) = new Point(p.getX, p.getY)
diff --git a/src/swing/scala/swing/geometry/Rectangle.scala b/src/swing/scala/swing/geometry/Rectangle.scala
new file mode 100644
index 0000000000..707c99a3a1
--- /dev/null
+++ b/src/swing/scala/swing/geometry/Rectangle.scala
@@ -0,0 +1,19 @@
+package scala.swing.geometry
+
+object Rectangle {
+ def apply(x: Int, y: Int, w: Int, h: Int) = new Rectangle {
+ lazy val peer: java.awt.Rectangle = new java.awt.Rectangle(x, y, w, h)
+ }
+
+ def wrap(rect: java.awt.Rectangle) = new Rectangle {
+ def peer: java.awt.Rectangle = rect
+ }
+}
+
+abstract class Rectangle {
+ def peer: java.awt.Rectangle
+ def width = peer.getWidth
+ def height = peer.getHeight
+ def x = peer.x
+ def y = peer.y
+}
diff --git a/src/swing/scala/swing/model/Matrix.scala b/src/swing/scala/swing/model/Matrix.scala
index 6342d65dc7..a578452fd2 100644
--- a/src/swing/scala/swing/model/Matrix.scala
+++ b/src/swing/scala/swing/model/Matrix.scala
@@ -1,6 +1,6 @@
package scala.swing.model
-trait Matrix[A]extends Function2[Int, Int, A] {
+trait Matrix[A] extends Function2[Int, Int, A] {
val width: Int
val height: Int
diff --git a/src/swing/scala/swing/test/CelsiusConverter.scala b/src/swing/scala/swing/test/CelsiusConverter.scala
index b1aef5f077..9cd6092f31 100644
--- a/src/swing/scala/swing/test/CelsiusConverter.scala
+++ b/src/swing/scala/swing/test/CelsiusConverter.scala
@@ -14,7 +14,7 @@ object CelsiusConverter extends SimpleGUIApplication {
text = "Celsius"
border = EmptyBorder(5, 5, 5, 5)
}
- object convertButton extends Button {
+ object convertButton extends PushButton {
icon = new javax.swing.ImageIcon("c:\\workspace\\gui\\images\\convert.gif")
border = EmptyBorder(5, 5, 5, 5)
}
@@ -23,13 +23,14 @@ object CelsiusConverter extends SimpleGUIApplication {
border = EmptyBorder(5, 5, 5, 5)
listenTo(convertButton, tempCelsius)
reactions += {
- case ButtonPressed(_) | ContentModified(_) =>
- val c = Integer.parseInt(tempCelsius.text)
+ case ButtonClicked(_) | ContentModified(_) =>
+ val c = Integer.parseInt(tempCelsius.contents)
val f = c * 9 / 5 + 32
text = "<html><font color = red>"+f+"</font> Fahrenheit</html>"
}
}
- content = new GridPanel(2,2)(tempCelsius, celsiusLabel, convertButton, fahrenheitLabel) {
+ content = new GridPanel(2,2) {
+ contents.append(tempCelsius, celsiusLabel, convertButton, fahrenheitLabel)
border = EmptyBorder(10, 10, 10, 10)
}
}
diff --git a/src/swing/scala/swing/test/CelsiusConverter2.scala b/src/swing/scala/swing/test/CelsiusConverter2.scala
index d19ce9e4e4..5b8af8f5c0 100644
--- a/src/swing/scala/swing/test/CelsiusConverter2.scala
+++ b/src/swing/scala/swing/test/CelsiusConverter2.scala
@@ -8,20 +8,20 @@ object CelsiusConverter2 extends SimpleGUIApplication {
title = "Convert Celsius / Fahrenheit"
object Celsius extends TextField { columns = 5 }
object Fahrenheit extends TextField { columns = 5 }
- content = new FlowPanel(Horizontal)(Celsius, new Label(" Celsius = "),
- Fahrenheit, new Label(" Fahrenheit")) {
+ content = new FlowPanel {
+ contents.append(Celsius, new Label(" Celsius = "), Fahrenheit, new Label(" Fahrenheit"))
border = EmptyBorder(15, 10, 10, 10)
}
listenTo(Fahrenheit.contentModified, Celsius.contentModified)
reactions += {
case ContentModified(Fahrenheit) =>
- val f = Integer.parseInt(Fahrenheit.text)
+ val f = Integer.parseInt(Fahrenheit.contents)
val c = (f - 32) * 5 / 9
- Celsius.text = c.toString
+ Celsius.contents = c.toString
case ContentModified(Celsius) =>
- val c = Integer.parseInt(Celsius.text)
+ val c = Integer.parseInt(Celsius.contents)
val f = c * 9 / 5 + 32
- Fahrenheit.text = f.toString
+ Fahrenheit.contents = f.toString
}
}
}
diff --git a/src/swing/scala/swing/test/GridBagDemo.scala b/src/swing/scala/swing/test/GridBagDemo.scala
new file mode 100644
index 0000000000..2131d0c82e
--- /dev/null
+++ b/src/swing/scala/swing/test/GridBagDemo.scala
@@ -0,0 +1,62 @@
+package scala.swing.test
+
+import swing._
+import swing.event._
+import GridBagPanel._
+import java.awt.Insets
+
+object GridBagDemo extends SimpleGUIApplication {
+ def top = new MainFrame {
+ title = "GridBag Demo"
+ content = new GridBagPanel {
+ val c = new Constraints
+ val shouldFill = true
+ if (shouldFill) {
+ c.fill = Fill.Horizontal
+ }
+
+ val button1 = new PushButton("Button 1")
+
+ c.weightx = 0.5
+
+ c.fill = Fill.Horizontal
+ c.gridx = 0;
+ c.gridy = 0;
+ layout(button1) = c
+
+ val button2 = new PushButton("Button 2")
+ c.fill = Fill.Horizontal
+ c.weightx = 0.5;
+ c.gridx = 1;
+ c.gridy = 0;
+ layout(button2) = c
+
+ val button3 = new PushButton("Button 3")
+ c.fill = Fill.Horizontal
+ c.weightx = 0.5;
+ c.gridx = 2;
+ c.gridy = 0;
+ layout(button3) = c
+
+ val button4 = new PushButton("Long-Named Button 4")
+ c.fill = Fill.Horizontal
+ c.ipady = 40; //make this component tall
+ c.weightx = 0.0;
+ c.gridwidth = 3;
+ c.gridx = 0;
+ c.gridy = 1;
+ layout(button4) = c
+
+ val button5 = new PushButton("5")
+ c.fill = Fill.Horizontal
+ c.ipady = 0; //reset to default
+ c.weighty = 1.0; //request any extra vertical space
+ c.anchor = Anchor.PageEnd
+ c.insets = new Insets(10,0,0,0); //top padding
+ c.gridx = 1; //aligned with button 2
+ c.gridwidth = 2; //2 columns wide
+ c.gridy = 2; //third row
+ layout(button5) = c
+ }
+ }
+} \ No newline at end of file
diff --git a/src/swing/scala/swing/test/MenuDemo.scala b/src/swing/scala/swing/test/MenuDemo.scala
new file mode 100644
index 0000000000..fb407503d5
--- /dev/null
+++ b/src/swing/scala/swing/test/MenuDemo.scala
@@ -0,0 +1,32 @@
+package scala.swing.test
+
+import swing._
+import swing.event._
+
+object MenuDemo extends SimpleGUIApplication {
+ def top = new MainFrame {
+ title = "Menu Demo"
+ menuBar = new MenuBar
+
+ implicit def action2MenuItem(a: Action): MenuItem = new MenuItem(a)
+
+ val menu = new Menu("A Menu")
+ menu.contents += new MenuItem("An item")
+ menu.contents += new Action("An action item") {
+ def apply() { println("Action '"+ title +"' invoked") }
+ }
+ menu.contents += new Separator
+ menu.contents += new CheckMenuItem("Check me")
+ menu.contents += new CheckMenuItem("Me too!")
+ menu.contents += new Separator
+ val a = new RadioMenuItem("a")
+ val b = new RadioMenuItem("b")
+ val c = new RadioMenuItem("b")
+ val mutex = new ButtonMutex(a,b,c)
+ menu.contents ++= mutex.buttons
+
+ menuBar.contents += menu
+ menuBar.contents += new Menu("Empty Menu")
+ }
+}
+
diff --git a/src/swing/scala/swing/test/SimpleApplet.scala b/src/swing/scala/swing/test/SimpleApplet.scala
index c42bc873eb..f072a617d6 100644
--- a/src/swing/scala/swing/test/SimpleApplet.scala
+++ b/src/swing/scala/swing/test/SimpleApplet.scala
@@ -5,15 +5,15 @@ import event._
class SimpleApplet extends Applet {
object ui extends UI with Reactor {
def init() = {
- val button = new Button("Press here!")
+ val button = new PushButton("Press here!")
val text = new TextField("Java Version: " +
System.getProperty("java.version")+"\n")
listenTo(button)
reactions += {
- case ButtonPressed(_) => text.content += "Button Pressed!\n"
+ case ButtonClicked(_) => text.contents += "Button Pressed!\n"
case _ =>
}
- content = new BoxPanel(Vertical)(button, text)
+ content = new BoxPanel(Vertical) { contents.append(button, text) }
}
}
} \ No newline at end of file
diff --git a/src/swing/scala/swing/test/SwingApp.scala b/src/swing/scala/swing/test/SwingApp.scala
index 3be407411a..5560c74f59 100644
--- a/src/swing/scala/swing/test/SwingApp.scala
+++ b/src/swing/scala/swing/test/SwingApp.scala
@@ -12,15 +12,16 @@ object SwingApp extends SimpleGUIApplication {
text = prefix + "0 "
listenTo(button)
reactions += {
- case ButtonPressed(button) =>
+ case ButtonClicked(button) =>
numclicks = numclicks + 1
text = prefix + numclicks
}
}
- object button extends Button {
+ object button extends PushButton {
text = "I am a button"
}
- content = new GridPanel(GridPanel.Adapt,1)(label, button) {
+ content = new GridPanel(GridPanel.Adapt,1) {
+ contents.append(label, button)
border = EmptyBorder(5, 5, 5, 5)
}
}
diff --git a/src/swing/scala/swing/test/TableSelection.scala b/src/swing/scala/swing/test/TableSelection.scala
new file mode 100644
index 0000000000..2e454144dd
--- /dev/null
+++ b/src/swing/scala/swing/test/TableSelection.scala
@@ -0,0 +1,99 @@
+package scala.swing.test
+
+import swing._
+import swing.event._
+import swing.geometry._
+
+object TableSelection extends SimpleGUIApplication {
+ def top = new MainFrame {
+ title = "Table Selection"
+
+ val model = Array[Array[AnyRef]](Array[AnyRef]("Mary", "Campione", "Snowboarding", new java.lang.Integer(5), new java.lang.Boolean(false)),
+ Array[AnyRef]("Alison", "Huml", "Rowing", new java.lang.Integer(5), new java.lang.Boolean(false)),
+ Array[AnyRef]("Kathy", "Walrath", "Knitting", new java.lang.Integer(5), new java.lang.Boolean(false)),
+ Array[AnyRef]("Sharon", "Zakhour", "Speed reading", new java.lang.Integer(5), new java.lang.Boolean(false)),
+ Array[AnyRef]("Philip", "Milne", "Pool", new java.lang.Integer(5), new java.lang.Boolean(false)))
+
+ content = new BoxPanel(Vertical) {
+ val table = new Table(model, Array[AnyRef]("First Name", "Last Name", "Sport", "# of Years", "Vegetarian"))
+ listenTo()
+ table.preferredViewportSize = Dimension(500, 70)
+ table.fillsViewportHeight = true
+ listenTo(table.selection)
+
+ contents += new ScrollPane(table)
+
+ contents += new Label("Selection Mode")
+ val intervalMutex = new ButtonMutex
+ def radio(mutex: ButtonMutex, text: String): RadioButton = {
+ val b = new RadioButton(text)
+ listenTo(b)
+ mutex.buttons += b
+ contents += b
+ b
+ }
+ val multiInterval = radio(intervalMutex, "Multiple Interval Selection")
+ val elementInterval = radio(intervalMutex, "Single Selection")
+ val singleInterval = radio(intervalMutex, "Single Interval Selection")
+
+ contents += new Label("Selection Options")
+ val elemMutex = new ButtonMutex
+ val rowSelection = radio(elemMutex, "Row Selection")
+ val columnSelection = radio(elemMutex, "Column Selection")
+ val cellSelection = radio(elemMutex, "Cell Selection")
+
+ val output = new TextArea(5, 40) { editable = false }
+ contents += new ScrollPane(output)
+
+ def outputSelection() {
+ output.append("Lead: " + table.selection.rows.leadIndex + "," +
+ table.selection.columns.leadIndex + ". ")
+ output.append("Rows:")
+ for (c <- table.selection.rows) output.append(" " + c)
+ output.append(". Columns:")
+ for (c <- table.selection.columns) output.append(" " + c)
+ output.append(".\n")
+ }
+ reactions += {
+ case ButtonClicked(_) =>
+ rowSelection.selected = table.selection.elementMode == Table.ElementMode.Row
+ columnSelection.selected = table.selection.elementMode == Table.ElementMode.Column
+ if (cellSelection.enabled) {
+ cellSelection.selected = table.selection.elementMode == Table.ElementMode.Cell
+ }
+ }
+
+ reactions += {
+ case ButtonClicked(`multiInterval`) =>
+ table.selection.intervalMode = Table.IntervalMode.MultiInterval
+ if (cellSelection.selected) {
+ elemMutex.deselectAll()
+ table.selection.elementMode = Table.ElementMode.None
+ }
+ cellSelection.enabled = false
+ case ButtonClicked(`elementInterval`) =>
+ table.selection.intervalMode = Table.IntervalMode.SingleInterval
+ cellSelection.enabled = true
+ case ButtonClicked(`singleInterval`) =>
+ table.selection.intervalMode = Table.IntervalMode.Single
+ cellSelection.enabled = true
+ case ButtonClicked(`rowSelection`) =>
+ if (rowSelection.selected)
+ table.selection.elementMode = Table.ElementMode.Row
+ case ButtonClicked(`columnSelection`) =>
+ if (columnSelection.selected)
+ table.selection.elementMode = Table.ElementMode.Column
+ case ButtonClicked(`cellSelection`) =>
+ if (cellSelection.selected)
+ table.selection.elementMode = Table.ElementMode.Cell
+ case RowsSelected(table, false, range) =>
+ output.append("Rows selected, changes: " + range + "\n")
+ outputSelection()
+ case ColumnsSelected(table, false, range) =>
+ output.append("Columns selected, changes " + range + "\n")
+ outputSelection()
+ }
+ }
+ }
+}
+