From b0706ef600ea3cb51ebd2c188cd2346d6a4b4d9b Mon Sep 17 00:00:00 2001 From: Ingo Maier Date: Wed, 8 Jul 2009 14:58:16 +0000 Subject: TextField installs it's listener lazily now --- src/swing/scala/swing/Table.scala | 5 +- src/swing/scala/swing/TextField.scala | 19 +++- src/swing/scala/swing/event/InputEvent.scala | 2 +- src/swing/scala/swing/event/Key.scala | 5 + src/swing/scala/swing/event/KeyEvent.scala | 6 +- src/swing/scala/swing/event/MouseEvent.scala | 16 +-- src/swing/scala/swing/event/SelectionEvent.scala | 8 +- src/swing/scala/swing/test/TableSelection.scala | 137 +++++++++++------------ 8 files changed, 106 insertions(+), 92 deletions(-) (limited to 'src/swing') diff --git a/src/swing/scala/swing/Table.scala b/src/swing/scala/swing/Table.scala index 9796b6b58f..80d8ce70f6 100644 --- a/src/swing/scala/swing/Table.scala +++ b/src/swing/scala/swing/Table.scala @@ -16,7 +16,7 @@ import javax.swing.table._ import javax.swing.event._ import java.awt.{Dimension, Color} import event._ -import scala.collection.mutable.Set +import scala.collection.mutable.{Set, Vector} object Table { object AutoResizeMode extends Enumeration { @@ -122,7 +122,8 @@ class Table extends Component with Scrollable with Publisher { } import Table._ - def this(rowData: Array[Array[Any]], columnNames: Seq[Any]) = { + // TODO: use Vector[_ <: Vector[Any]], see ticket #2005 + def this(rowData: Array[Array[Any]], columnNames: Seq[_]) = { this() peer.setModel(new AbstractTableModel { override def getColumnName(column: Int) = columnNames(column).toString diff --git a/src/swing/scala/swing/TextField.scala b/src/swing/scala/swing/TextField.scala index 3d068bb7f7..201a97b724 100644 --- a/src/swing/scala/swing/TextField.scala +++ b/src/swing/scala/swing/TextField.scala @@ -39,13 +39,22 @@ class TextField(text0: String, columns0: Int) extends TextComponent with TextCom def columns: Int = peer.getColumns def columns_=(n: Int) = peer.setColumns(n) - peer.addActionListener(Swing.ActionListener { e => + private lazy val actionListener = Swing.ActionListener { e => publish(EditDone(TextField.this)) - }) + } - peer.addFocusListener(new FocusAdapter { - override def focusLost(e: java.awt.event.FocusEvent) { publish(EditDone(TextField.this)) } - }) + override def onFirstSubscribe { + super.onFirstSubscribe + peer.addActionListener(actionListener) + peer.addFocusListener(new FocusAdapter { + override def focusLost(e: java.awt.event.FocusEvent) { publish(EditDone(TextField.this)) } + }) + } + + override def onLastUnsubscribe { + super.onLastUnsubscribe + peer.removeActionListener(actionListener) + } def verifier: String => Boolean = s => peer.getInputVerifier.verify(peer) def verifier_=(v: String => Boolean) { diff --git a/src/swing/scala/swing/event/InputEvent.scala b/src/swing/scala/swing/event/InputEvent.scala index e29d04d954..561518a9a1 100644 --- a/src/swing/scala/swing/event/InputEvent.scala +++ b/src/swing/scala/swing/event/InputEvent.scala @@ -14,7 +14,7 @@ package scala.swing.event trait InputEvent extends ComponentEvent { def peer: java.awt.event.InputEvent def when: Long = peer.getWhen - def modifiers: Int + def modifiers: Key.Modifiers def consume() { peer.consume() } def consumed: Boolean = peer.isConsumed } diff --git a/src/swing/scala/swing/event/Key.scala b/src/swing/scala/swing/event/Key.scala index e0880409e2..c2e8ef3515 100644 --- a/src/swing/scala/swing/event/Key.scala +++ b/src/swing/scala/swing/event/Key.scala @@ -11,6 +11,9 @@ package scala.swing.event +/** + * Enumeration of key codes used by key events. + */ object Key extends Enumeration { import java.awt.event.KeyEvent._ @@ -22,6 +25,8 @@ object Key extends Enumeration { val Unknown = Value(java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN) } + type Modifiers = Int + object Modifier { import java.awt.event.InputEvent._ val Shift = SHIFT_DOWN_MASK diff --git a/src/swing/scala/swing/event/KeyEvent.scala b/src/swing/scala/swing/event/KeyEvent.scala index ddb8d57997..5745a4f7d1 100644 --- a/src/swing/scala/swing/event/KeyEvent.scala +++ b/src/swing/scala/swing/event/KeyEvent.scala @@ -17,7 +17,7 @@ sealed abstract class KeyEvent extends InputEvent { def peer: java.awt.event.KeyEvent } -case class KeyTyped(val source: Component, char: Char, val modifiers: Int, +case class KeyTyped(val source: Component, char: Char, val modifiers: Key.Modifiers, location: Key.Location.Value) (val peer: java.awt.event.KeyEvent) extends KeyEvent { def this(e: java.awt.event.KeyEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), @@ -25,14 +25,14 @@ case class KeyTyped(val source: Component, char: Char, val modifiers: Int, Key.Location(e.getKeyLocation))(e) } -case class KeyPressed(val source: Component, key: Key.Value, val modifiers: Int, +case class KeyPressed(val source: Component, key: Key.Value, val modifiers: Key.Modifiers, location: Key.Location.Value) (val peer: java.awt.event.KeyEvent) extends KeyEvent { def this(e: java.awt.event.KeyEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), Key(e.getKeyCode), e.getModifiersEx, Key.Location(e.getKeyLocation))(e) } -case class KeyReleased(val source: Component, key: Key.Value, val modifiers: Int, +case class KeyReleased(val source: Component, key: Key.Value, val modifiers: Key.Modifiers, location: Key.Location.Value) (val peer: java.awt.event.KeyEvent) extends KeyEvent { def this(e: java.awt.event.KeyEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), diff --git a/src/swing/scala/swing/event/MouseEvent.scala b/src/swing/scala/swing/event/MouseEvent.scala index 51af9ba304..a41e5a92ae 100644 --- a/src/swing/scala/swing/event/MouseEvent.scala +++ b/src/swing/scala/swing/event/MouseEvent.scala @@ -23,19 +23,19 @@ sealed abstract class MouseButtonEvent extends MouseEvent { def clicks: Int def triggersPopup: Boolean } -case class MouseClicked(val source: Component, point: Point, val modifiers: Int, +case class MouseClicked(val source: Component, point: Point, val modifiers: Key.Modifiers, clicks: Int, triggersPopup: Boolean)(val peer: java.awt.event.MouseEvent) extends MouseButtonEvent { def this(e: java.awt.event.MouseEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), e.getPoint, e.getModifiersEx, e.getClickCount, e.isPopupTrigger)(e) } -case class MousePressed(val source: Component, point: Point, val modifiers: Int, +case class MousePressed(val source: Component, point: Point, val modifiers: Key.Modifiers, clicks: Int, triggersPopup: Boolean)(val peer: java.awt.event.MouseEvent) extends MouseButtonEvent { def this(e: java.awt.event.MouseEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), e.getPoint, e.getModifiersEx, e.getClickCount, e.isPopupTrigger)(e) } -case class MouseReleased(val source: Component, point: Point, val modifiers: Int, +case class MouseReleased(val source: Component, point: Point, val modifiers: Key.Modifiers, clicks: Int, triggersPopup: Boolean)(val peer: java.awt.event.MouseEvent) extends MouseButtonEvent { def this(e: java.awt.event.MouseEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), @@ -43,28 +43,28 @@ case class MouseReleased(val source: Component, point: Point, val modifiers: Int } sealed abstract class MouseMotionEvent extends MouseEvent -case class MouseMoved(val source: Component, point: Point, val modifiers: Int)(val peer: java.awt.event.MouseEvent) +case class MouseMoved(val source: Component, point: Point, val modifiers: Key.Modifiers)(val peer: java.awt.event.MouseEvent) extends MouseMotionEvent { def this(e: java.awt.event.MouseEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), e.getPoint, e.getModifiersEx)(e) } -case class MouseDragged(val source: Component, point: Point, val modifiers: Int)(val peer: java.awt.event.MouseEvent) +case class MouseDragged(val source: Component, point: Point, val modifiers: Key.Modifiers)(val peer: java.awt.event.MouseEvent) extends MouseMotionEvent { def this(e: java.awt.event.MouseEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), e.getPoint, e.getModifiersEx)(e) } -case class MouseEntered(val source: Component, point: Point, val modifiers: Int)(val peer: java.awt.event.MouseEvent) +case class MouseEntered(val source: Component, point: Point, val modifiers: Key.Modifiers)(val peer: java.awt.event.MouseEvent) extends MouseMotionEvent { def this(e: java.awt.event.MouseEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), e.getPoint, e.getModifiersEx)(e) } -case class MouseExited(val source: Component, point: Point, val modifiers: Int)(val peer: java.awt.event.MouseEvent) +case class MouseExited(val source: Component, point: Point, val modifiers: Key.Modifiers)(val peer: java.awt.event.MouseEvent) extends MouseMotionEvent { def this(e: java.awt.event.MouseEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), e.getPoint, e.getModifiersEx)(e) } -case class MouseWheelMoved(val source: Component, point: Point, val modifiers: Int, rotation: Int)(val peer: java.awt.event.MouseEvent) +case class MouseWheelMoved(val source: Component, point: Point, val modifiers: Key.Modifiers, rotation: Int)(val peer: java.awt.event.MouseEvent) extends MouseEvent { def this(e: java.awt.event.MouseWheelEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), e.getPoint, e.getModifiersEx, e.getWheelRotation)(e) diff --git a/src/swing/scala/swing/event/SelectionEvent.scala b/src/swing/scala/swing/event/SelectionEvent.scala index 41f149f146..48ee31b4ed 100644 --- a/src/swing/scala/swing/event/SelectionEvent.scala +++ b/src/swing/scala/swing/event/SelectionEvent.scala @@ -11,8 +11,14 @@ package scala.swing.event -trait SelectionEvent extends ComponentEvent +/** + * An event that indicates a change in a selection such as in a list view or a table. + */ +trait SelectionEvent +/** + * An event that indicates a selection of a range of indices. + */ trait ListSelectionEvent extends SelectionEvent { def range: Range } diff --git a/src/swing/scala/swing/test/TableSelection.scala b/src/swing/scala/swing/test/TableSelection.scala index e7218da9be..828f772085 100644 --- a/src/swing/scala/swing/test/TableSelection.scala +++ b/src/swing/scala/swing/test/TableSelection.scala @@ -17,88 +17,81 @@ object TableSelection extends SimpleGUIApplication { lazy val ui = new BoxPanel(Orientation.Vertical) { val table = new Table(model, Array("First Name", "Last Name", "Sport", "# of Years", "Vegetarian")) { preferredViewportSize = new Dimension(500, 70) - val l = new Table.LabelRenderer[String] - override def rendererComponent(isSelected: Boolean, focused: Boolean, row: Int, column: Int): Component = - this(row, column) match { - case s: String => l.componentFor(this, isSelected, focused, s, row, column) - case _ => super.rendererComponent(isSelected, focused, row, column) - } - } - //1.6:table.fillsViewportHeight = true - listenTo(table.selection) + } + //1.6:table.fillsViewportHeight = true + listenTo(table.selection) - contents += new ScrollPane(table) - contents += new Label("Selection Mode") + contents += new ScrollPane(table) + contents += new Label("Selection Mode") - def radio(mutex: ButtonGroup, text: String): RadioButton = { - val b = new RadioButton(text) - listenTo(b) - mutex.buttons += b - contents += b - b - } + def radio(mutex: ButtonGroup, text: String): RadioButton = { + val b = new RadioButton(text) + listenTo(b) + mutex.buttons += b + contents += b + b + } - val intervalMutex = new ButtonGroup - val multiInterval = radio(intervalMutex, "Multiple Interval Selection") - val elementInterval = radio(intervalMutex, "Single Selection") - val singleInterval = radio(intervalMutex, "Single Interval Selection") - intervalMutex.select(multiInterval) + val intervalMutex = new ButtonGroup + val multiInterval = radio(intervalMutex, "Multiple Interval Selection") + val elementInterval = radio(intervalMutex, "Single Selection") + val singleInterval = radio(intervalMutex, "Single Interval Selection") + intervalMutex.select(multiInterval) - contents += new Label("Selection Options") - val elemMutex = new ButtonGroup - val rowSelection = radio(elemMutex, "Row Selection") - val columnSelection = radio(elemMutex, "Column Selection") - val cellSelection = radio(elemMutex, "Cell Selection") - elemMutex.select(rowSelection) + contents += new Label("Selection Options") + val elemMutex = new ButtonGroup + val rowSelection = radio(elemMutex, "Row Selection") + val columnSelection = radio(elemMutex, "Column Selection") + val cellSelection = radio(elemMutex, "Cell Selection") + elemMutex.select(rowSelection) - val output = new TextArea(5, 40) { editable = false } - contents += new ScrollPane(output) + 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") - } + 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(`multiInterval`) => - table.selection.intervalMode = Table.IntervalMode.MultiInterval - if (cellSelection.selected) { - elemMutex.select(rowSelection) - table.selection.elementMode = Table.ElementMode.None - } - cellSelection.enabled = false - case ButtonClicked(`elementInterval`) => - table.selection.intervalMode = Table.IntervalMode.Single - cellSelection.enabled = true - case ButtonClicked(`singleInterval`) => - table.selection.intervalMode = Table.IntervalMode.SingleInterval - 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 TableRowsSelected(_, range, false) => - output.append("Rows selected, changes: " + range + "\n") - outputSelection() - case TableColumnsSelected(_, range, false) => - output.append("Columns selected, changes " + range + "\n") - outputSelection() - } + reactions += { + case ButtonClicked(`multiInterval`) => + table.selection.intervalMode = Table.IntervalMode.MultiInterval + if (cellSelection.selected) { + elemMutex.select(rowSelection) + table.selection.elementMode = Table.ElementMode.None + } + cellSelection.enabled = false + case ButtonClicked(`elementInterval`) => + table.selection.intervalMode = Table.IntervalMode.Single + cellSelection.enabled = true + case ButtonClicked(`singleInterval`) => + table.selection.intervalMode = Table.IntervalMode.SingleInterval + 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 TableRowsSelected(_, range, false) => + output.append("Rows selected, changes: " + range + "\n") + outputSelection() + case TableColumnsSelected(_, range, false) => + output.append("Columns selected, changes " + range + "\n") + outputSelection() + } } def top = new MainFrame { title = "Table Selection" contents = ui } -} - +} \ No newline at end of file -- cgit v1.2.3