Reputation: 263270
Here is a very simple Scala GUI test:
import scala.swing._
object FirstSwingApp extends SimpleGUIApplication {
def top = new MainFrame {
contents = new GridPanel(30, 20) {
contents ++= 1 to 600 map (_ => new Label("test"))
}
}
}
Every contained label is displayed exactly as big as it needs to be:
Now I want to replace Label
with a custom type:
contents ++= 1 to 600 map (_ => new Foo)
class Foo extends Panel {
override def minimumSize = {
println("minimumSize")
new java.awt.Dimension(32, 32)
}
override def preferredSize = {
println("preferredSize")
new java.awt.Dimension(32, 32)
}
override def maximumSize = {
println("maximumSize")
new java.awt.Dimension(32, 32)
}
}
But the result is way too small:
Apparently, none of the xxxSize
methods gets called, because the program produces no console output. What exactly do I have to change so that each Foo
is displayed with a size of 32x32 pixels?
Upvotes: 3
Views: 1767
Reputation: 67310
As Rogach said, the problem is you don't change the underlying peer. Another possibility to do that is the following:
class Foo extends Panel {
preferredSize = new Dimension(32, 32)
}
Upvotes: 2
Reputation: 27250
The problem here is that scala.swing
is just a wrapper around javax.swing
. And Label
, in this case, is just an instance, that is wrapped around javax.swing.JLabel
.
And when the component is being passed to javax.swing
system, only the component is passed, not the wrapper.
Thus, overriding methods on wrappers will do you no good.
But you can override methods on the actual component instance. For example:
import scala.swing._
import javax.swing._
import java.awt.Dimension
import javax.swing.JPanel
object Swg extends SimpleSwingApplication {
class Foo extends Panel {
override lazy val peer: JPanel = new JPanel with SuperMixin {
override def getMinimumSize = new Dimension(32, 32)
override def getPreferredSize = new Dimension(32, 32)
override def getMaximumSize = new Dimension(32, 32)
}
}
def top = new MainFrame {
contents = new GridPanel(30, 20) {
contents ++= List.fill(600)(new Foo)
}
}
}
On my machine, that gives a frame of 640 px wide and about 960 px high - which is probably what you want.
Upvotes: 4