1

I am using Swing in Scala "org.scala-lang" % "scala-swing" % "2.11.0-M7". I want to set position for my components explicitly. It is possible to do in Swing API for Java.

Question: is it possible to set absolute position for components in Swing Scala API?

Swing API for Scala example:

import scala.swing._
object PositionAbsolute extends SimpleSwingApplication {
  lazy val top = new MainFrame() {
    title = "PositionAbsolute"
    val label = new Label("I want to be at (0, 0)")
    val panel = new FlowPanel()
    panel.preferredSize = new swing.Dimension(300, 400)
    panel.contents += label
    contents = panel
  }
} 

How it renders

kisileno
  • 787
  • 9
  • 23
  • 3
    *"I want to set position for my components explicitly. It is possible to do in Swing API for Java."* Being 'possible' does not make it a 'good idea'. Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). – Andrew Thompson May 24 '16 at 01:39
  • Is this a [XY-Problem?](http://xyproblem.info/) Why do you want to position your components absolutely? – hamena314 May 24 '16 at 08:13
  • I just had this exact case, where I had a very small GUI (only 3 controls and some labels) with a fixed size, and an answer to this question would have helped me a lot – Michael W. Jun 15 '22 at 07:09

1 Answers1

0

I know it's a little late for a response - and I am not at all an expert in these things, so please bear with me.

If you absolutely want or need to do absolute positioning of controls with swing in scala, here is a way to do it:

import scala.swing.{Button, Dimension, MainFrame}

object Main extends App {
  val b1 = new Button {
    text = "one"
    preferredSize = new Dimension(60, 30)
  }
  val b2 = new Button {
    text = "two"
    preferredSize = new Dimension(80, 40)
  }
  val b3 = new Button("three")

  b1.peer.setBounds(25, 5, b1.peer.getPreferredSize.width, b1.peer.getPreferredSize.height)
  b2.peer.setBounds(55, 50, b2.peer.getPreferredSize.width, b2.peer.getPreferredSize.height)
  b3.peer.setBounds(150, 15, b3.peer.getPreferredSize.width, b3.peer.getPreferredSize.height)

  javax.swing.SwingUtilities.invokeLater(() => {
    val frame: MainFrame = new MainFrame {
      title = "AbsoluteLayoutDemo"
      resizable = true
      size = new Dimension(300, 150)
    }
    frame.peer.setLayout(null)
    frame.peer.add(b1.peer)
    frame.peer.add(b2.peer)
    frame.peer.add(b3.peer)
    frame.visible = true
  })
}

I don't like it very much myself, but this works. I compiled this code with scala version 2.13.8 and

libraryDependencies += "org.scala-lang.modules" %% "scala-swing" % "3.0.0"

in the build.sbt file

This was my translation of the java-example in docs.oracle.com/javase/tutorial/uiswing/layout/none.html

but I made a few changes that I thought would make sense for a scala example.

I am not exactly sure what the consequences of this approach are, so please use at your own risk - because I am really not sure how this works.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Michael W.
  • 182
  • 1
  • 12