From 35c590828cd7265d4b9d1e5384cd87a913ebdeaa Mon Sep 17 00:00:00 2001 From: Ingo Maier Date: Fri, 21 Aug 2009 13:04:22 +0000 Subject: Applied some of Kevin Wright's patches. --- src/swing/scala/swing/Adjustable.scala | 53 +++++++++++++++++++++++++++++++ src/swing/scala/swing/Component.scala | 6 ++-- src/swing/scala/swing/EditorPane.scala | 33 +++++++++++++++++++ src/swing/scala/swing/ListView.scala | 3 +- src/swing/scala/swing/Orientable.scala | 8 ++++- src/swing/scala/swing/Orientation.scala | 3 +- src/swing/scala/swing/Oriented.scala | 26 ++++++++++----- src/swing/scala/swing/ProgressBar.scala | 6 ++-- src/swing/scala/swing/ScrollBar.scala | 40 +++++++++++++++++++++++ src/swing/scala/swing/ScrollPane.scala | 4 ++- src/swing/scala/swing/Scrollable.scala | 32 +++++++++++++------ src/swing/scala/swing/Separator.scala | 4 +-- src/swing/scala/swing/Slider.scala | 5 ++- src/swing/scala/swing/SplitPane.scala | 6 ++-- src/swing/scala/swing/Table.scala | 2 +- src/swing/scala/swing/TextComponent.scala | 5 +++ src/swing/scala/swing/UIElement.scala | 21 ++++++++---- 17 files changed, 213 insertions(+), 44 deletions(-) create mode 100644 src/swing/scala/swing/Adjustable.scala create mode 100644 src/swing/scala/swing/EditorPane.scala create mode 100644 src/swing/scala/swing/ScrollBar.scala (limited to 'src/swing') diff --git a/src/swing/scala/swing/Adjustable.scala b/src/swing/scala/swing/Adjustable.scala new file mode 100644 index 0000000000..97fe5103c2 --- /dev/null +++ b/src/swing/scala/swing/Adjustable.scala @@ -0,0 +1,53 @@ +package scala.swing + +import java.awt.{Adjustable => JAdjustable} + +object Adjustable { + trait Wrapper extends Oriented.Wrapper with Adjustable { + def peer: JAdjustable with OrientedMixin + + def unitIncrement = peer.getUnitIncrement + def unitIncrement_=(i: Int) = peer.setUnitIncrement(i) + def blockIncrement = peer.getBlockIncrement + def blockIncrement_=(i: Int) = peer.setBlockIncrement(i) + + def value = peer.getValue + def value_=(v: Int) = peer.setValue(v) + + def visibleAmount = peer.getVisibleAmount + def visibleAmount_=(v: Int) = peer.setVisibleAmount(v) + + def minimum = peer.getMinimum + def minimum_=(m: Int) = peer.setMinimum(m) + def maximum = peer.getMaximum + def maximum_=(m: Int) = peer.setMaximum(m) + } +} + +trait Adjustable extends Oriented { + def unitIncrement: Int + def unitIncrement_=(i: Int) + def blockIncrement: Int + def blockIncrement_=(i: Int) + + def value: Int + def value_=(v : Int) + + def visibleAmount: Int + def visibleAmount_=(v: Int) + + def minimum: Int + def minimum_=(m: Int) + def maximum: Int + def maximum_=(m: Int) + +// Needs implementation of AdjustmentEvent +// +// val adjustments: Publisher = new Publisher { +// peer.addAdjustmentListener(new AdjustmentListener { +// def adjustmentValueChanged(e: java.awt.event.AdjustmentEvent) { +// publish(new AdjustmentEvent(e)) +// } +// }) +// } +} \ No newline at end of file diff --git a/src/swing/scala/swing/Component.scala b/src/swing/scala/swing/Component.scala index ed975897b7..dd0f04086e 100644 --- a/src/swing/scala/swing/Component.scala +++ b/src/swing/scala/swing/Component.scala @@ -25,8 +25,10 @@ object Component { /** * Wraps a given Java Swing Component into a new wrapper. */ - def wrap(c: JComponent): Component = new Component { - override lazy val peer = c + def wrap(c: JComponent): Component = { + val w = UIElement.cachedWrapper[Component](c) + if (w != null) w + else new Component { override lazy val peer = c } } } diff --git a/src/swing/scala/swing/EditorPane.scala b/src/swing/scala/swing/EditorPane.scala new file mode 100644 index 0000000000..79777a1f34 --- /dev/null +++ b/src/swing/scala/swing/EditorPane.scala @@ -0,0 +1,33 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2007-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: EditorPane.scala $ + +package scala.swing + +import javax.swing._ +import javax.swing.text._ +import java.awt.Color +import java.awt.event._ +import event._ + +/** + * A text component that allows multiline text input and display. + * + * @see javax.swing.JEditorPane + */ +class EditorPane(contentType0: String, text0: String) extends TextComponent { + override lazy val peer: JEditorPane = new JEditorPane(contentType0, text0) with SuperMixin {} + def this() = this("text/plain", "") + + def contentType: String = peer.getContentType + def contentType_=(t: String) = peer.setContentType(t) + + def editorKit: EditorKit = peer.getEditorKit + def editorKit_=(k: EditorKit) = peer.setEditorKit(k) +} \ No newline at end of file diff --git a/src/swing/scala/swing/ListView.scala b/src/swing/scala/swing/ListView.scala index 8c84ac5514..11b4a72441 100644 --- a/src/swing/scala/swing/ListView.scala +++ b/src/swing/scala/swing/ListView.scala @@ -128,8 +128,7 @@ object ListView { override lazy val peer: ListCellRenderer = new DefaultListCellRenderer def componentFor(list: ListView[_], isSelected: Boolean, focused: Boolean, a: Any, index: Int): Component = { val c = peer.getListCellRendererComponent(list.peer, a, index, isSelected, focused).asInstanceOf[JComponent] - val w = UIElement.cachedWrapper[Component](c) - if (w eq null) Component.wrap(c) else w + Component.wrap(c) } } } diff --git a/src/swing/scala/swing/Orientable.scala b/src/swing/scala/swing/Orientable.scala index 79eaf362bb..fb89e47e29 100644 --- a/src/swing/scala/swing/Orientable.scala +++ b/src/swing/scala/swing/Orientable.scala @@ -11,9 +11,15 @@ package scala.swing +object Orientable { + trait Wrapper extends Oriented.Wrapper with Orientable { + def orientation_=(o: Orientation.Value) { peer.setOrientation(o.id) } + } +} + /** * An Oriented whose orientation can be changed. */ trait Orientable extends Oriented { - def orientation_=(o: Orientation.Value) { peer.setOrientation(o.id) } + def orientation_=(o: Orientation.Value) } diff --git a/src/swing/scala/swing/Orientation.scala b/src/swing/scala/swing/Orientation.scala index 77e14bf3a6..7f10bbee65 100644 --- a/src/swing/scala/swing/Orientation.scala +++ b/src/swing/scala/swing/Orientation.scala @@ -11,9 +11,10 @@ package scala.swing -import javax.swing.SwingConstants._ +import java.awt.Adjustable._ object Orientation extends Enumeration { val Horizontal = Value(HORIZONTAL) val Vertical = Value(VERTICAL) + val NoOrientation = Value(NO_ORIENTATION) } diff --git a/src/swing/scala/swing/Oriented.scala b/src/swing/scala/swing/Oriented.scala index da16b1d58e..a29976ada9 100644 --- a/src/swing/scala/swing/Oriented.scala +++ b/src/swing/scala/swing/Oriented.scala @@ -11,15 +11,25 @@ package scala.swing +object Oriented { + trait Wrapper extends Oriented { + def peer: OrientedMixin + + /* + * Need to revert to structural type, since scroll bars are oriented + * and these are created by scroll panes. Shouldn't be a bootleneck. + */ + protected type OrientedMixin = { + def getOrientation(): Int + def setOrientation(n: Int) + } + def orientation: Orientation.Value = Orientation(peer.getOrientation) + } +} + /** * Something that can have an orientation. */ trait Oriented { - def peer: javax.swing.JComponent with OrientedMixin - - protected trait OrientedMixin { - def getOrientation(): Int - def setOrientation(n: Int) - } - def orientation: Orientation.Value = Orientation(peer.getOrientation) -} + def orientation: Orientation.Value +} \ No newline at end of file diff --git a/src/swing/scala/swing/ProgressBar.scala b/src/swing/scala/swing/ProgressBar.scala index da8cb7edcc..cdc4262bfd 100644 --- a/src/swing/scala/swing/ProgressBar.scala +++ b/src/swing/scala/swing/ProgressBar.scala @@ -20,9 +20,9 @@ import event._ * * @see javax.swing.JProgressBar */ -class ProgressBar extends Component with Orientable { - override lazy val peer: javax.swing.JProgressBar with OrientedMixin = - new javax.swing.JProgressBar with OrientedMixin +class ProgressBar extends Component with Orientable.Wrapper { + override lazy val peer: javax.swing.JProgressBar = + new javax.swing.JProgressBar def min: Int = peer.getMinimum def min_=(v: Int) { peer.setMinimum(v) } diff --git a/src/swing/scala/swing/ScrollBar.scala b/src/swing/scala/swing/ScrollBar.scala new file mode 100644 index 0000000000..978c8ab05b --- /dev/null +++ b/src/swing/scala/swing/ScrollBar.scala @@ -0,0 +1,40 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2007-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: $ + + +package scala.swing + +import javax.swing.{JScrollBar, BoundedRangeModel} +import java.awt.event.{AdjustmentListener} + +object ScrollBar { + def wrap(c: JScrollBar): ScrollBar = { + val w = UIElement.cachedWrapper[ScrollBar](c) + if (w != null) w + else new ScrollBar { override lazy val peer = c } + } +} + +class ScrollBar extends Component with Orientable.Wrapper with Adjustable.Wrapper { + override lazy val peer = new JScrollBar + + def valueIsAjusting = peer.getValueIsAdjusting + def valueIsAjusting_=(b : Boolean) = peer.setValueIsAdjusting(b) + + // TODO: can we find a better interface? + //def setValues(value: Int = this.value, visible: Int = visibleAmount, + // min: Int = minimum, max: Int = maximum) = + // peer.setValues(value, visible, min, max) + +// Not currently needed, requires wrapper for BoundedRangeModel +// +// def model = peer.getModel +// def model_=(m : BoundedRangeModel) = peer.setModel(m) +} diff --git a/src/swing/scala/swing/ScrollPane.scala b/src/swing/scala/swing/ScrollPane.scala index e7a64324f9..4dee13464b 100644 --- a/src/swing/scala/swing/ScrollPane.scala +++ b/src/swing/scala/swing/ScrollPane.scala @@ -81,4 +81,6 @@ class ScrollPane extends Component with Container { def horizontalScrollBarPolicy = BarPolicy.wrap(peer.getHorizontalScrollBarPolicy) def horizontalScrollBarPolicy_=(p: BarPolicy.Value) = peer.setHorizontalScrollBarPolicy(p.horizontalPeer) -} + def horizontalScrollBar = ScrollBar.wrap(peer.getHorizontalScrollBar) + def verticalScrollBar = ScrollBar.wrap(peer.getVerticalScrollBar) +} \ No newline at end of file diff --git a/src/swing/scala/swing/Scrollable.scala b/src/swing/scala/swing/Scrollable.scala index 0a4bc48e1c..f59cb8b5d1 100644 --- a/src/swing/scala/swing/Scrollable.scala +++ b/src/swing/scala/swing/Scrollable.scala @@ -11,7 +11,23 @@ package scala.swing -import java.awt.Rectangle +import java.awt.{Rectangle, Dimension} + +object Scrollable { + trait Wrapper extends Scrollable { + 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.Value, direction: Int): Int = + scrollablePeer.getScrollableBlockIncrement(visibleRect, orientation.id, direction) + + def unitIncrement(visibleRect: Rectangle, orientation: Orientation.Value, direction: Int): Int = + scrollablePeer.getScrollableUnitIncrement(visibleRect, orientation.id, direction) + } +} /** * A component that is specially suitable for being placed inside a @@ -20,15 +36,11 @@ import java.awt.Rectangle * @see javax.swing.Scrollable */ 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 preferredViewportSize: Dimension - def blockIncrement(visibleRect: Rectangle, orientation: Orientation.Value, direction: Int): Int = - scrollablePeer.getScrollableBlockIncrement(visibleRect, orientation.id, direction) + def tracksViewportHeight: Boolean + def tracksViewportWidth: Boolean - def unitIncrement(visibleRect: Rectangle, orientation: Orientation.Value, direction: Int): Int = - scrollablePeer.getScrollableUnitIncrement(visibleRect, orientation.id, direction) + def blockIncrement(visibleRect: Rectangle, orientation: Orientation.Value, direction: Int): Int + def unitIncrement(visibleRect: Rectangle, orientation: Orientation.Value, direction: Int): Int } diff --git a/src/swing/scala/swing/Separator.scala b/src/swing/scala/swing/Separator.scala index dd98b35915..608df073e0 100644 --- a/src/swing/scala/swing/Separator.scala +++ b/src/swing/scala/swing/Separator.scala @@ -18,7 +18,7 @@ import javax.swing._ * * @see javax.swing.JSeparator */ -class Separator(o: Orientation.Value) extends Component with Oriented { - override lazy val peer: JSeparator with OrientedMixin = new JSeparator(o.id) with OrientedMixin +class Separator(o: Orientation.Value) extends Component with Oriented.Wrapper { + override lazy val peer: JSeparator = new JSeparator(o.id) def this() = this(Orientation.Horizontal) } diff --git a/src/swing/scala/swing/Slider.scala b/src/swing/scala/swing/Slider.scala index e18850f908..8059bfaef5 100644 --- a/src/swing/scala/swing/Slider.scala +++ b/src/swing/scala/swing/Slider.scala @@ -23,9 +23,8 @@ import event._ * * @see javax.swing.JSlider */ -class Slider extends Component with Orientable with Publisher { - override lazy val peer: JSlider with OrientedMixin = - new JSlider with OrientedMixin +class Slider extends Component with Orientable.Wrapper with Publisher { + override lazy val peer: JSlider = new JSlider def min: Int = peer.getMinimum def min_=(v: Int) { peer.setMinimum(v) } diff --git a/src/swing/scala/swing/SplitPane.scala b/src/swing/scala/swing/SplitPane.scala index 7d821afb75..9e5584cd19 100644 --- a/src/swing/scala/swing/SplitPane.scala +++ b/src/swing/scala/swing/SplitPane.scala @@ -21,9 +21,9 @@ import Swing._ * * @see javax.swing.JSplitPane */ -class SplitPane(o: Orientation.Value, left: Component, right: Component) extends Component with Container with Orientable { - override lazy val peer: javax.swing.JSplitPane with OrientedMixin = - new javax.swing.JSplitPane(o.id, left.peer, right.peer) with OrientedMixin +class SplitPane(o: Orientation.Value, left: Component, right: Component) extends Component with Container with Orientable.Wrapper { + override lazy val peer: javax.swing.JSplitPane = + new javax.swing.JSplitPane(o.id, left.peer, right.peer) def this(o: Orientation.Value) = this(o, new Component {}, new Component {}) def this() = this(Orientation.Horizontal) diff --git a/src/swing/scala/swing/Table.scala b/src/swing/scala/swing/Table.scala index 80d8ce70f6..729d0c344c 100644 --- a/src/swing/scala/swing/Table.scala +++ b/src/swing/scala/swing/Table.scala @@ -110,7 +110,7 @@ object Table { * * @see javax.swing.JTable */ -class Table extends Component with Scrollable with Publisher { +class Table extends Component with Scrollable.Wrapper { override lazy val peer: JTable = new JTable with Table.JTableMixin { def tableWrapper = Table.this override def getCellRenderer(r: Int, c: Int) = new TableCellRenderer { diff --git a/src/swing/scala/swing/TextComponent.scala b/src/swing/scala/swing/TextComponent.scala index f65749220a..70d6d8055c 100644 --- a/src/swing/scala/swing/TextComponent.scala +++ b/src/swing/scala/swing/TextComponent.scala @@ -14,6 +14,7 @@ package scala.swing import javax.swing._ import javax.swing.text._ import javax.swing.event._ +import java.awt.Color import event._ object TextComponent { @@ -48,6 +49,10 @@ class TextComponent extends Component with Publisher { def selectionVisible_=(b: Boolean) { peer.getCaret.setSelectionVisible(b) } def blinkRate: Int = peer.getCaret.getBlinkRate def blinkRate_=(n: Int) { peer.getCaret.setBlinkRate(n) } + def color: Color = peer.getCaretColor + def color_=(c: Color) = peer.setCaretColor(c) + def position: Int = peer.getCaretPosition + def position_=(p: Int) = peer.setCaretPosition(p) peer.addCaretListener { new CaretListener { diff --git a/src/swing/scala/swing/UIElement.scala b/src/swing/scala/swing/UIElement.scala index 42ee4da39e..f3d2d0d785 100644 --- a/src/swing/scala/swing/UIElement.scala +++ b/src/swing/scala/swing/UIElement.scala @@ -28,18 +28,22 @@ object UIElement { /** * Returns the wrapper for a given peer, null if there is no cached wrapper - * for the given component. + * for the given component of the given type. Should never throw an exception. */ - private[swing] def cachedWrapper[C<:UIElement](c: java.awt.Component): C = (c match { - case c: javax.swing.JComponent => c.getClientProperty(ClientKey) - case _ => wrapperCache.get(c) - }).asInstanceOf[C] + private[swing] def cachedWrapper[C<:UIElement](c: java.awt.Component): C = { + val w = c match { + case c: javax.swing.JComponent => c.getClientProperty(ClientKey) + case _ => wrapperCache.get(c) + } + try { w.asInstanceOf[C] } catch { case _ => null } + } /** - * Wraps a given AWT component in a UIElement. + * Wraps a given AWT component in a UIElement. If there is no wrapper in the + * cache, this method will create a new one. */ def wrap(c: java.awt.Component): UIElement = { - val w = cachedWrapper(c) + val w = cachedWrapper[UIElement](c) if (w != null) w else new UIElement { def peer = c } } @@ -54,6 +58,9 @@ object UIElement { * Java Swing. The peer is of type java.awt.Component since this is the * least common upper bound of possible underlying peers. * + * @note [Implementation] A UIElement automatically adds itself to the + * component cache on creation. + * * @see java.awt.Component */ trait UIElement extends Proxy with LazyPublisher { -- cgit v1.2.3