Skip to content

Commit eec0251

Browse files
committed
Merge pull request #22 from jacobsallan/swingtut
Rewrite of FrameDemo2.
2 parents 4c18e5f + a9895b8 commit eec0251

File tree

1 file changed

+328
-0
lines changed
  • examples/src/main/scala/scala/swing/examples/tutorials/components

1 file changed

+328
-0
lines changed
Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
/*
2+
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
*
8+
* - Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
*
11+
* - Redistributions in binary form must reproduce the above copyright
12+
* notice, this list of conditions and the following disclaimer in the
13+
* documentation and/or other materials provided with the distribution.
14+
*
15+
* - Neither the name of Oracle or the names of its
16+
* contributors may be used to endorse or promote products derived
17+
* from this software without specific prior written permission.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20+
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21+
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
package scala.swing.examples.tutorials.components
32+
33+
import scala.swing._
34+
import scala.swing.event.ButtonClicked
35+
import javax.swing.{ Box, BoxLayout, JDialog, JFrame, ImageIcon, UIManager }
36+
import java.awt.{ BorderLayout, Color, Component, Dimension, Graphics, Image, Point, Toolkit }
37+
import java.awt.image.BufferedImage
38+
import java.net.URL
39+
40+
/*
41+
* Tutorial: How to Make Frames (Main Windows)
42+
* http://docs.oracle.com/javase/tutorial/uiswing/components/frame.html
43+
*
44+
* Source code reference:
45+
* http://docs.oracle.com/javase/tutorial/uiswing/examples/components/FrameDemo2Project/src/components/FrameDemo2.java
46+
*
47+
* FrameDemo2.scala shows off the window decoration features added in
48+
* 1.4, plus some window positioning code and (optionally)
49+
* setIconImage. It uses the file /scala/swing/examples/tutorials/images/FD.jpg.
50+
*/
51+
class FrameDemo2 {
52+
private var lastLocation: Point = null
53+
private var defaultButton: Button = null
54+
// private val maxX = 500
55+
// private val maxY = 500
56+
//constants for action commands
57+
val NO_DECORATIONS = "no_dec";
58+
val LF_DECORATIONS = "laf_dec";
59+
val WS_DECORATIONS = "ws_dec";
60+
val CREATE_WINDOW = "new_win";
61+
val DEFAULT_ICON = "def_icon";
62+
val FILE_ICON = "file_icon";
63+
val PAINT_ICON = "paint_icon";
64+
65+
//true if the next frame created should have no window decorations
66+
var noDecorations = false;
67+
68+
//true if the next frame created should have setIconImage called
69+
var specifyIcon = false;
70+
71+
//true if the next frame created should have a custom painted icon
72+
var createIcon = false;
73+
74+
val screenSize: Dimension = Toolkit.getDefaultToolkit().getScreenSize()
75+
val maxX = screenSize.width - 50
76+
val maxY = screenSize.height - 50
77+
78+
//Create a new MyFrame object and show it.
79+
def showNewWindow(): Unit = {
80+
//Take care of the no window decorations case.
81+
//NOTE: Unless you really need the functionality
82+
//provided by JFrame, you would usually use a
83+
//Window or JWindow instead of an undecorated JFrame.
84+
val frame: Option[Frame] = if (noDecorations) Some(new MyFrameUndecorated()) else Some(new MyFrame())
85+
//Set window location.
86+
if (frame.isDefined) {
87+
val f = frame.get
88+
if (lastLocation != null) {
89+
//Move the window over and down 40 pixels.
90+
lastLocation.translate(40, 40);
91+
if ((lastLocation.x > maxX) || (lastLocation.y > maxY)) {
92+
lastLocation.setLocation(0, 0);
93+
}
94+
f.location = lastLocation
95+
} else {
96+
lastLocation = f.location
97+
}
98+
99+
//Calling setIconImage sets the icon displayed when the window
100+
//is minimized. Most window systems (or look and feels, if
101+
//decorations are provided by the look and feel) also use this
102+
//icon in the window decorations.
103+
if (specifyIcon) {
104+
if (createIcon) {
105+
//create an icon from scratch
106+
f.iconImage = FrameDemo2.createFDImage()
107+
} else {
108+
//get the icon from a file
109+
f.iconImage = FrameDemo2.getFDImage().get
110+
}
111+
}
112+
}
113+
}
114+
115+
// Create the window-creation controls that go in the main window.
116+
def createOptionControls(frame: Frame): BoxPanel = {
117+
val label1 = new Label("Decoration options for subsequently created frames:")
118+
val bg1 = new ButtonGroup()
119+
val label2 = new Label("Icon options:")
120+
val bg2 = new ButtonGroup()
121+
122+
//Create the buttons
123+
val rb1 = new RadioButton() {
124+
text = "Look and feel decorated"
125+
selected = true
126+
}
127+
bg1.buttons += rb1
128+
//
129+
val rb2 = new RadioButton() {
130+
text = "Window system decorated"
131+
}
132+
bg1.buttons += rb2
133+
//
134+
val rb3 = new RadioButton() {
135+
text = "No decorations"
136+
}
137+
bg1.buttons += rb3
138+
//
139+
val rb4 = new RadioButton() {
140+
text = "Default icon"
141+
selected = true
142+
}
143+
bg2.buttons += rb4
144+
//
145+
val rb5 = new RadioButton() {
146+
text = "Icon from a JPEG file"
147+
}
148+
bg2.buttons += rb5
149+
//
150+
val rb6 = new RadioButton() {
151+
text = "Painted icon"
152+
}
153+
bg2.buttons += rb6
154+
155+
//Add everything to a container.
156+
val box = new BoxPanel(Orientation.Vertical) {
157+
border = Swing.EmptyBorder(10, 10, 10, 10)
158+
contents += label1
159+
contents += Swing.VStrut(5) // spacer
160+
contents += rb1
161+
contents += rb2
162+
contents += rb3
163+
contents += Swing.VStrut(15)
164+
contents += label2
165+
contents += Swing.VStrut(5)
166+
contents += rb4
167+
contents += rb5
168+
contents += rb6
169+
}
170+
171+
frame.listenTo(rb1)
172+
frame.listenTo(rb2)
173+
frame.listenTo(rb3)
174+
frame.listenTo(rb4)
175+
frame.listenTo(rb5)
176+
frame.listenTo(rb6)
177+
frame.reactions += {
178+
case ButtonClicked(`rb1`) =>
179+
noDecorations = false
180+
JFrame.setDefaultLookAndFeelDecorated(true)
181+
case ButtonClicked(`rb2`) =>
182+
noDecorations = false
183+
JFrame.setDefaultLookAndFeelDecorated(false)
184+
case ButtonClicked(`rb3`) =>
185+
noDecorations = true
186+
// No need to set the default look and feel decorated property to false.
187+
// JFrame.setDefaultLookAndFeelDecorated(false)
188+
case ButtonClicked(`rb4`) => specifyIcon = false
189+
case ButtonClicked(`rb5`) =>
190+
specifyIcon = true
191+
createIcon = false
192+
case ButtonClicked(`rb6`) =>
193+
specifyIcon = true
194+
createIcon = true
195+
}
196+
197+
box
198+
}
199+
200+
//Create the button that goes in the main window.
201+
def createButtonPane(frame: Frame): FlowPanel = {
202+
val button = new Button("New window")
203+
defaultButton = button
204+
205+
frame.listenTo(button)
206+
frame.reactions += {
207+
case ButtonClicked(`button`) => showNewWindow()
208+
}
209+
210+
//Center the button in a panel with some space around it.
211+
val pane = new FlowPanel() {
212+
border = Swing.EmptyBorder(5, 5, 5, 5)
213+
contents += button
214+
}
215+
pane
216+
}
217+
218+
}
219+
220+
class MyFrame extends Frame {
221+
title = "A window"
222+
223+
//This button lets you close even an undecorated window.
224+
val button = new Button("Close window") {
225+
xLayoutAlignment = java.awt.Component.CENTER_ALIGNMENT
226+
}
227+
228+
//Place the button near the bottom of the window.
229+
contents = new BoxPanel(Orientation.Vertical) {
230+
contents += Swing.VGlue
231+
contents += button
232+
contents += Swing.VStrut(5)
233+
}
234+
//
235+
listenTo(button)
236+
reactions += {
237+
case ButtonClicked(`button`) =>
238+
visible = false
239+
dispose()
240+
}
241+
preferredSize = new Dimension(150, 150)
242+
pack()
243+
visible = true
244+
override def closeOperation() = {
245+
close
246+
}
247+
}
248+
249+
class MyFrameUndecorated extends Frame with RichWindow.Undecorated {
250+
visible = false
251+
//This button lets you close even an undecorated window.
252+
val button = new Button("Close window") {
253+
xLayoutAlignment = java.awt.Component.CENTER_ALIGNMENT
254+
}
255+
256+
//Place the button near the bottom of the window.
257+
//Undecorated windows are not supported in scala swing.
258+
contents = new BoxPanel(Orientation.Vertical) {
259+
contents += Swing.VGlue
260+
contents += button
261+
contents += Swing.VStrut(5)
262+
}
263+
//
264+
listenTo(button)
265+
reactions += {
266+
case ButtonClicked(`button`) =>
267+
visible = false
268+
dispose()
269+
}
270+
preferredSize = new Dimension(150, 150)
271+
pack()
272+
visible = true
273+
override def closeOperation() = {
274+
close
275+
}
276+
}
277+
278+
object FrameDemo2 extends SimpleSwingApplication {
279+
//Creates an icon-worthy Image from scratch.
280+
def createFDImage(): Image = {
281+
//Create a 16x16 pixel image.
282+
val bi = new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB)
283+
//Draw into it.
284+
val g: Graphics = bi.getGraphics()
285+
g.setColor(Color.BLACK);
286+
g.fillRect(0, 0, 15, 15)
287+
g.setColor(Color.RED)
288+
g.fillOval(5, 3, 6, 6)
289+
290+
//Clean up.
291+
g.dispose()
292+
293+
//Return it.
294+
bi
295+
}
296+
297+
// Returns an Image Option or None.
298+
def getFDImage(): Option[Image] = {
299+
val imgURL: URL = getClass().getResource("/scala/swing/examples/tutorials/images/FD.jpg");
300+
if (imgURL != null) {
301+
return Some(new ImageIcon(imgURL).getImage)
302+
} else {
303+
return None
304+
}
305+
}
306+
307+
lazy val top = new Frame() {
308+
title = "FrameDemo2"
309+
//Use the Java look and feel. This needs to be done before the frame is created
310+
//so the companion object FrameDemo2 cannot simply extend SimpleSwingApplcation.
311+
try {
312+
UIManager.setLookAndFeel(
313+
UIManager.getCrossPlatformLookAndFeelClassName());
314+
} catch {
315+
case e: Exception => ;
316+
}
317+
//Make sure we have nice window decorations.
318+
JFrame.setDefaultLookAndFeelDecorated(true);
319+
JDialog.setDefaultLookAndFeelDecorated(true);
320+
//Create and set up the content pane.
321+
val demo = new FrameDemo2();
322+
}
323+
val bp: BorderPanel = new BorderPanel() {
324+
layout(top.demo.createOptionControls(top)) = BorderPanel.Position.Center
325+
layout(top.demo.createButtonPane(top)) = BorderPanel.Position.South
326+
}
327+
top.contents = bp
328+
}

0 commit comments

Comments
 (0)