Skip to content

Commit 3566a92

Browse files
authored
Merge pull request #86 from Sciss/issue/84
Issue/84
2 parents c52d48b + 15c7223 commit 3566a92

File tree

119 files changed

+836
-733
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+836
-733
lines changed

README.md

+62-26
Original file line numberDiff line numberDiff line change
@@ -5,79 +5,115 @@
55
[<img src="https://img.shields.io/maven-central/v/org.scala-lang.modules/scala-swing_2.12.svg?label=latest%20release%20for%202.12"/>](http://search.maven.org/#search%7Cga%7C1%7Cg%3Aorg.scala-lang.modules%20a%3Ascala-swing_2.12)
66
[![Stories in Ready](https://badge.waffle.io/scala/scala-swing.svg?label=ready&title=Ready)](http://waffle.io/scala/scala-swing)
77

8-
This is now community maintained by @benhutchison & @Sciss. If you're interested in helping then contact them or @adriaanm.
8+
This is now community maintained by @benhutchison & @Sciss. If you are interested in helping then contact them or @adriaanm.
99

1010
This is a UI library that will wrap most of Java Swing for Scala in a straightforward manner.
1111
The widget class hierarchy loosely resembles that of Java Swing. The main differences are:
1212

13-
- In Java Swing all components are containers per default. This doesn't make much sense for
13+
- In Java Swing all components are containers per default. This does not make much sense for
1414
a number of components, like TextField, CheckBox, RadioButton, and so on. Our guess is that
1515
this architecture was chosen because Java lacks multiple inheritance.
1616
In scala-swing, components that can have child components extend the Container trait.
17-
- Layout managers and panels are coupled. There is no way to exchange the layout manager
17+
- Layout managers and panels are coupled. There is no way to exchange the layout manager
1818
of a panel. As a result, the layout constraints for widgets can be typed.
1919
(Note that you gain more type-safety and don't loose much flexibility here. Besides
2020
being not a common operation, exchanging the layout manager of a panel in Java
2121
Swing almost always leads to exchanging the layout constraints for every of the panel's
2222
child component. In the end, it is not more work to move all children to a newly created
2323
panel.)
24-
25-
The event system. TODO.
26-
24+
- Widget hierarchies are built by adding children to their parent container's `contents`
25+
collection. The typical usage style is to create anonymous subclasses of the widgets to
26+
customize their properties, and nest children and event reactions.
27+
- The scala-swing event system follows a different approach than the underlying Java system.
28+
Instead of add event listeners with a particular interface (such as `java.awt.ActionListener`),
29+
a `Reactor` instances announces the interest in receiving events by calling `listenTo` for
30+
a `Publisher`. Publishers are also reactors and listen to themselves per default as a convenience.
31+
A reactor contains an object `reactions` which serves as a convenient place to register observers
32+
by adding partial functions that pattern match for any event that the observer is interested in.
33+
This is shown in the examples section below.
2734
- For more details see [SIP-8](docs/SIP-8.md)
2835

2936
The library comprises two main packages:
3037

3138
- `scala.swing`: All widget classes and traits.
3239
- `scala.swing.event`: The event hierarchy.
3340

34-
3541
## Examples
3642

3743
A number of examples can be found in the `examples` project.
38-
A good place to start is `[12] scala.swing.examples.UIDemo` (_index number may be different for you_). This pulls in the all the other examples into a tabbed window.
44+
A good place to start is `[16] scala.swing.examples.UIDemo`.
45+
This pulls in the all the other examples into a tabbed window.
3946

4047
```
4148
$ sbt examples/run
4249
4350
Multiple main classes detected, select one to run:
4451
4552
[1] scala.swing.examples.ButtonApp
46-
[2] scala.swing.examples.Dialogs
47-
[3] scala.swing.examples.ComboBoxes
48-
[4] scala.swing.examples.CelsiusConverter2
49-
[5] scala.swing.examples.ListViewDemo
50-
[6] scala.swing.examples.HelloWorld
51-
[7] scala.swing.examples.LabelTest
52-
[8] scala.swing.examples.PopupDemo
53-
[9] scala.swing.examples.ColorChooserDemo
54-
[10] scala.swing.examples.LinePainting
55-
[11] scala.swing.examples.GridBagDemo
56-
[12] scala.swing.examples.UIDemo
57-
[13] scala.swing.examples.TableSelection
58-
[14] scala.swing.examples.CelsiusConverter
59-
[15] scala.swing.examples.SwingApp
60-
[16] scala.swing.examples.CountButton
53+
[2] scala.swing.examples.CelsiusConverter
54+
[3] scala.swing.examples.CelsiusConverter2
55+
[4] scala.swing.examples.ColorChooserDemo
56+
[5] scala.swing.examples.ComboBoxes
57+
[6] scala.swing.examples.CountButton
58+
[7] scala.swing.examples.Dialogs
59+
[8] scala.swing.examples.GridBagDemo
60+
[9] scala.swing.examples.HelloWorld
61+
[10] scala.swing.examples.LabelTest
62+
[11] scala.swing.examples.LinePainting
63+
[12] scala.swing.examples.ListViewDemo
64+
[13] scala.swing.examples.PopupDemo
65+
[14] scala.swing.examples.SwingApp
66+
[15] scala.swing.examples.TableSelection
67+
[16] scala.swing.examples.UIDemo
6168
6269
Enter number:
6370
```
6471

72+
### Frame with a Button
73+
74+
The following example shows how to plug components and containers together and react to a
75+
mouse click on a button:
76+
77+
```scala
78+
import scala.swing._
79+
80+
new Frame {
81+
title = "Hello world"
82+
83+
contents = new FlowPanel {
84+
contents += new Label("Launch rainbows:")
85+
contents += new Button("Click me") {
86+
reactions += {
87+
case event.ButtonClicked(_) =>
88+
println("All the colours!")
89+
}
90+
}
91+
}
92+
93+
pack()
94+
centerOnScreen()
95+
open()
96+
}
97+
```
6598

6699
## Versions
67100

68101
- The `1.0.x` branch is compiled with JDK 6 and released for Scala 2.10, 2.11. The 1.0.x releases can be used with both Scala versions on JDK 6 or newer.
69102
- The `2.0.x` branch is compiled with JDK 8 and released for Scala 2.11 and 2.12.
70103
- When using Scala 2.11, you can use the Scala swing 2.0.x releases on JDK 6 or newer.
71104
- Scala 2.12 requires you to use JDK 8 (that has nothing to do with scala-swing).
105+
- Version `2.1.0` adds support for Scala 2.13, while dropping Scala 2.10.
72106

73-
The reason to have two 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 soruces to be adjusted.
107+
The reason to have different major versions is to allow for binary incompatible changes. Also, some java-swing classes were
108+
generified in JDK 7 (see [SI-3634](https://issues.scala-lang.org/browse/SI-3634)) and require the scala-swing sources to be adjusted.
74109

75110

76111
## API documentation (Scaladoc)
77112

78-
The API documentation for scala-swing can be found at [http://www.scala-lang.org/documentation/api.html](http://www.scala-lang.org/documentation/api.html).
113+
The API documentation for scala-swing can be found
114+
at [http://www.scala-lang.org/documentation/api.html](http://www.scala-lang.org/documentation/api.html).
79115

80116

81117
## Current Work
82118

83-
Current changes are being made on the `2.0.x` branch.
119+
Current changes are being made on the `work` branch.

build.sbt

+11-9
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,32 @@ scalaModuleSettings
44

55
name := "scala-swing"
66

7-
version := "2.0.4-SNAPSHOT"
7+
version := "2.1.0-SNAPSHOT"
88

9-
scalacOptions ++= Seq("-deprecation", "-feature")
9+
scalacOptions in ThisBuild ++= Seq("-deprecation", "-feature")
1010

1111
// Map[JvmMajorVersion, List[(ScalaVersion, UseForPublishing)]]
1212
scalaVersionsByJvm in ThisBuild := Map(
13-
8 -> List("2.11.12", "2.12.6", "2.13.0-M3").map(_ -> true),
14-
9 -> List("2.11.12", "2.12.6", "2.13.0-M3").map(_ -> false),
15-
10 -> List("2.11.12", "2.12.6", "2.13.0-M3").map(_ -> false),
16-
11 -> List("2.11.12", "2.12.6", "2.13.0-M3").map(_ -> false)
13+
8 -> List("2.11.12", "2.12.8", "2.13.0-M5").map(_ -> true),
14+
9 -> List("2.11.12", "2.12.8", "2.13.0-M5").map(_ -> false),
15+
10 -> List("2.11.12", "2.12.8", "2.13.0-M5").map(_ -> false),
16+
11 -> List("2.11.12", "2.12.8", "2.13.0-M5").map(_ -> false)
1717
)
1818

19+
scalaVersion in ThisBuild := "2.13.0-M5" // for testing
20+
1921
OsgiKeys.exportPackage := Seq(s"scala.swing.*;version=${version.value}")
2022

21-
mimaPreviousVersion := Some("2.0.0")
23+
mimaPreviousVersion := None // Some("2.0.0")
2224

2325
// set the prompt (for this build) to include the project id.
2426
shellPrompt in ThisBuild := { state => Project.extract(state).currentRef.project + "> " }
2527

2628
lazy val swing = project.in(file("."))
2729
.settings(
2830
libraryDependencies += {
29-
val v = if (scalaVersion.value == "2.13.0-M3") "3.0.5-M1" else "3.0.5"
30-
"org.scalatest" %% "scalatest" % v % "test"
31+
val v = if (scalaVersion.value == "2.13.0-M5") "3.0.6-SNAP5" else "3.0.5"
32+
"org.scalatest" %% "scalatest" % v % Test
3133
}
3234
)
3335

examples/src/main/scala/scala/swing/examples/ButtonApp.scala

+1-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import scala.swing._
1212
import scala.swing.event._
1313

1414
object ButtonApp extends SimpleSwingApplication {
15-
def top = new MainFrame {
15+
def top: Frame = new MainFrame {
1616
title = "My Frame"
1717
contents = new GridPanel(2, 2) {
1818
hGap = 3
@@ -27,4 +27,3 @@ object ButtonApp extends SimpleSwingApplication {
2727
size = new Dimension(300, 80)
2828
}
2929
}
30-

examples/src/main/scala/scala/swing/examples/CelsiusConverter.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import scala.swing.event._
1515
* A GUI app to convert celsius to centigrade
1616
*/
1717
object CelsiusConverter extends SimpleSwingApplication {
18-
def top = new MainFrame {
18+
def top: Frame = new MainFrame {
1919
title = "Convert Celsius to Fahrenheit"
2020
val tempCelsius = new TextField
2121
val celsiusLabel = new Label {
@@ -42,7 +42,7 @@ object CelsiusConverter extends SimpleSwingApplication {
4242
}
4343
}
4444
contents = new GridPanel(2, 2) {
45-
contents.append(tempCelsius, celsiusLabel, convertButton, fahrenheitLabel)
45+
contents ++= Seq(tempCelsius, celsiusLabel, convertButton, fahrenheitLabel)
4646
border = Swing.EmptyBorder(10, 10, 10, 10)
4747
}
4848
//defaultButton = Some(convertButton)

examples/src/main/scala/scala/swing/examples/CelsiusConverter2.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ import scala.swing._
1212
import scala.swing.event._
1313

1414
object CelsiusConverter2 extends SimpleSwingApplication {
15-
def newField = new TextField {
15+
def newField: TextField = new TextField {
1616
text = "0"
1717
columns = 5
1818
horizontalAlignment = Alignment.Right
1919
}
2020

21-
val celsius = newField
22-
val fahrenheit = newField
21+
val celsius = newField
22+
val fahrenheit = newField
2323

2424
listenTo(fahrenheit, celsius)
2525
reactions += {
@@ -38,7 +38,7 @@ object CelsiusConverter2 extends SimpleSwingApplication {
3838
border = Swing.EmptyBorder(15, 10, 10, 10)
3939
}
4040

41-
def top = new MainFrame {
41+
def top: Frame = new MainFrame {
4242
title = "Convert Celsius / Fahrenheit"
4343
contents = ui
4444
}

examples/src/main/scala/scala/swing/examples/ColorChooserDemo.scala

+12-11
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
package scala.swing.examples
1010

1111
import java.awt.{Color, Font}
12+
13+
import scala.swing.BorderPanel._
14+
import scala.swing.Swing._
1215
import scala.swing._
1316
import scala.swing.event._
14-
import scala.swing.Swing._
15-
import scala.swing.BorderPanel._
1617

1718
/**
1819
* Demo for ColorChooser.
@@ -21,23 +22,23 @@ import scala.swing.BorderPanel._
2122
2223
*/
2324
object ColorChooserDemo extends SimpleSwingApplication {
24-
def top = new MainFrame {
25+
def top: Frame = new MainFrame {
2526
title = "ColorChooser Demo"
2627
size = new Dimension(400, 400)
2728

2829
contents = ui
2930
}
3031

31-
val banner = new Label("Welcome to Scala Swing") {
32+
val banner: Label = new Label("Welcome to Scala Swing") {
3233
horizontalAlignment = Alignment.Center
3334
foreground = Color.yellow
3435
background = Color.blue
3536
opaque = true
3637
font = new Font("SansSerif", Font.BOLD, 24)
3738
}
3839

39-
def ui = new BorderPanel {
40-
val colorChooser = new ColorChooser {
40+
def ui: BorderPanel = new BorderPanel {
41+
val colorChooser: ColorChooser = new ColorChooser {
4142
reactions += {
4243
case ColorChanged(_, c) =>
4344
banner.foreground = c
@@ -46,13 +47,13 @@ object ColorChooserDemo extends SimpleSwingApplication {
4647

4748
colorChooser.border = TitledBorder(EtchedBorder, "Choose Text Color")
4849

49-
val bannerArea = new BorderPanel {
50+
val bannerArea: BorderPanel = new BorderPanel {
5051
layout(banner) = Position.Center
5152
border = TitledBorder(EtchedBorder, "Banner")
5253
}
5354

5455
// Display a color selection dialog when button pressed
55-
val selectColor = new Button("Choose Background Color") {
56+
val selectColor: Button = new Button("Choose Background Color") {
5657
reactions += {
5758
case ButtonClicked(_) =>
5859
ColorChooser.showDialog(this, "Test", Color.red) match {
@@ -62,8 +63,8 @@ object ColorChooserDemo extends SimpleSwingApplication {
6263
}
6364
}
6465

65-
layout(bannerArea) = Position.North
66-
layout(colorChooser) = Position.Center
67-
layout(selectColor) = Position.South
66+
layout(bannerArea) = Position.North
67+
layout(colorChooser) = Position.Center
68+
layout(selectColor) = Position.South
6869
}
6970
}

examples/src/main/scala/scala/swing/examples/ComboBoxes.scala

+7-6
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88

99
package scala.swing.examples
1010

11-
import scala.swing._
12-
import scala.swing.event._
13-
import java.util.Date
1411
import java.awt.Color
1512
import java.text.SimpleDateFormat
13+
import java.util.Date
14+
1615
import javax.swing.{Icon, ImageIcon}
1716

17+
import scala.swing._
18+
import scala.swing.event._
19+
1820
/**
1921
* Demonstrates how to use combo boxes and custom item renderers.
2022
*
@@ -24,7 +26,7 @@ object ComboBoxes extends SimpleSwingApplication {
2426

2527
import ComboBox._
2628

27-
lazy val ui = new FlowPanel {
29+
lazy val ui: FlowPanel = new FlowPanel {
2830
contents += new ComboBox(List(1, 2, 3, 4))
2931

3032
val patterns = List(
@@ -100,10 +102,9 @@ object ComboBoxes extends SimpleSwingApplication {
100102
contents += iconBox
101103
}
102104

103-
def top = new MainFrame {
105+
def top: Frame = new MainFrame {
104106
title = "ComboBoxes Demo"
105107
contents = ui
106108
}
107-
108109
}
109110

examples/src/main/scala/scala/swing/examples/CountButton.scala

+5-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import scala.swing._
1212
import scala.swing.event._
1313

1414
object CountButton extends SimpleSwingApplication {
15-
def top = new MainFrame {
15+
def top: Frame = new MainFrame {
1616
title = "My Frame"
1717
contents = new GridPanel(2, 2) {
1818
hGap = 3
@@ -27,11 +27,11 @@ object CountButton extends SimpleSwingApplication {
2727
contents += label
2828

2929
listenTo(button)
30-
var nclicks = 0
30+
var nClicks = 0
3131
reactions += {
32-
case ButtonClicked(b) =>
33-
nclicks += 1
34-
label.text = "Number of button clicks: " + nclicks
32+
case ButtonClicked(_) =>
33+
nClicks += 1
34+
label.text = "Number of button clicks: " + nClicks
3535
}
3636
}
3737
}

0 commit comments

Comments
 (0)