Adding to contents of scala.swing.Panel

492 views
Skip to first unread message

Alan Mimms

unread,
Mar 5, 2012, 12:05:46 PM3/5/12
to scala...@googlegroups.com
OK, I have had coffee and am more awake now :)

I am wrestling with "assignment to val" in the following

package trythings
import scala.swing._

class TryPanel extends Panel {
  var subPanel = new GridBagPanel()
  _contents += subPanel          // No error here
  contents += subPanel           // "Assignment to val" error here
}

To me this looks incorrect. Panel is defined as

abstract class Panel extends Component with Container.Wrapper

and doesn't directly override contents. Nor does Component.

In scala.swing.Container.Wrapper, we have 

object Container {
...
  trait Wrapper extends Container with Publisher {
    override def peer: javax.swing.JComponent
    
    protected val _contents = new Content
    def contents: Seq[Component] = _contents
  
    protected class Content extends BufferWrapper[Component] {
      override def clear() { peer.removeAll() }
      override def remove(n: Int): Component = { 
        val c = peer.getComponent(n)
        peer.remove(n)
        UIElement.cachedWrapper[Component](c)
      }
      protected def insertAt(n: Int, c: Component) { peer.add(c.peer, n) }
      def +=(c: Component): this.type = { peer.add(c.peer) ; this }
      def length = peer.getComponentCount
      def apply(n: Int) = UIElement.cachedWrapper[Component](peer.getComponent(n))
    }
...
}

This appears to define contents as Seq[Component] and sets its value to _contents, which is a Container.Wrapper.Content. Container.Wrapper.Content defines a += method to forward to peer.add().

And yet I get "assignment to val" error here.

Via another path, if I hack and make my class TryPanel extend BoxPanel(Orientation.Horizontal) the error goes away. BoxPanel extends SequentialContainer.Wrapper instead of Container.Wrapper which directly defines contents as a Buffer[Component].

What is going on here? Am I (a newbie with Scala) missing something obvious to you wise old sages of Scala-dom? I'm guessing that contents' the use of Seq[Component] in Container.Wrapper is where the problem comes in, but I am not confident enough in my Scala skills to be sure. Is this a bug?

Thanks!

pagoda_5b

unread,
Mar 5, 2012, 2:04:10 PM3/5/12
to scala...@googlegroups.com
I believe the point here is why you're trying to create a subclass of Panel.

If you only need a specific panel (let's say BoxPanel) to add your components, you should just:

 val myPane = new BoxPanel {
   contents += new GridBagPanel()
   ...
 }

where you could use an anonimous class to layout your application gui.

If you're trying to create your custom panel, then I guess you should override the panel contents method, which returns a generic Seq[Component], which in turn doesn't sports any += method

if you look at the signatures of the Content inner class you can figure it out:

    protected val _contents = new Content
    def contents: Seq[Component] = _contents

As you already noted, the specific subclasses like BoxPanel override the public method to return a specific type (like Buffer[Component]) that have a += method

I think you could override the content method with a val to just return the already available protected Content value:

    override val contents: Content = _contents

Does it makes sense to you?
Ivano

Alan Mimms

unread,
Mar 5, 2012, 11:11:47 PM3/5/12
to scala...@googlegroups.com
Yes, I think that makes sense. I do not understand the reason for the original implementation in Panel, though.
Reply all
Reply to author
Forward
0 new messages