summaryrefslogtreecommitdiff
path: root/src/swing/scala/swing/ListView.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/swing/scala/swing/ListView.scala')
-rw-r--r--src/swing/scala/swing/ListView.scala76
1 files changed, 72 insertions, 4 deletions
diff --git a/src/swing/scala/swing/ListView.scala b/src/swing/scala/swing/ListView.scala
index c0a8b2fc4c..25af541802 100644
--- a/src/swing/scala/swing/ListView.scala
+++ b/src/swing/scala/swing/ListView.scala
@@ -3,6 +3,7 @@ package scala.swing
import javax.swing._
import javax.swing.event._
import event._
+import java.awt.Color
object ListView {
object IntervalMode extends Enumeration {
@@ -10,6 +11,68 @@ object ListView {
val SingleInterval = Value(ListSelectionModel.SINGLE_INTERVAL_SELECTION)
val MultiInterval = Value(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
}
+
+ def wrap[A](c: JList) = new ListView[A] {
+ override lazy val peer = c
+ }
+
+ object Renderer {
+ def wrap[A](r: ListCellRenderer): Renderer[A] = new Wrapped[A](r)
+
+ class Wrapped[A](override val peer: ListCellRenderer) extends Renderer[A] {
+ def componentFor(list: ListView[_<:A], isSelected: Boolean, hasFocus: Boolean, a: A, index: Int) = {
+ Component.wrap(peer.getListCellRendererComponent(list.peer, a, index, isSelected, hasFocus).asInstanceOf[JComponent])
+ }
+ }
+ }
+
+ abstract class Renderer[-A] {
+ def peer: ListCellRenderer = new ListCellRenderer {
+ def getListCellRendererComponent(list: JList, a: Any, index: Int, isSelected: Boolean, hasFocus: Boolean) = {
+ componentFor(ListView.wrap[A](list), isSelected, hasFocus, a.asInstanceOf[A], index).peer
+ }
+ }
+ def componentFor(list: ListView[_<:A], isSelected: Boolean, hasFocus: Boolean, a: A, index: Int): Component
+ }
+
+ /**
+ * A default renderer that maintains a single component for item rendering
+ * and preconfigures it to sensible defaults. It is polymorphic on the
+ * components type so clients can easily use component specific attributes
+ * during configuration.
+ */
+ abstract class DefaultRenderer[-A, C<:Component](protected val component: C) extends Renderer[A] {
+ // The renderer component is responsible for painting selection
+ // backgrounds. Hence, make sure it is opaque to let it draw
+ // the background.
+ component.opaque = true
+
+ /**
+ * Standard preconfiguration that is commonly done for any component.
+ */
+ def preConfigure(list: ListView[_<:A], isSelected: Boolean, hasFocus: Boolean, a: A, index: Int) {
+ if (isSelected) {
+ component.background = list.selectionBackground
+ component.foreground = list.selectionForeground
+ } else {
+ component.background = list.background
+ component.foreground = list.foreground
+ }
+ }
+ /**
+ * Configuration that is specific to the component and this renderer.
+ */
+ def configure(list: ListView[_<:A], isSelected: Boolean, hasFocus: Boolean, a: A, index: Int)
+
+ /**
+ * Configures the component before returning it.
+ */
+ def componentFor(list: ListView[_<:A], isSelected: Boolean, hasFocus: Boolean, a: A, index: Int): Component = {
+ preConfigure(list, isSelected, hasFocus, a, index)
+ configure(list, isSelected, hasFocus, a, index)
+ component
+ }
+ }
}
/**
@@ -23,11 +86,11 @@ class ListView[A] extends Component {
import ListView._
override lazy val peer: JList = new JList
- def this(elems: Seq[A]) = {
+ def this(items: Seq[A]) = {
this()
peer.setModel(new AbstractListModel {
- def getElementAt(n: Int) = elems(n).asInstanceOf[AnyRef]
- def getSize = elems.size
+ def getElementAt(n: Int) = items(n).asInstanceOf[AnyRef]
+ def getSize = items.size
})
}
@@ -48,7 +111,7 @@ class ListView[A] extends Component {
def anchorIndex: Int = peer.getSelectionModel.getAnchorSelectionIndex
}
- object elements extends SeqProxy[A] {
+ object items extends SeqProxy[A] {
def self = peer.getSelectedValues.projection.map(_.asInstanceOf[A])
def leadIndex: Int = peer.getSelectionModel.getLeadSelectionIndex
def anchorIndex: Int = peer.getSelectionModel.getAnchorSelectionIndex
@@ -70,6 +133,11 @@ class ListView[A] extends Component {
def fixedCellHeight = peer.getFixedCellHeight
def fixedCellHeight_=(x: Int) = peer.setFixedCellHeight(x)
+ def selectionForeground: Color = peer.getSelectionForeground
+ def selectionForeground_=(c: Color) = peer.setSelectionForeground(c)
+ def selectionBackground: Color = peer.getSelectionBackground
+ def selectionBackground_=(c: Color) = peer.setSelectionBackground(c)
+
peer.getModel.addListDataListener(new ListDataListener {
def contentsChanged(e: ListDataEvent) { publish(ListChanged(ListView.this)) }
def intervalRemoved(e: ListDataEvent) { publish(ListElementsRemoved(ListView.this, e.getIndex0 to e.getIndex1)) }