diff --git a/.gitignore b/.gitignore index 098288e7..e94bd628 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ scala-swing.iml .DS_Store target/ +/.bloop/ +/.bsp/ diff --git a/.travis.yml b/.travis.yml index c402d2f8..073c58aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ scala: - 2.11.12 - 2.12.11 - 2.13.3 + - 3.0.0-M1 env: - ADOPTOPENJDK=8 diff --git a/README.md b/README.md index 37d52e4e..d89399c1 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,15 @@ [](http://search.maven.org/#search%7Cga%7C1%7Cg%3Aorg.scala-lang.modules%20a%3Ascala-swing_2.12) [](http://search.maven.org/#search%7Cga%7C1%7Cg%3Aorg.scala-lang.modules%20a%3Ascala-swing_2.13) -This is now community maintained by [@Sciss](https://github.com/Sciss) and [@benhutchison](https://github.com/benhutchison). If you are interested in helping then contact them or [@adriaanm](https://github.com/adriaanm). +This is now community maintained by [@Sciss](https://github.com/Sciss) and [@benhutchison](https://github.com/benhutchison). +If you are interested in helping then contact them or [@adriaanm](https://github.com/adriaanm). ## Adding an sbt dependency To use scala-swing from sbt, add this to your `build.sbt`: ``` -libraryDependencies += "org.scala-lang.modules" %% "scala-swing" % "2.1.1" +libraryDependencies += "org.scala-lang.modules" %% "scala-swing" % "3.0.0" ``` ## About scala-swing @@ -113,6 +114,7 @@ new Frame { - When using Scala 2.11, you can use the Scala swing 2.0.x releases on JDK 6 or newer. - Scala 2.12 requires you to use JDK 8 (that has nothing to do with scala-swing). - The `2.1.x` series adds support for Scala 2.13, while dropping Scala 2.10. +- The `3.0.x` series adds support for Scala 3.0. The reason to have different major versions is to allow for binary incompatible changes. Also, some java-swing classes were generified in JDK 7 (see [SI-3634](https://issues.scala-lang.org/browse/SI-3634)) and require the scala-swing sources to be adjusted. diff --git a/build.sbt b/build.sbt index bdc99963..5816be49 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,15 @@ +lazy val scalaTestVersion = "3.2.3" + +lazy val commonSettings = Seq( + crossScalaVersions := Seq("3.0.0-M1", "2.13.3", "2.12.12", "2.11.12"), + scalaVersion := "2.13.3", + scalacOptions ++= Seq("-deprecation", "-feature"), +) + lazy val swing = project.in(file(".")) .settings(ScalaModulePlugin.scalaModuleSettings) .settings(ScalaModulePlugin.scalaModuleOsgiSettings) + .settings(commonSettings) .settings( name := "scala-swing", OsgiKeys.exportPackage := Seq(s"scala.swing.*;version=${version.value}"), @@ -8,8 +17,8 @@ lazy val swing = project.in(file(".")) // set the prompt (for this build) to include the project id. ThisBuild / shellPrompt := { state => Project.extract(state).currentRef.project + "> " }, libraryDependencies ++= Seq( - "org.scalatest" %% "scalatest-flatspec" % "3.2.0" % Test, - "org.scalatest" %% "scalatest-shouldmatchers" % "3.2.0" % Test, + "org.scalatest" %% "scalatest-flatspec" % scalaTestVersion % Test, + "org.scalatest" %% "scalatest-shouldmatchers" % scalaTestVersion % Test, ), // Adds a `src/main/scala-2.13+` source directory for Scala 2.13 and newer // and a `src/main/scala-2.13-` source directory for Scala version older than 2.13 @@ -17,6 +26,7 @@ lazy val swing = project.in(file(".")) val sourceDir = (Compile / sourceDirectory).value CrossVersion.partialVersion(scalaVersion.value) match { case Some((2, n)) if n >= 13 => sourceDir / "scala-2.13+" + case Some((3, _)) => sourceDir / "scala-2.13+" // Dotty case _ => sourceDir / "scala-2.13-" } } @@ -24,6 +34,7 @@ lazy val swing = project.in(file(".")) lazy val examples = project.in(file("examples")) .dependsOn(swing) + .settings(commonSettings) .settings( scalaVersion := (swing / scalaVersion).value, run / fork := true, @@ -32,6 +43,7 @@ lazy val examples = project.in(file("examples")) lazy val uitest = project.in(file("uitest")) .dependsOn(swing) + .settings(commonSettings) .settings( scalaVersion := (swing / scalaVersion).value, run / fork := true, diff --git a/examples/src/main/scala/scala/swing/examples/LinePainting.scala b/examples/src/main/scala/scala/swing/examples/LinePainting.scala index 5b75a586..5ecb7656 100644 --- a/examples/src/main/scala/scala/swing/examples/LinePainting.scala +++ b/examples/src/main/scala/scala/swing/examples/LinePainting.scala @@ -47,11 +47,11 @@ object LinePainting extends SimpleSwingApplication { var path = new geom.GeneralPath def lineTo(p: Point): Unit = { - path.lineTo(p.x, p.y); repaint() + path.lineTo(p.x.toFloat, p.y.toFloat); repaint() } def moveTo(p: Point): Unit = { - path.moveTo(p.x, p.y); repaint() + path.moveTo(p.x.toFloat, p.y.toFloat); repaint() } override def paintComponent(g: Graphics2D): Unit = { diff --git a/examples/src/main/scala/scala/swing/examples/tutorials/components/ButtonHtmlDemo.scala b/examples/src/main/scala/scala/swing/examples/tutorials/components/ButtonHtmlDemo.scala index cfe31595..efe178c2 100644 --- a/examples/src/main/scala/scala/swing/examples/tutorials/components/ButtonHtmlDemo.scala +++ b/examples/src/main/scala/scala/swing/examples/tutorials/components/ButtonHtmlDemo.scala @@ -88,19 +88,19 @@ class ButtonHtmlDemo extends FlowPanel { listenTo(enable) reactions += { - case ButtonClicked(`enable`) => enableMiddle - case ButtonClicked(`disable`) => disableMiddle + case ButtonClicked(`enable`) => enableMiddle() + case ButtonClicked(`disable`) => disableMiddle() } def enableMiddle(): Unit = { - enable.enabled = false - middle.enabled = true - disable.enabled = true + enable .enabled = false + middle .enabled = true + disable .enabled = true } def disableMiddle(): Unit = { - enable.enabled = true - middle.enabled = false - disable.enabled = false + enable .enabled = true + middle .enabled = false + disable .enabled = false } def createImageIcon(path: String): Option[javax.swing.ImageIcon] = { val imgURL: java.net.URL = getClass().getResource(path) diff --git a/examples/src/main/scala/scala/swing/examples/tutorials/components/FrameDemo2.scala b/examples/src/main/scala/scala/swing/examples/tutorials/components/FrameDemo2.scala index f5f02d38..673feebd 100644 --- a/examples/src/main/scala/scala/swing/examples/tutorials/components/FrameDemo2.scala +++ b/examples/src/main/scala/scala/swing/examples/tutorials/components/FrameDemo2.scala @@ -28,15 +28,18 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + package scala.swing.examples.tutorials.components -import scala.swing._ -import scala.swing.event.ButtonClicked -import javax.swing.{ Box, BoxLayout, JDialog, JFrame, ImageIcon, UIManager } -import java.awt.{ BorderLayout, Color, Component, Dimension, Graphics, Image, Point, Toolkit } import java.awt.image.BufferedImage +import java.awt.{Color, Dimension, Graphics, Image, Point, Toolkit} import java.net.URL +import javax.swing.{ImageIcon, JDialog, JFrame, UIManager} + +import scala.swing._ +import scala.swing.event.ButtonClicked + /* * Tutorial: How to Make Frames (Main Windows) * http://docs.oracle.com/javase/tutorial/uiswing/components/frame.html @@ -49,75 +52,75 @@ import java.net.URL * setIconImage. It uses the file /scala/swing/examples/tutorials/images/FD.jpg. */ class FrameDemo2 { - private var lastLocation: Point = null - private var defaultButton: Button = null - // private val maxX = 500 - // private val maxY = 500 - //constants for action commands - val NO_DECORATIONS = "no_dec"; - val LF_DECORATIONS = "laf_dec"; - val WS_DECORATIONS = "ws_dec"; - val CREATE_WINDOW = "new_win"; - val DEFAULT_ICON = "def_icon"; - val FILE_ICON = "file_icon"; - val PAINT_ICON = "paint_icon"; - - //true if the next frame created should have no window decorations - var noDecorations = false; - - //true if the next frame created should have setIconImage called - var specifyIcon = false; - - //true if the next frame created should have a custom painted icon - var createIcon = false; - - val screenSize: Dimension = Toolkit.getDefaultToolkit().getScreenSize() - val maxX = screenSize.width - 50 - val maxY = screenSize.height - 50 - - //Create a new MyFrame object and show it. + private var lastLocation : Point = null + private var defaultButton : Button = null + + // constants for action commands + val NO_DECORATIONS = "no_dec" + val LF_DECORATIONS = "laf_dec" + val WS_DECORATIONS = "ws_dec" + val CREATE_WINDOW = "new_win" + val DEFAULT_ICON = "def_icon" + val FILE_ICON = "file_icon" + val PAINT_ICON = "paint_icon" + + // true if the next frame created should have no window decorations + var noDecorations = false + + // true if the next frame created should have setIconImage called + var specifyIcon = false + + // true if the next frame created should have a custom painted icon + var createIcon = false + + val screenSize: Dimension = Toolkit.getDefaultToolkit.getScreenSize + + val maxX: Int = screenSize.width - 50 + val maxY: Int = screenSize.height - 50 + + // Creates a new MyFrame object and show it. def showNewWindow(): Unit = { - //Take care of the no window decorations case. - //NOTE: Unless you really need the functionality - //provided by JFrame, you would usually use a - //Window or JWindow instead of an undecorated JFrame. + // Take care of the no window decorations case. + // NOTE: Unless you really need the functionality + // provided by JFrame, you would usually use a + // Window or JWindow instead of an undecorated JFrame. val frame: Option[Frame] = if (noDecorations) Some(new MyFrameUndecorated()) else Some(new MyFrame()) - //Set window location. + // Set window location. if (frame.isDefined) { val f = frame.get if (lastLocation != null) { //Move the window over and down 40 pixels. - lastLocation.translate(40, 40); + lastLocation.translate(40, 40) if ((lastLocation.x > maxX) || (lastLocation.y > maxY)) { - lastLocation.setLocation(0, 0); + lastLocation.setLocation(0, 0) } f.location = lastLocation } else { lastLocation = f.location } - //Calling setIconImage sets the icon displayed when the window - //is minimized. Most window systems (or look and feels, if - //decorations are provided by the look and feel) also use this - //icon in the window decorations. + // Calling setIconImage sets the icon displayed when the window + // is minimized. Most window systems (or look and feels, if + // decorations are provided by the look and feel) also use this + // icon in the window decorations. if (specifyIcon) { if (createIcon) { - //create an icon from scratch + // create an icon from scratch f.iconImage = FrameDemo2.createFDImage() } else { - //get the icon from a file + // get the icon from a file f.iconImage = FrameDemo2.getFDImage().get } } } } - // Create the window-creation controls that go in the main window. + // Creates the window-creation controls that go in the main window. def createOptionControls(frame: Frame): BoxPanel = { - val label1 = new Label("Decoration options for subsequently created frames:") - val bg1 = new ButtonGroup() - val label2 = new Label("Icon options:") - val bg2 = new ButtonGroup() + val label1 = new Label("Decoration options for subsequently created frames:") + val bg1 = new ButtonGroup() + val label2 = new Label("Icon options:") + val bg2 = new ButtonGroup() //Create the buttons val rb1 = new RadioButton() { @@ -197,7 +200,7 @@ class FrameDemo2 { box } - //Create the button that goes in the main window. + // Creates the button that goes in the main window. def createButtonPane(frame: Frame): FlowPanel = { val button = new Button("New window") defaultButton = button @@ -207,7 +210,7 @@ class FrameDemo2 { case ButtonClicked(`button`) => showNewWindow() } - //Center the button in a panel with some space around it. + // Center the button in a panel with some space around it. val pane = new FlowPanel() { border = Swing.EmptyBorder(5, 5, 5, 5) contents += button @@ -220,12 +223,12 @@ class FrameDemo2 { class MyFrame extends Frame { title = "A window" - //This button lets you close even an undecorated window. - val button = new Button("Close window") { + // This button lets you close even an undecorated window. + val button: Button = new Button("Close window") { xLayoutAlignment = java.awt.Component.CENTER_ALIGNMENT } - //Place the button near the bottom of the window. + // Place the button near the bottom of the window. contents = new BoxPanel(Orientation.Vertical) { contents += Swing.VGlue contents += button @@ -241,20 +244,19 @@ class MyFrame extends Frame { preferredSize = new Dimension(150, 150) pack() visible = true - override def closeOperation() = { - close - } + + override def closeOperation(): Unit = close() } class MyFrameUndecorated extends Frame with RichWindow.Undecorated { visible = false - //This button lets you close even an undecorated window. - val button = new Button("Close window") { + // This button lets you close even an undecorated window. + val button: Button = new Button("Close window") { xLayoutAlignment = java.awt.Component.CENTER_ALIGNMENT } - //Place the button near the bottom of the window. - //Undecorated windows are not supported in scala swing. + // Place the button near the bottom of the window. + // Undecorated windows are not supported in scala swing. contents = new BoxPanel(Orientation.Vertical) { contents += Swing.VGlue contents += button @@ -270,55 +272,54 @@ class MyFrameUndecorated extends Frame with RichWindow.Undecorated { preferredSize = new Dimension(150, 150) pack() visible = true - override def closeOperation() = { - close - } + + override def closeOperation(): Unit = close() } object FrameDemo2 extends SimpleSwingApplication { - //Creates an icon-worthy Image from scratch. + // Creates an icon-worthy Image from scratch. def createFDImage(): Image = { - //Create a 16x16 pixel image. + // Create a 16x16 pixel image. val bi = new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB) - //Draw into it. - val g: Graphics = bi.getGraphics() - g.setColor(Color.BLACK); + // Draw into it. + val g: Graphics = bi.getGraphics + g.setColor(Color.BLACK) g.fillRect(0, 0, 15, 15) g.setColor(Color.RED) g.fillOval(5, 3, 6, 6) - //Clean up. + // Clean up. g.dispose() - //Return it. + // Return it. bi } // Returns an Image Option or None. def getFDImage(): Option[Image] = { - val imgURL: URL = getClass().getResource("/scala/swing/examples/tutorials/images/FD.jpg"); + val imgURL: URL = getClass.getResource("/scala/swing/examples/tutorials/images/FD.jpg") if (imgURL != null) { - return Some(new ImageIcon(imgURL).getImage) + Some(new ImageIcon(imgURL).getImage) } else { - return None + None } } - lazy val top: Frame { val demo: FrameDemo2 } = new Frame() { + object top extends Frame { title = "FrameDemo2" - //Use the Java look and feel. This needs to be done before the frame is created - //so the companion object FrameDemo2 cannot simply extend SimpleSwingApplcation. + // Use the Java look and feel. This needs to be done before the frame is created + // so the companion object FrameDemo2 cannot simply extend SimpleSwingApplication. try { UIManager.setLookAndFeel( - UIManager.getCrossPlatformLookAndFeelClassName()); + UIManager.getCrossPlatformLookAndFeelClassName) } catch { - case e: Exception => ; + case _: Exception => () } - //Make sure we have nice window decorations. - JFrame.setDefaultLookAndFeelDecorated(true); - JDialog.setDefaultLookAndFeelDecorated(true); - //Create and set up the content pane. - val demo = new FrameDemo2(); + // Make sure we have nice window decorations. + JFrame .setDefaultLookAndFeelDecorated(true) + JDialog.setDefaultLookAndFeelDecorated(true) + // Create and set up the content pane. + val demo = new FrameDemo2() } val bp: BorderPanel = new BorderPanel() { layout(top.demo.createOptionControls(top)) = BorderPanel.Position.Center diff --git a/examples/src/main/scala/scala/swing/examples/tutorials/components/IconDemoApp.scala b/examples/src/main/scala/scala/swing/examples/tutorials/components/IconDemoApp.scala index 191d6a36..8a5b937c 100644 --- a/examples/src/main/scala/scala/swing/examples/tutorials/components/IconDemoApp.scala +++ b/examples/src/main/scala/scala/swing/examples/tutorials/components/IconDemoApp.scala @@ -123,18 +123,16 @@ class IconDemoApp extends MainFrame { }.toList } - f.foreach { - thumbs:List[Option[ThumbnailAction]] => - buttonBar.contents.dropRight(1) - thumbs.foreach{ thumbAction => { - thumbAction.foreach { ta => - buttonBar.contents += new Button(ta) - } - }} - buttonBar.contents += Swing.Glue + f.foreach { thumbs => + buttonBar.contents.dropRight(1) + thumbs.foreach { thumbAction => + thumbAction.foreach { ta => + buttonBar.contents += new Button(ta) + } + } + buttonBar.contents += Swing.Glue } - /** * Resizes an image using a Graphics2D object backed by a BufferedImage. * @param srcImg - source image to scale diff --git a/examples/src/main/scala/scala/swing/examples/tutorials/components/SliderDemo.scala b/examples/src/main/scala/scala/swing/examples/tutorials/components/SliderDemo.scala index 74c6d660..028081f0 100644 --- a/examples/src/main/scala/scala/swing/examples/tutorials/components/SliderDemo.scala +++ b/examples/src/main/scala/scala/swing/examples/tutorials/components/SliderDemo.scala @@ -31,12 +31,13 @@ package scala.swing.examples.tutorials.components -import scala.swing._ -import scala.swing.event.{ ValueChanged, WindowDeiconified, WindowIconified } import java.awt.Font -import java.awt.event.{ ActionEvent, ActionListener } -import javax.swing.Timer -import javax.swing.{ImageIcon, UIManager} +import java.awt.event.{ActionEvent, ActionListener} + +import javax.swing.{ImageIcon, Timer} + +import scala.swing._ +import scala.swing.event.{ValueChanged, WindowDeiconified, WindowIconified} /** * Tutorial: How to Use Sliders @@ -49,27 +50,28 @@ import javax.swing.{ImageIcon, UIManager} * directory. */ class SliderDemo(window: Window) extends BoxPanel(Orientation.Vertical) with ActionListener { - //Set up animation parameters. - val FpsMin = 0 - val FpsMax = 30 - val FpsInit = 15 //initial frames per second - var frameNumber = 0 - val NumFrames = 14 - val images = new Array[Option[ImageIcon]](NumFrames) - var frozen = false - var delay = 1000 / FpsInit - - val sliderLabel = new Label("Frames Per Second") { + // Set up animation parameters. + val FpsMin = 0 + val FpsMax = 30 + val FpsInit = 15 // initial frames per second + var frameNumber = 0 + val NumFrames = 14 + + val images = new Array[Option[ImageIcon]](NumFrames) + var frozen = false + var delay: Int = 1000 / FpsInit + + val sliderLabel: Label = new Label("Frames Per Second") { horizontalAlignment = Alignment.Center xLayoutAlignment = java.awt.Component.CENTER_ALIGNMENT } - val framesPerSecond = new Slider { + val framesPerSecond: Slider = new Slider { orientation = Orientation.Horizontal min = FpsMin max = FpsMax value = FpsInit - //Turn on labels at major tick marks. + // Turn on labels at major tick marks. majorTickSpacing = 10 minorTickSpacing = 1 paintTicks = true @@ -78,24 +80,24 @@ class SliderDemo(window: Window) extends BoxPanel(Orientation.Vertical) with Act font = new Font("Serif", Font.ITALIC, 15) } - val picture = new Label() { + val picture: Label = new Label() { horizontalAlignment = Alignment.Center - xLayoutAlignment = java.awt.Component.CENTER_ALIGNMENT - Swing.Lowered + xLayoutAlignment = java.awt.Component.CENTER_ALIGNMENT + border = Swing.CompoundBorder( Swing.BeveledBorder(Swing.Lowered), Swing.EmptyBorder(10, 10, 10, 10)) } - updatePicture(0); //display first frame + updatePicture(0) // display first frame contents += sliderLabel contents += framesPerSecond contents += picture border = Swing.EmptyBorder(10, 10, 10, 10) - //Set up a timer that calls this object's action handler. + // Set up a timer that calls this object's action handler. val timer = new Timer(delay, this) - timer.setInitialDelay(delay * 7) //We pause animation twice per cycle - //by restarting the timer + timer.setInitialDelay(delay * 7) // We pause animation twice per cycle + // by restarting the timer timer.setCoalesce(true) listenTo(framesPerSecond) @@ -113,32 +115,30 @@ class SliderDemo(window: Window) extends BoxPanel(Orientation.Vertical) with Act if (frozen) startAnimation() } } - case WindowIconified(`window`) => - stopAnimation() - case WindowDeiconified(`window`) => - startAnimation() + case WindowIconified (`window`) => stopAnimation() + case WindowDeiconified(`window`) => startAnimation() } startAnimation() def startAnimation(): Unit = { - //Start (or restart) animating! + // Start (or restart) animating! timer.start() frozen = false } def stopAnimation(): Unit = { - //Stop the animating thread. + // Stop the animating thread. timer.stop() frozen = true } - //Called when the Timer fires. + // Called when the Timer fires. def actionPerformed(e: ActionEvent): Unit = { - //Advance the animation frame. + // Advance the animation frame. frameNumber = if (frameNumber == (NumFrames - 1)) 0 else frameNumber + 1 - updatePicture(frameNumber); //display the next picture + updatePicture(frameNumber) //display the next picture if (frameNumber == (NumFrames - 1) || frameNumber == (NumFrames / 2 - 1)) { timer.restart() @@ -147,29 +147,32 @@ class SliderDemo(window: Window) extends BoxPanel(Orientation.Vertical) with Act /** Update the label to display the image for the current frame. */ def updatePicture(frameNum: Int): Unit = { - //Get the image if we haven't already. - if (images(frameNumber) == null) { - images(frameNumber) = SliderDemo.createImageIcon(s"/scala/swing/examples/tutorials/images/doggy/T$frameNumber.gif") + // Get the image if we haven't already. + if (images(frameNum) == null) { + images(frameNum) = SliderDemo.createImageIcon(s"/scala/swing/examples/tutorials/images/doggy/T$frameNumber.gif") } - //Set the image. - images(frameNumber) match { - case Some( frm ) => picture.icon = frm - case None => picture.text = s"image #$frameNumber not found" + // Set the image. + images(frameNum) match { + case Some(frm) => picture.icon = frm + case None => picture.text = s"image #$frameNumber not found" } + + // On some operating systems refresh is slow unless input devices (mouse, keyboard) are used. + // Ensure picture is repainted fast. + picture.toolkit.sync() } } object SliderDemo extends SimpleSwingApplication { - //TD UIManager.put("swing.boldMetal", false) + // TD UIManager.put("swing.boldMetal", false) /** Returns an ImageIcon, or null if the path was invalid. */ - def createImageIcon(path: String): Option[javax.swing.ImageIcon] = { + def createImageIcon(path: String): Option[javax.swing.ImageIcon] = Option(resourceFromClassloader(path)).map(imgURL => Swing.Icon(imgURL)) - } - lazy val top = new MainFrame() { + object top extends MainFrame() { title = "SliderDemo" - //Create and set up the content pane. + // Create and set up the content pane. contents = new SliderDemo(this) } } diff --git a/examples/src/main/scala/scala/swing/examples/tutorials/layout/BoxLayoutDemo2.scala b/examples/src/main/scala/scala/swing/examples/tutorials/layout/BoxLayoutDemo2.scala index d5e64fd4..533b8754 100644 --- a/examples/src/main/scala/scala/swing/examples/tutorials/layout/BoxLayoutDemo2.scala +++ b/examples/src/main/scala/scala/swing/examples/tutorials/layout/BoxLayoutDemo2.scala @@ -93,9 +93,10 @@ class BoxLayoutDemo2 extends BorderPanel { } def notifyBldComponents(): Unit = { - for (i <- 0 until NumComponents) + for (i <- 0 until NumComponents) { bldComponent(i).setSizeRestriction(restrictSize) - bldComponent(0).revalidate + } + bldComponent(0).revalidate() } } diff --git a/examples/src/main/scala/scala/swing/examples/tutorials/layout/DiagonalLayout.scala b/examples/src/main/scala/scala/swing/examples/tutorials/layout/DiagonalLayout.scala index 9ad10cad..e9b04357 100644 --- a/examples/src/main/scala/scala/swing/examples/tutorials/layout/DiagonalLayout.scala +++ b/examples/src/main/scala/scala/swing/examples/tutorials/layout/DiagonalLayout.scala @@ -48,7 +48,7 @@ class DiagonalLayout(private var vgap: Int) extends LayoutManager { private var sizeUnknown: Boolean = true - def this() { + def this() = { this(5) } diff --git a/project/build.properties b/project/build.properties index 0837f7a1..c19c768d 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.3.13 +sbt.version=1.4.2 diff --git a/project/plugins.sbt b/project/plugins.sbt index c3f0c93b..31d532c4 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1 +1,2 @@ -addSbtPlugin("org.scala-lang.modules" % "sbt-scala-module" % "2.2.2") +addSbtPlugin("org.scala-lang.modules" % "sbt-scala-module" % "2.2.3") +addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.4.5") // cross-compile for dotty diff --git a/src/main/scala/scala/swing/AbstractButton.scala b/src/main/scala/scala/swing/AbstractButton.scala index 4ed79492..e4455a62 100644 --- a/src/main/scala/scala/swing/AbstractButton.scala +++ b/src/main/scala/scala/swing/AbstractButton.scala @@ -22,7 +22,7 @@ import scala.swing.event.{ButtonClicked, Key} * * @see javax.swing.AbstractButton */ -abstract class AbstractButton extends Component with Action.Trigger.Wrapper with Publisher { +abstract class AbstractButton extends Component with Action.Trigger with Publisher { override lazy val peer: JAbstractButton = new JAbstractButton with SuperMixin {} def text: String = peer.getText @@ -43,6 +43,11 @@ abstract class AbstractButton extends Component with Action.Trigger.Wrapper with def rolloverSelectedIcon: Icon = peer.getRolloverSelectedIcon def rolloverSelectedIcon_=(b: Icon): Unit = peer.setRolloverSelectedIcon(b) + // TODO: we need an action cache + private var _action: Action = Action.NoAction + def action: Action = _action + def action_=(a: Action): Unit = { _action = a; peer.setAction(a.peer) } + peer.addActionListener(Swing.ActionListener { _ => publish(ButtonClicked(AbstractButton.this)) }) diff --git a/src/main/scala/scala/swing/Action.scala b/src/main/scala/scala/swing/Action.scala index 3b32a1b2..685cc291 100644 --- a/src/main/scala/scala/swing/Action.scala +++ b/src/main/scala/scala/swing/Action.scala @@ -12,8 +12,6 @@ package scala.swing -import java.awt.event.ActionListener - import javax.swing.{Icon, KeyStroke} object Action { @@ -26,25 +24,6 @@ object Action { */ case object NoAction extends Action("") { def apply(): Unit = () } - object Trigger { - trait Wrapper extends Action.Trigger { - def peer: javax.swing.JComponent { - def addActionListener(a: ActionListener): Unit - def removeActionListener(a: ActionListener): Unit - def setAction(a: javax.swing.Action): Unit - def getAction(): javax.swing.Action // note: must keep empty parentheses for Java compatibility - } - - // TODO: we need an action cache - private var _action: Action = Action.NoAction - def action: Action = _action - def action_=(a: Action): Unit = { _action = a; peer.setAction(a.peer) } - - //1.6: def hideActionText: Boolean = peer.getHideActionText - //def hideActionText_=(b: Boolean) = peer.setHideActionText(b) - } - } - /** * Something that triggers an action. */ diff --git a/src/main/scala/scala/swing/Adjustable.scala b/src/main/scala/scala/swing/Adjustable.scala index 525f997e..a99043a4 100644 --- a/src/main/scala/scala/swing/Adjustable.scala +++ b/src/main/scala/scala/swing/Adjustable.scala @@ -15,8 +15,8 @@ package scala.swing import java.awt.{Adjustable => JAdjustable} object Adjustable { - trait Wrapper extends Oriented.Wrapper with Adjustable { - def peer: JAdjustable with OrientedMixin + trait Wrapper extends Oriented with Adjustable { + def peer: JAdjustable def unitIncrement: Int = peer.getUnitIncrement def unitIncrement_=(i: Int): Unit = peer.setUnitIncrement(i) diff --git a/src/main/scala/scala/swing/ButtonGroup.scala b/src/main/scala/scala/swing/ButtonGroup.scala index c4946663..39ce1f0d 100644 --- a/src/main/scala/scala/swing/ButtonGroup.scala +++ b/src/main/scala/scala/swing/ButtonGroup.scala @@ -32,9 +32,9 @@ class ButtonGroup(initialButtons: AbstractButton*) { override def size: Int = peer.getButtonCount def iterator: Iterator[AbstractButton] = new Iterator[AbstractButton] { - private val enum = peer.getElements - def next(): AbstractButton = UIElement.cachedWrapper[AbstractButton](enum.nextElement()) - def hasNext: Boolean = enum.hasMoreElements + private val elements = peer.getElements + def next(): AbstractButton = UIElement.cachedWrapper[AbstractButton](elements.nextElement()) + def hasNext: Boolean = elements.hasMoreElements } } buttons ++= initialButtons diff --git a/src/main/scala/scala/swing/ComboBox.scala b/src/main/scala/scala/swing/ComboBox.scala index 2dfec78b..a819d3d4 100644 --- a/src/main/scala/scala/swing/ComboBox.scala +++ b/src/main/scala/scala/swing/ComboBox.scala @@ -16,6 +16,7 @@ import java.awt.event.ActionListener import javax.swing.{AbstractListModel, ComboBoxModel, InputVerifier, JComboBox, JComponent, JTextField, ListCellRenderer} +import scala.language.implicitConversions import scala.swing.event.ActionEvent object ComboBox { diff --git a/src/main/scala/scala/swing/Component.scala b/src/main/scala/scala/swing/Component.scala index 4eb23f95..3da84cb7 100644 --- a/src/main/scala/scala/swing/Component.scala +++ b/src/main/scala/scala/swing/Component.scala @@ -14,9 +14,12 @@ package scala.swing import java.awt.Graphics import java.awt.event._ + import javax.swing.JComponent import javax.swing.border.Border +import scala.swing.Swing.PeerContainer + /** * Utility methods, mostly for wrapping components. */ @@ -42,7 +45,7 @@ object Component { * @see http://java.sun.com/products/jfc/tsc/articles/painting/ for the component * painting mechanism */ -abstract class Component extends UIElement { +abstract class Component extends UIElement with PeerContainer { override lazy val peer: javax.swing.JComponent = new javax.swing.JComponent with SuperMixin {} /** diff --git a/src/main/scala/scala/swing/GridBagPanel.scala b/src/main/scala/scala/swing/GridBagPanel.scala index e08a4c4e..c6cd5276 100644 --- a/src/main/scala/scala/swing/GridBagPanel.scala +++ b/src/main/scala/scala/swing/GridBagPanel.scala @@ -14,6 +14,8 @@ package scala.swing import java.awt.{GridBagConstraints, GridBagLayout} +import scala.language.implicitConversions + object GridBagPanel { object Fill extends Enumeration { import GridBagConstraints._ diff --git a/src/main/scala/scala/swing/Orientable.scala b/src/main/scala/scala/swing/Orientable.scala index ed591fd9..068c9f01 100644 --- a/src/main/scala/scala/swing/Orientable.scala +++ b/src/main/scala/scala/swing/Orientable.scala @@ -12,12 +12,6 @@ package scala.swing -object Orientable { - trait Wrapper extends Oriented.Wrapper with Orientable { - def orientation_=(o: Orientation.Value): Unit = peer.setOrientation(o.id) - } -} - /** * An Oriented whose orientation can be changed. */ diff --git a/src/main/scala/scala/swing/Oriented.scala b/src/main/scala/scala/swing/Oriented.scala index 5638fdbf..d51164b8 100644 --- a/src/main/scala/scala/swing/Oriented.scala +++ b/src/main/scala/scala/swing/Oriented.scala @@ -12,22 +12,6 @@ package scala.swing -object Oriented { - trait Wrapper extends Oriented { - def peer: OrientedMixin - - /* - * Need to revert to structural type, since scroll bars are oriented - * and these are created by scroll panes. Shouldn't be a bottleneck. - */ - protected type OrientedMixin = { - def getOrientation(): Int // note: must keep empty parentheses for Java compatibility - def setOrientation(n: Int): Unit - } - def orientation: Orientation.Value = Orientation(peer.getOrientation()) - } -} - /** * Something that can have an orientation. */ diff --git a/src/main/scala/scala/swing/ProgressBar.scala b/src/main/scala/scala/swing/ProgressBar.scala index 9570c0fa..485ff6d6 100644 --- a/src/main/scala/scala/swing/ProgressBar.scala +++ b/src/main/scala/scala/swing/ProgressBar.scala @@ -21,7 +21,7 @@ import javax.swing.JProgressBar * * @see javax.swing.JProgressBar */ -class ProgressBar extends Component with Orientable.Wrapper { +class ProgressBar extends Component with Orientable { override lazy val peer: JProgressBar = new javax.swing.JProgressBar with SuperMixin @@ -43,4 +43,7 @@ class ProgressBar extends Component with Orientable.Wrapper { def paintBorder: Boolean = peer.isBorderPainted def paintBorder(v: Boolean): Unit = peer.setBorderPainted(v) + + def orientation : Orientation.Value = Orientation(peer.getOrientation()) + def orientation_= (o: Orientation.Value): Unit = peer.setOrientation(o.id) } diff --git a/src/main/scala/scala/swing/Publisher.scala b/src/main/scala/scala/swing/Publisher.scala index 3960fe62..7a82ca86 100644 --- a/src/main/scala/scala/swing/Publisher.scala +++ b/src/main/scala/scala/swing/Publisher.scala @@ -79,7 +79,7 @@ private[swing] trait LazyPublisher extends Publisher { import scala.ref._ -private[swing] trait SingleRefCollection[+A <: AnyRef] extends Iterable[A] { self => +private[swing] trait SingleRefCollection[A <: AnyRef] extends Iterable[A] { self => trait Ref[+B <: AnyRef] extends Reference[B] { override def hashCode(): Int = get match { @@ -119,7 +119,7 @@ private[swing] trait SingleRefCollection[+A <: AnyRef] extends Iterable[A] { sel while (!ahead && elems.hasNext) { // make sure we have a reference to the next element, // otherwise it might be garbage collected - val next = elems.next.get + val next = elems.next().get ahead = next.isDefined if (ahead) hd = next.get } diff --git a/src/main/scala/scala/swing/RichWindow.scala b/src/main/scala/scala/swing/RichWindow.scala index 63063857..16d2e7da 100644 --- a/src/main/scala/scala/swing/RichWindow.scala +++ b/src/main/scala/scala/swing/RichWindow.scala @@ -37,9 +37,9 @@ object RichWindow { * window is either a dialog or a frame at some point. */ sealed trait RichWindow extends Window { - def peer: AWTWindow with InterfaceMixin + def peer: AWTWindow with InterfaceMixin2 - trait InterfaceMixin extends super.InterfaceMixin { + trait InterfaceMixin2 extends InterfaceMixin { def getJMenuBar: JMenuBar def setJMenuBar(b: JMenuBar): Unit def setUndecorated(b: Boolean): Unit @@ -79,13 +79,16 @@ sealed trait RichWindow extends Window { * @see javax.swing.JFrame */ class Frame(gc: java.awt.GraphicsConfiguration = null) extends RichWindow { - override lazy val peer: JFrame with InterfaceMixin = new JFrame(gc) with InterfaceMixin with SuperMixin + override lazy val peer: JFrame with InterfaceMixin2 = new JFrame(gc) with InterfaceMixin2 with SuperMixin - def iconify(): Unit = { peer.setExtendedState(peer.getExtendedState | AWTFrame.ICONIFIED) } - def uniconify(): Unit = { peer.setExtendedState(peer.getExtendedState & ~AWTFrame.ICONIFIED) } + def iconify() : Unit = { peer.setExtendedState(peer.getExtendedState | AWTFrame.ICONIFIED) } + def uniconify() : Unit = { peer.setExtendedState(peer.getExtendedState & ~AWTFrame.ICONIFIED) } + def iconified: Boolean = (peer.getExtendedState & AWTFrame.ICONIFIED) != 0 - def maximize(): Unit = { peer.setExtendedState(peer.getExtendedState | AWTFrame.MAXIMIZED_BOTH) } + + def maximize() : Unit = { peer.setExtendedState(peer.getExtendedState | AWTFrame.MAXIMIZED_BOTH) } def unmaximize(): Unit = { peer.setExtendedState(peer.getExtendedState & ~AWTFrame.MAXIMIZED_BOTH) } + def maximized: Boolean = (peer.getExtendedState & AWTFrame.MAXIMIZED_BOTH) != 0 def iconImage: Image = peer.getIconImage @@ -189,11 +192,11 @@ object Dialog { * @see javax.swing.JDialog */ class Dialog(owner: Window, gc: java.awt.GraphicsConfiguration = null) extends RichWindow { - override lazy val peer: JDialog with InterfaceMixin = - if (owner == null) new JDialog with InterfaceMixin with SuperMixin + override lazy val peer: JDialog with InterfaceMixin2 = + if (owner == null) new JDialog with InterfaceMixin2 with SuperMixin else owner match { - case f: Frame => new JDialog(f.peer, "", false, gc) with InterfaceMixin with SuperMixin - case d: Dialog => new JDialog(d.peer, "", false, gc) with InterfaceMixin with SuperMixin + case f: Frame => new JDialog(f.peer, "", false, gc) with InterfaceMixin2 with SuperMixin + case d: Dialog => new JDialog(d.peer, "", false, gc) with InterfaceMixin2 with SuperMixin } def this() = this(null) diff --git a/src/main/scala/scala/swing/ScrollBar.scala b/src/main/scala/scala/swing/ScrollBar.scala index c52d18b8..9966942f 100644 --- a/src/main/scala/scala/swing/ScrollBar.scala +++ b/src/main/scala/scala/swing/ScrollBar.scala @@ -22,16 +22,19 @@ object ScrollBar { } } -class ScrollBar extends Component with Orientable.Wrapper with Adjustable.Wrapper { - override lazy val peer: JScrollBar = new JScrollBar with SuperMixin +class ScrollBar extends Component with Orientable with Adjustable.Wrapper { + override lazy val peer: JScrollBar = new JScrollBar with SuperMixin - def valueIsAdjusting: Boolean = peer.getValueIsAdjusting - def valueIsAdjusting_=(b : Boolean): Unit = peer.setValueIsAdjusting(b) + def valueIsAdjusting: Boolean = peer.getValueIsAdjusting + def valueIsAdjusting_=(b : Boolean): Unit = peer.setValueIsAdjusting(b) - // TODO: can we find a better interface? - //def setValues(value: Int = this.value, visible: Int = visibleAmount, - // min: Int = minimum, max: Int = maximum) = - // peer.setValues(value, visible, min, max) + def orientation : Orientation.Value = Orientation(peer.getOrientation()) + def orientation_= (o: Orientation.Value): Unit = peer.setOrientation(o.id) + + // TODO: can we find a better interface? + //def setValues(value: Int = this.value, visible: Int = visibleAmount, + // min: Int = minimum, max: Int = maximum) = + // peer.setValues(value, visible, min, max) // Not currently needed, requires wrapper for BoundedRangeModel // diff --git a/src/main/scala/scala/swing/ScrollPane.scala b/src/main/scala/scala/swing/ScrollPane.scala index 0b8f4e61..3e73a1ce 100644 --- a/src/main/scala/scala/swing/ScrollPane.scala +++ b/src/main/scala/scala/swing/ScrollPane.scala @@ -17,25 +17,21 @@ import javax.swing.{JScrollPane, ScrollPaneConstants} import scala.collection.immutable object ScrollPane { - object BarPolicy extends Enumeration { + object BarPolicy { import ScrollPaneConstants._ - val AsNeeded = new Value(HORIZONTAL_SCROLLBAR_AS_NEEDED, - VERTICAL_SCROLLBAR_AS_NEEDED) - val Never = new Value(HORIZONTAL_SCROLLBAR_NEVER, - VERTICAL_SCROLLBAR_NEVER) - val Always = new Value(HORIZONTAL_SCROLLBAR_ALWAYS, - VERTICAL_SCROLLBAR_ALWAYS) + val AsNeeded = BarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED, VERTICAL_SCROLLBAR_AS_NEEDED) + val Never = BarPolicy(HORIZONTAL_SCROLLBAR_NEVER , VERTICAL_SCROLLBAR_NEVER ) + val Always = BarPolicy(HORIZONTAL_SCROLLBAR_ALWAYS , VERTICAL_SCROLLBAR_ALWAYS ) - def wrap(id: Int): BarPolicy.Value = id match { + def wrap(id: Int): Value = id match { case HORIZONTAL_SCROLLBAR_AS_NEEDED | VERTICAL_SCROLLBAR_AS_NEEDED => AsNeeded case HORIZONTAL_SCROLLBAR_NEVER | VERTICAL_SCROLLBAR_NEVER => Never case HORIZONTAL_SCROLLBAR_ALWAYS | VERTICAL_SCROLLBAR_ALWAYS => Always } - - class Value(val horizontalPeer: Int, val verticalPeer: Int) extends super.Val { - override def id: Int = horizontalPeer - } + + type Value = BarPolicy } + final case class BarPolicy(val horizontalPeer: Int, val verticalPeer: Int) } /** diff --git a/src/main/scala/scala/swing/Separator.scala b/src/main/scala/scala/swing/Separator.scala index 15d39de4..c197cd70 100644 --- a/src/main/scala/scala/swing/Separator.scala +++ b/src/main/scala/scala/swing/Separator.scala @@ -19,7 +19,9 @@ import javax.swing.JSeparator * * @see javax.swing.JSeparator */ -class Separator(o: Orientation.Value) extends Component with Oriented.Wrapper { +class Separator(o: Orientation.Value) extends Component with Oriented { override lazy val peer: JSeparator = new JSeparator(o.id) with SuperMixin def this() = this(Orientation.Horizontal) + + def orientation: Orientation.Value = Orientation(peer.getOrientation()) } diff --git a/src/main/scala/scala/swing/Slider.scala b/src/main/scala/scala/swing/Slider.scala index 6afbffeb..f5dc5818 100644 --- a/src/main/scala/scala/swing/Slider.scala +++ b/src/main/scala/scala/swing/Slider.scala @@ -23,7 +23,7 @@ import javax.swing.{JLabel, JSlider} * * @see javax.swing.JSlider */ -class Slider extends Component with Orientable.Wrapper with Publisher { +class Slider extends Component with Orientable with Publisher { override lazy val peer: JSlider = new JSlider with SuperMixin def min: Int = peer.getMinimum @@ -65,6 +65,9 @@ class Slider extends Component with Orientable.Wrapper with Publisher { peer.setLabelTable(table) } + def orientation : Orientation.Value = Orientation(peer.getOrientation()) + def orientation_= (o: Orientation.Value): Unit = peer.setOrientation(o.id) + peer.addChangeListener(new javax.swing.event.ChangeListener { def stateChanged(e: javax.swing.event.ChangeEvent): Unit = publish(new event.ValueChanged(Slider.this)) diff --git a/src/main/scala/scala/swing/SplitPane.scala b/src/main/scala/scala/swing/SplitPane.scala index d829775f..6c77c81e 100644 --- a/src/main/scala/scala/swing/SplitPane.scala +++ b/src/main/scala/scala/swing/SplitPane.scala @@ -32,7 +32,7 @@ import scala.swing.Swing.nullPeer * @see javax.swing.JSplitPane */ class SplitPane(o: Orientation.Value, left: Component, right: Component) - extends Component with Container with Orientable.Wrapper { + extends Component with Container with Orientable { def this(o: Orientation.Value) = this(o, new Component {}, new Component {}) def this() = this(Orientation.Horizontal) @@ -82,4 +82,7 @@ class SplitPane(o: Orientation.Value, left: Component, right: Component) def continuousLayout : Boolean = peer.isContinuousLayout def continuousLayout_= (b: Boolean): Unit = peer.setContinuousLayout(b) + + def orientation : Orientation.Value = Orientation(peer.getOrientation()) + def orientation_= (o: Orientation.Value): Unit = peer.setOrientation(o.id) } diff --git a/src/main/scala/scala/swing/Swing.scala b/src/main/scala/scala/swing/Swing.scala index f80cb7c6..54c264d0 100644 --- a/src/main/scala/scala/swing/Swing.scala +++ b/src/main/scala/scala/swing/Swing.scala @@ -19,11 +19,13 @@ import javax.swing.border.{BevelBorder, Border, CompoundBorder, MatteBorder, Tit import javax.swing.event.{ChangeEvent, ChangeListener} import javax.swing.{BorderFactory, Icon, ImageIcon, JComponent, SwingUtilities} +import scala.language.implicitConversions + /** * Helpers for this package. */ object Swing { - protected[swing] type PeerContainer = { def peer: awt.Container } + protected[swing] trait PeerContainer { def peer: awt.Container } protected[swing] def toNoIcon (i: Icon): Icon = if (i == null) EmptyIcon else i protected[swing] def toNullIcon (i: Icon): Icon = if (i == EmptyIcon) null else i @@ -74,8 +76,9 @@ object Swing { * that you don't want an icon. */ case object EmptyIcon extends Icon { - def getIconHeight: Int = 0 - def getIconWidth: Int = 0 + def getIconHeight : Int = 0 + def getIconWidth : Int = 0 + def paintIcon(c: java.awt.Component, g: java.awt.Graphics, x: Int, y: Int): Unit = () } @@ -102,16 +105,16 @@ object Swing { shadowOuter, shadowInner) sealed abstract class Embossing { - def bevelPeer: Int - def etchPeer: Int + def bevelPeer : Int + def etchPeer : Int } case object Lowered extends Embossing { - def bevelPeer: Int = BevelBorder.LOWERED - def etchPeer: Int = javax.swing.border.EtchedBorder.LOWERED + def bevelPeer : Int = BevelBorder.LOWERED + def etchPeer : Int = javax.swing.border.EtchedBorder.LOWERED } case object Raised extends Embossing { - def bevelPeer: Int = BevelBorder.RAISED - def etchPeer: Int = javax.swing.border.EtchedBorder.RAISED + def bevelPeer : Int = BevelBorder.RAISED + def etchPeer : Int = javax.swing.border.EtchedBorder.RAISED } def EtchedBorder: Border = BorderFactory.createEtchedBorder() diff --git a/src/main/scala/scala/swing/Table.scala b/src/main/scala/scala/swing/Table.scala index b7815580..070c1d16 100644 --- a/src/main/scala/scala/swing/Table.scala +++ b/src/main/scala/scala/swing/Table.scala @@ -91,7 +91,7 @@ object Table { } class LabelRenderer[A](convert: A => (Icon, String)) extends AbstractRenderer[A, Label](new Label) { - def this() { + def this() = { this(a => (null, a.toString)) } diff --git a/src/main/scala/scala/swing/TextField.scala b/src/main/scala/scala/swing/TextField.scala index 2072ca27..f2d498f2 100644 --- a/src/main/scala/scala/swing/TextField.scala +++ b/src/main/scala/scala/swing/TextField.scala @@ -32,7 +32,7 @@ import scala.swing.event.EditDone * * @see javax.swing.JTextField */ -class TextField(text0: String, columns0: Int) extends TextComponent with TextComponent.HasColumns with Action.Trigger.Wrapper { +class TextField(text0: String, columns0: Int) extends TextComponent with TextComponent.HasColumns with Action.Trigger { override lazy val peer: JTextField = new JTextField(text0, columns0) with SuperMixin def this(text: String) = this(text, 0) def this(columns: Int) = this("", columns) @@ -46,6 +46,11 @@ class TextField(text0: String, columns0: Int) extends TextComponent with TextCom /** @see javax.swing.JTextField#setHorizontalAlignment() */ def horizontalAlignment_=(x: Alignment.Value): Unit = peer.setHorizontalAlignment(x.id) + // TODO: we need an action cache + private var _action: Action = Action.NoAction + def action: Action = _action + def action_=(a: Action): Unit = { _action = a; peer.setAction(a.peer) } + private lazy val actionListener = Swing.ActionListener { _ => publish(EditDone(TextField.this)) } diff --git a/src/main/scala/scala/swing/Window.scala b/src/main/scala/scala/swing/Window.scala index c3e2b3c2..617c5299 100644 --- a/src/main/scala/scala/swing/Window.scala +++ b/src/main/scala/scala/swing/Window.scala @@ -15,6 +15,8 @@ package scala.swing import java.awt.event.{WindowEvent, WindowListener} import java.awt.{Window => AWTWindow} +import scala.swing.Swing.PeerContainer + /** * A window with decoration such as a title, border, and action buttons. * @@ -23,7 +25,7 @@ import java.awt.{Window => AWTWindow} * * @see javax.swing.JFrame */ -abstract class Window extends UIElement with RootPanel with Publisher { outer => +abstract class Window extends UIElement with RootPanel with PeerContainer with Publisher { outer => def peer: AWTWindow with InterfaceMixin protected trait InterfaceMixin extends javax.swing.RootPaneContainer @@ -48,22 +50,23 @@ abstract class Window extends UIElement with RootPanel with Publisher { outer => } def defaultButton: Option[Button] = toOption(peer.getRootPane.getDefaultButton) map UIElement.cachedWrapper[Button] - def defaultButton_=(b: Button): Unit = { + + def defaultButton_=(b: Button): Unit = peer.getRootPane.setDefaultButton(b.peer) - } - def defaultButton_=(b: Option[Button]): Unit = { + + def defaultButton_=(b: Option[Button]): Unit = peer.getRootPane.setDefaultButton(b.map(_.peer).orNull) - } def dispose(): Unit = peer.dispose() def pack(): this.type = { peer.pack(); this } - def setLocationRelativeTo(c: UIElement): Unit = peer.setLocationRelativeTo(c.peer) - def centerOnScreen(): Unit = peer.setLocationRelativeTo(null) - def location_=(p: Point): Unit = peer.setLocation(p) - def size_=(size: Dimension): Unit = peer.setSize(size) - def bounds_=(rect: Rectangle): Unit = peer.setBounds(rect) + def setLocationRelativeTo(c: UIElement) : Unit = peer.setLocationRelativeTo(c.peer) + def centerOnScreen() : Unit = peer.setLocationRelativeTo(null) + + def location_= (p : Point ): Unit = peer.setLocation(p ) + def size_= (size : Dimension ): Unit = peer.setSize (size ) + def bounds_= (rect : Rectangle ): Unit = peer.setBounds (rect ) def owner: Window = UIElement.cachedWrapper[Window](peer.getOwner) diff --git a/src/main/scala/scala/swing/package.scala b/src/main/scala/scala/swing/package.scala index d715e85c..a33e1892 100644 --- a/src/main/scala/scala/swing/package.scala +++ b/src/main/scala/scala/swing/package.scala @@ -90,9 +90,6 @@ package object swing { type Image = java.awt.Image type Font = java.awt.Font - implicit lazy val reflectiveCalls = scala.language.reflectiveCalls - implicit lazy val implicitConversions = scala.language.implicitConversions - private[swing] def ifNull [A](o: Object, a: A): A = if(o eq null) a else o.asInstanceOf[A] private[swing] def toOption [A](o: Object): Option[A] = if(o eq null) None else Some(o.asInstanceOf[A])