Search code examples
scalaswinglayout-managerjscrollpanegridbaglayout

Controlling downsize behaviour of ScrollPane within GridBagLayout


I'm experimenting with manipulating images in a GUI. I need to have an image shown in a GUI, with several other components around it. If the GUI window is resized, only the image area needs to resize with it.

I thought using a GridBagLayout was the way to go, but when I do, the resize behaviour of the ScrollPane holding the image is unexpected: when the GUI window is downsized in a way that the available space is too small for the image in the ScrollPane, the ScrollPane component downsizes immediately to a dimension which is much smaller that the available space.

Image for code example: qm.png

import scala.swing.{ Button, GridBagPanel, Label, MainFrame, ScrollPane, SimpleSwingApplication }
import javax.swing.ImageIcon

object GridBag_vs_ScrollPane extends SimpleSwingApplication {
    def top = new MainFrame {
        title = "GridBag vs ScrollPane"
        contents = gui
    }

    val gui = new GridBagPanel {
        val fp_img = """.\resources\qm.png"""
        val scrPane = new ScrollPane( new Label { icon = new ImageIcon(fp_img) } )
        val button1 = new Button("Button 1")

        val c = new Constraints
        c.gridx = 0
        c.gridy = 0
        layout(button1) = c

        c.weighty = 1.0
        c.gridx = 0
        c.gridy = 1
        layout(scrPane) = c
    }
}

The behaviour of the ScrollPane I was looking for is more like the one of the next piece of code:

import javax.swing.ImageIcon

import scala.swing.{Label, MainFrame, ScrollPane, SimpleSwingApplication}

object SimpleScrollPane extends SimpleSwingApplication {
    def top = new MainFrame {
        title = "Simple ScrollPane"
        val fp_img = """.\resources\qm.png"""
        contents = new ScrollPane( new Label { icon = new ImageIcon(fp_img) } )
    }
}

I can’t figure how to get the desired behaviour, nor why the ScrollPane behaves differently in both GUI implementations.

Can anyone enlighten me?


Solution

  • The suggestion of Andrew Thompson got me halfway. I needed to add bothc.fill = Fill.Both and c.weightx = 1.0 to the constraints for the scroll pane.

    The fact that the fill constraint is part of the solution is counter intuitive to me since the tutorial on GridBagLayout describes the fill constraints as «Used when the component's display area is larger than the component's requested size to determine whether and how to resize the component.», while in my case the requested size of the scroll pane component was actually larger than the available display area.