From 5906c86214c80de9aaf97005c88c6092a6813951 Mon Sep 17 00:00:00 2001 From: Ingo Maier Date: Mon, 1 Jun 2009 18:30:23 +0000 Subject: bigger commit for 2.8 preview --- src/swing/scala/swing/Button.scala | 4 + src/swing/scala/swing/Component.scala | 78 ++++---- src/swing/scala/swing/Dialog.scala | 82 -------- src/swing/scala/swing/FileChooser.scala | 29 ++- src/swing/scala/swing/Frame.scala | 67 ------- src/swing/scala/swing/GUIApplication.scala | 19 +- src/swing/scala/swing/Key.scala | 194 ------------------ src/swing/scala/swing/Menu.scala | 2 +- src/swing/scala/swing/Oriented.scala | 4 +- src/swing/scala/swing/ProgressBar.scala | 3 +- src/swing/scala/swing/RichWindows.scala | 165 ++++++++++++++++ src/swing/scala/swing/RootPanel.scala | 2 +- src/swing/scala/swing/ScrollPane.scala | 6 +- src/swing/scala/swing/Separator.scala | 2 +- src/swing/scala/swing/SequentialContainer.scala | 2 +- src/swing/scala/swing/SimpleGUIApplication.scala | 14 ++ src/swing/scala/swing/SplitPane.scala | 7 +- src/swing/scala/swing/Swing.scala | 14 +- src/swing/scala/swing/SwingActor.scala | 22 +++ src/swing/scala/swing/UIElement.scala | 34 ++++ src/swing/scala/swing/Views.scala | 7 - src/swing/scala/swing/Window.scala | 64 ++++++ src/swing/scala/swing/event/InputEvent.scala | 7 +- src/swing/scala/swing/event/Key.scala | 216 +++++++++++++++++++++ src/swing/scala/swing/event/KeyEvent.scala | 29 +++ src/swing/scala/swing/event/MouseEvent.scala | 78 +++++--- src/swing/scala/swing/event/WindowActivated.scala | 2 +- src/swing/scala/swing/event/WindowClosed.scala | 2 +- src/swing/scala/swing/event/WindowClosing.scala | 2 +- .../scala/swing/event/WindowDeactivated.scala | 2 +- .../scala/swing/event/WindowDeiconified.scala | 2 +- src/swing/scala/swing/event/WindowEvent.scala | 2 +- src/swing/scala/swing/event/WindowIconified.scala | 2 +- src/swing/scala/swing/event/WindowOpened.scala | 2 +- src/swing/scala/swing/test/CelsiusConverter2.scala | 6 +- src/swing/scala/swing/test/ComboBoxes.scala | 2 +- src/swing/scala/swing/test/Dialogs.scala | 31 ++- src/swing/scala/swing/test/GridBagDemo.scala | 2 +- src/swing/scala/swing/test/HelloWorld.scala | 5 +- src/swing/scala/swing/test/LabelTest.scala | 24 +++ src/swing/scala/swing/test/TableSelection.scala | 2 +- src/swing/scala/swing/test/UIDemo.scala | 1 + 42 files changed, 774 insertions(+), 466 deletions(-) delete mode 100644 src/swing/scala/swing/Dialog.scala delete mode 100644 src/swing/scala/swing/Frame.scala delete mode 100644 src/swing/scala/swing/Key.scala create mode 100644 src/swing/scala/swing/RichWindows.scala create mode 100644 src/swing/scala/swing/SwingActor.scala delete mode 100644 src/swing/scala/swing/Views.scala create mode 100644 src/swing/scala/swing/Window.scala create mode 100644 src/swing/scala/swing/event/Key.scala create mode 100644 src/swing/scala/swing/event/KeyEvent.scala create mode 100644 src/swing/scala/swing/test/LabelTest.scala (limited to 'src') diff --git a/src/swing/scala/swing/Button.scala b/src/swing/scala/swing/Button.scala index 0aa93ae45b..673ccd9629 100644 --- a/src/swing/scala/swing/Button.scala +++ b/src/swing/scala/swing/Button.scala @@ -3,6 +3,10 @@ package scala.swing import javax.swing._ import event._ +object Button { + def apply(text0: String)(op: => Unit) = new Button(Action(text0)(op)) +} + /** * A button that can be clicked, usually to perform some action. * diff --git a/src/swing/scala/swing/Component.scala b/src/swing/scala/swing/Component.scala index 4ca5149f87..4c5c4d2e18 100644 --- a/src/swing/scala/swing/Component.scala +++ b/src/swing/scala/swing/Component.scala @@ -2,7 +2,7 @@ package scala.swing import event._ -import java.awt.{Dimension, Point} +import java.awt.{Dimension, Point, Graphics, Graphics2D} import java.awt.event._ import javax.swing.JComponent import javax.swing.border.Border @@ -11,15 +11,6 @@ import javax.swing.border.Border * Utility methods, mostly for wrapping components. */ object Component { - private val ClientKey = "scala.swingWrapper" - - /** - * Returns the wrapper for a given peer, null if there is no wrapper - * for the given component. - */ - protected[swing] def wrapperFor[C<:Component](c: javax.swing.JComponent): C = - c.getClientProperty(ClientKey).asInstanceOf[C] - /** * Wraps a given Java Swing Component into a new wrapper. */ @@ -42,28 +33,26 @@ object Component { abstract class Component extends UIElement with Publisher { override lazy val peer: javax.swing.JComponent = new javax.swing.JComponent with SuperMixin {} var initP: JComponent = null - peer.putClientProperty(Component.ClientKey, this) /** * This trait is used to redirect certain calls from the peer to the wrapper * and back. Useful to expose methods that can be customized by overriding. */ protected trait SuperMixin extends JComponent { - override def paintComponent(g: java.awt.Graphics) { - Component.this.paintComponent(g) + override def paintComponent(g: Graphics) { + Component.this.paintComponent(g.asInstanceOf[Graphics2D]) } - def __super__paintComponent(g: java.awt.Graphics) { + def __super__paintComponent(g: Graphics) { super.paintComponent(g) } - override def paint(g: java.awt.Graphics) { - Component.this.paint(g) + override def paint(g: Graphics) { + Component.this.paint(g.asInstanceOf[Graphics2D]) } - def __super__paint(g: java.awt.Graphics) { + def __super__paint(g: Graphics) { super.paint(g) } } - /** * Used by certain layout managers, e.g., BoxLayout or OverlayLayout to * align components relative to each other. @@ -90,7 +79,7 @@ abstract class Component extends UIElement with Publisher { } def inputVerifier_=(v: this.type => Boolean) { peer.setInputVerifier(new javax.swing.InputVerifier { - def verify(c: javax.swing.JComponent) = v(Component.wrapperFor(c)) + def verify(c: javax.swing.JComponent) = v(UIElement.cachedWrapper(c)) }) } @@ -99,7 +88,7 @@ abstract class Component extends UIElement with Publisher { } def verifyOnTraversal_=(v: (Component, Component) => Boolean) { peer.setInputVerifier(new javax.swing.InputVerifier { - def verify(c: javax.swing.JComponent) = v(Component.wrapperFor(c)) + def verify(c: javax.swing.JComponent) = v(UIElement.cachedWrapper(c)) }) }*/ @@ -120,7 +109,7 @@ abstract class Component extends UIElement with Publisher { peer.addFocusListener(new java.awt.event.FocusListener { def other(e: java.awt.event.FocusEvent) = e.getOppositeComponent match { - case c: JComponent => Some(Component.wrapperFor(c)) + case c: JComponent => Some(UIElement.cachedWrapper(c)) case _ => None } @@ -132,11 +121,13 @@ abstract class Component extends UIElement with Publisher { } }) + @deprecated lazy val Mouse = mouse + /** * Contains publishers for various mouse events. They are separated for * efficiency reasons. */ - object Mouse { + object mouse { /** * Publishes clicks, presses and releases. */ @@ -145,16 +136,13 @@ abstract class Component extends UIElement with Publisher { def mouseEntered(e: java.awt.event.MouseEvent) { } def mouseExited(e: java.awt.event.MouseEvent) { } def mouseClicked(e: java.awt.event.MouseEvent) { - publish(MouseClicked(Component.wrapperFor(e.getSource.asInstanceOf[JComponent]), - e.getPoint, e.getModifiersEx, e.getClickCount, e.isPopupTrigger)(e.getWhen)) + publish(new MouseClicked(e)) } def mousePressed(e: java.awt.event.MouseEvent) { - publish(MousePressed(Component.wrapperFor(e.getSource.asInstanceOf[JComponent]), - e.getPoint, e.getModifiersEx, e.getClickCount, e.isPopupTrigger)(e.getWhen)) + publish(new MousePressed(e)) } def mouseReleased(e: java.awt.event.MouseEvent) { - publish(MouseReleased(Component.wrapperFor(e.getSource.asInstanceOf[JComponent]), - e.getPoint, e.getModifiersEx, e.getClickCount, e.isPopupTrigger)(e.getWhen)) + publish(new MouseReleased(e)) } }) } @@ -164,12 +152,10 @@ abstract class Component extends UIElement with Publisher { val moves: Publisher = new Publisher { peer.addMouseListener(new MouseListener { def mouseEntered(e: java.awt.event.MouseEvent) { - publish(MouseEntered(Component.wrapperFor(e.getSource.asInstanceOf[JComponent]), - e.getPoint, e.getModifiersEx)(e.getWhen)) + publish(new MouseEntered(e)) } def mouseExited(e: java.awt.event.MouseEvent) { - publish(MouseExited(Component.wrapperFor(e.getSource.asInstanceOf[JComponent]), - e.getPoint, e.getModifiersEx)(e.getWhen)) + publish(new MouseExited(e)) } def mouseClicked(e: java.awt.event.MouseEvent) {} def mousePressed(e: java.awt.event.MouseEvent) { } @@ -177,12 +163,10 @@ abstract class Component extends UIElement with Publisher { }) peer.addMouseMotionListener(new MouseMotionListener { def mouseMoved(e: java.awt.event.MouseEvent) { - publish(MouseMoved(Component.wrapperFor(e.getSource.asInstanceOf[JComponent]), - e.getPoint, e.getModifiersEx)(e.getWhen)) + publish(new MouseMoved(e)) } def mouseDragged(e: java.awt.event.MouseEvent) { - publish(MouseDragged(Component.wrapperFor(e.getSource.asInstanceOf[JComponent]), - e.getPoint, e.getModifiersEx)(e.getWhen)) + publish(new MouseDragged(e)) } }) } @@ -194,14 +178,26 @@ abstract class Component extends UIElement with Publisher { // mouse wheel events if there is a listener installed. See ticket #1442. lazy val l = new MouseWheelListener { def mouseWheelMoved(e: java.awt.event.MouseWheelEvent) { - publish(MouseWheelMoved(Component.wrapperFor(e.getSource.asInstanceOf[JComponent]), - e.getPoint, e.getModifiersEx, e.getWheelRotation)(e.getWhen)) } + publish(new MouseWheelMoved(e)) } } def onFirstSubscribe() = peer.addMouseWheelListener(l) def onLastUnsubscribe() = peer.removeMouseWheelListener(l) } } + object keys extends Publisher { + peer.addKeyListener(new KeyListener { + def keyPressed(e: java.awt.event.KeyEvent) { publish(new KeyPressed(e)) } + def keyReleased(e: java.awt.event.KeyEvent) { publish(new KeyReleased(e)) } + def keyTyped(e: java.awt.event.KeyEvent) { publish(new KeyTyped(e)) } + }) + } + + def focusable: Boolean = peer.isFocusable + def focusable_=(b: Boolean) = peer.setFocusable(b) + def requestFocus() = peer.requestFocus() + def requestFocusInWindow() = peer.requestFocusInWindow() + def hasFocus: Boolean = peer.isFocusOwner peer.addPropertyChangeListener(new java.beans.PropertyChangeListener { def propertyChange(e: java.beans.PropertyChangeEvent) { @@ -224,19 +220,19 @@ abstract class Component extends UIElement with Publisher { def revalidate() { peer.revalidate() } - def requestFocus() { peer.requestFocus() } + /** * For custom painting, users should usually override this method. */ - protected def paintComponent(g: java.awt.Graphics) { + protected def paintComponent(g: Graphics2D) { peer match { case peer: SuperMixin => peer.__super__paintComponent(g) case _ => // it's a wrapper created on the fly } } - protected def paint(g: java.awt.Graphics) { + protected def paint(g: Graphics2D) { peer match { case peer: SuperMixin => peer.__super__paint(g) case _ => // it's a wrapper created on the fly diff --git a/src/swing/scala/swing/Dialog.scala b/src/swing/scala/swing/Dialog.scala deleted file mode 100644 index 1de0f27130..0000000000 --- a/src/swing/scala/swing/Dialog.scala +++ /dev/null @@ -1,82 +0,0 @@ -package scala.swing - -import javax.swing.{Icon, JOptionPane} -import Swing._ - -/** - * Simple predefined dialogs. - * - * @see javax.swing.JOptionPane - */ -object Dialog { - /** - * The message type of a dialog. - */ - object Message extends Enumeration { - val Error = Value(JOptionPane.ERROR_MESSAGE) - val Info = Value(JOptionPane.INFORMATION_MESSAGE) - val Warning = Value(JOptionPane.WARNING_MESSAGE) - val Question = Value(JOptionPane.QUESTION_MESSAGE) - val Plain = Value(JOptionPane.PLAIN_MESSAGE) - } - - /** - * The possible answers a user can select. - */ - object Options extends Enumeration { - val Default = Value(JOptionPane.DEFAULT_OPTION) - val YesNo = Value(JOptionPane.YES_NO_OPTION) - val YesNoCancel = Value(JOptionPane.YES_NO_CANCEL_OPTION) - val OkCancel = Value(JOptionPane.OK_CANCEL_OPTION) - } - - /** - * The selected result of dialog. - */ - object Result extends Enumeration { - val Yes = Value(JOptionPane.YES_OPTION) - val Ok = Yes - val No = Value(JOptionPane.NO_OPTION) - val Cancel = Value(JOptionPane.CANCEL_OPTION) - val Closed = Value(JOptionPane.CLOSED_OPTION) - } - - - def showConfirmation(parent: Component, message: String, title: String, - optionType: Options.Value, messageType: Message.Value, icon: Icon): Result.Value = - Result(JOptionPane.showConfirmDialog(nullPeer(parent), message, title, - optionType.id, messageType.id, Swing.wrapIcon(icon))) - def showConfirmation(parent: Component, message: String, title: String, - optionType: Options.Value): Result.Value = - Result(JOptionPane.showConfirmDialog(nullPeer(parent), message, title, - optionType.id)) - - def showOptions(parent: Component, message: String, title: String, - optionType: Options.Value, messageType: Message.Value, icon: Icon, - entries: Seq[Any], initialEntry: Int): Result.Value = { - val r = JOptionPane.showOptionDialog(nullPeer(parent), message, title, - optionType.id, messageType.id, Swing.wrapIcon(icon), - entries.map(_.asInstanceOf[AnyRef]).toArray, entries(initialEntry)) - Result(r) - } - - def showInput[A](parent: Component, message: String, title: String, - messageType: Message.Value, icon: Icon, - entries: Seq[A], initialEntry: A): Option[A] = { - val e = if (entries.isEmpty) null - else entries.map(_.asInstanceOf[AnyRef]).toArray - val r = JOptionPane.showInputDialog(nullPeer(parent), message, title, - messageType.id, Swing.wrapIcon(icon), - e, initialEntry) - Swing.toOption(r) - } - def showMessage(parent: Component, message: String, title: String, - messageType: Message.Value, icon: Icon) { - JOptionPane.showMessageDialog(nullPeer(parent), message, title, - messageType.id, Swing.wrapIcon(icon)) - } - - def showMessage(parent: Component, message: String) { - JOptionPane.showMessageDialog(nullPeer(parent), message) - } -} diff --git a/src/swing/scala/swing/FileChooser.scala b/src/swing/scala/swing/FileChooser.scala index 412649051a..d52e69a282 100644 --- a/src/swing/scala/swing/FileChooser.scala +++ b/src/swing/scala/swing/FileChooser.scala @@ -48,7 +48,7 @@ class FileChooser(dir: File) { def title: String = peer.getDialogTitle def title_=(t: String) { peer.setDialogTitle(t) } - def accessory: Component = Component.wrapperFor(peer.getAccessory) + def accessory: Component = UIElement.cachedWrapper(peer.getAccessory) def accessory_=(c: Component) { peer.setAccessory(c.peer) } def fileHidingEnabled: Boolean = peer.isFileHidingEnabled @@ -73,4 +73,31 @@ class FileChooser(dir: File) { def traversable(f: File) = peer.isTraversable(f) def acceptAllFileFilter = peer.getAcceptAllFileFilter + + /*peer.addPropertyChangeListener(new java.beans.PropertyChangeListener { + def propertyChange(e: java.beans.PropertyChangeEvent) { + import JFileChooser._ + e.getPropertyName match { + case APPROVE_BUTTON_TEXT_CHANGED_PROPERTY => + case ACCESSORY_CHANGED_PROPERTY => + case APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY => + case APPROVE_BUTTON_TEXT_CHANGED_PROPERTY => + case APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY => + case CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY => + case CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY => + case DIALOG_TITLE_CHANGED_PROPERTY => + case DIALOG_TYPE_CHANGED_PROPERTY => + case DIRECTORY_CHANGED_PROPERTY => + case FILE_FILTER_CHANGED_PROPERTY => + case FILE_HIDING_CHANGED_PROPERTY => + case FILE_SELECTION_MODE_CHANGED_PROPERTY => + case FILE_SYSTEM_VIEW_CHANGED_PROPERTY => + case FILE_VIEW_CHANGED_PROPERTY => + case MULTI_SELECTION_ENABLED_CHANGED_PROPERTY => + case SELECTED_FILE_CHANGED_PROPERTY => + case SELECTED_FILES_CHANGED_PROPERTY => + case _ => + } + } + })*/ } diff --git a/src/swing/scala/swing/Frame.scala b/src/swing/scala/swing/Frame.scala deleted file mode 100644 index af80fceebd..0000000000 --- a/src/swing/scala/swing/Frame.scala +++ /dev/null @@ -1,67 +0,0 @@ -package scala.swing - -import java.awt.{Image, Point} -import javax.swing._ -import event._ - -/** - * A window with decoration such as a title, border, and action buttons. - * - * @see javax.swing.JFrame - */ -class Frame extends UIElement with RootPanel with Publisher { - override lazy val peer: JFrame = new JFrame with SuperMixin - def title: String = peer.getTitle - def title_=(s: String) = peer.setTitle(s) - - protected trait SuperMixin extends JFrame { - override protected def processWindowEvent(e: java.awt.event.WindowEvent) { - super.processWindowEvent(e) - if (e.getID() == java.awt.event.WindowEvent.WINDOW_CLOSING) - closeOperation() - } - } - - /** - * This method is called when the window is closing, after all other window - * event listeners have been processed. - */ - def closeOperation() {} - - override def contents_=(c: Component) { - super.contents_=(c) - peer.pack() // pack also validates, which is generally required after an add - } - def defaultButton: Option[Button] = - Swing.toOption(peer.getRootPane.getDefaultButton).map(Component.wrapperFor(_)) - def defaultButton_=(b: Button) { - peer.getRootPane.setDefaultButton(b.peer) - } - def defaultButton_=(b: Option[Button]) { - peer.getRootPane.setDefaultButton(Swing.toNull(b.map(_.peer))) - } - - def dispose() { peer.dispose() } - - def pack(): this.type = { peer.pack(); this } - - def menuBar: MenuBar = Component.wrapperFor(peer.getJMenuBar) - def menuBar_=(m: MenuBar) = peer.setJMenuBar(m.peer) - - def setLocationRelativeTo(c: UIElement) { peer.setLocationRelativeTo(c.peer) } - def centerOnScreen() { peer.setLocationRelativeTo(null) } - def location_=(p: Point) { peer.setLocation(p) } - - def iconImage: Image = peer.getIconImage - def iconImage_=(i: Image) { peer.setIconImage(i) } - - peer.addWindowListener(new java.awt.event.WindowListener { - def windowActivated(e: java.awt.event.WindowEvent) { publish(WindowActivated(Frame.this)) } - def windowClosed(e: java.awt.event.WindowEvent) { publish(WindowClosed(Frame.this)) } - def windowClosing(e: java.awt.event.WindowEvent) { publish(WindowClosing(Frame.this)) } - def windowDeactivated(e: java.awt.event.WindowEvent) { publish(WindowDeactivated(Frame.this)) } - def windowDeiconified(e: java.awt.event.WindowEvent) { publish(WindowDeiconified(Frame.this)) } - def windowIconified(e: java.awt.event.WindowEvent) { publish(WindowIconified(Frame.this)) } - def windowOpened(e: java.awt.event.WindowEvent) { publish(WindowOpened(Frame.this)) } - }) -} diff --git a/src/swing/scala/swing/GUIApplication.scala b/src/swing/scala/swing/GUIApplication.scala index 999ef3971f..04133788eb 100644 --- a/src/swing/scala/swing/GUIApplication.scala +++ b/src/swing/scala/swing/GUIApplication.scala @@ -3,21 +3,18 @@ package scala.swing import javax.swing._ import event.Event +/** + * Convenience class with utility methods for GUI applications. + */ class GUIApplication { - //def defaultLookAndFeelDecorated: Boolean = true - def init() = { - //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) - //JFrame.setDefaultLookAndFeelDecorated(defaultLookAndFeelDecorated) - } + /** + * Called before the GUI is created. Override to customize. + */ + def init() {} /** * Initializes the framework and runs the given program. */ - def run(prog: => Unit): Unit = - SwingUtilities.invokeLater { - new Runnable() { - def run() = { init(); prog } - } - } + def run(prog: => Unit) = Swing.onEDT { init(); prog } } diff --git a/src/swing/scala/swing/Key.scala b/src/swing/scala/swing/Key.scala deleted file mode 100644 index 487e88bb4f..0000000000 --- a/src/swing/scala/swing/Key.scala +++ /dev/null @@ -1,194 +0,0 @@ -package scala.swing - -object Key extends Enumeration { - import java.awt.event.KeyEvent._ - - val Enter = Value(VK_ENTER) - val BackSpace = Value(VK_BACK_SPACE) - val Tab = Value(VK_TAB) - val Cancel = Value(VK_CANCEL) - val Clear = Value(VK_CLEAR) - val Shift = Value(VK_SHIFT) - val Control = Value(VK_CONTROL) - val Alt = Value(VK_ALT) - val Pause = Value(VK_PAUSE) - val CapsLock = Value(VK_CAPS_LOCK) - val Escape = Value(VK_ESCAPE) - val Space = Value(VK_SPACE) - val PageUp = Value(VK_PAGE_UP) - val PageDown = Value(VK_PAGE_DOWN) - val End = Value(VK_END) - val Home = Value(VK_HOME) - val Left = Value(VK_LEFT) - val Up = Value(VK_UP) - val Right = Value(VK_RIGHT) - val Down = Value(VK_DOWN) - val Comma = Value(VK_COMMA) - val Minus = Value(VK_MINUS) - val Period = Value(VK_PERIOD) - val Slash = Value(VK_SLASH) - val Key0 = Value(VK_0) - val Key1 = Value(VK_1) - val Key2 = Value(VK_2) - val Key3 = Value(VK_3) - val Key4 = Value(VK_4) - val Key5 = Value(VK_5) - val Key6 = Value(VK_6) - val Key7 = Value(VK_7) - val Key8 = Value(VK_8) - val Key9 = Value(VK_9) - val Semicolon = Value(VK_SEMICOLON) - val Equals = Value(VK_EQUALS) - val A = Value(VK_A) - val B = Value(VK_B) - val C = Value(VK_C) - val D = Value(VK_D) - val E = Value(VK_E) - val F = Value(VK_F) - val G = Value(VK_G) - val H = Value(VK_H) - val I = Value(VK_I) - val J = Value(VK_J) - val K = Value(VK_K) - val L = Value(VK_L) - val M = Value(VK_M) - val N = Value(VK_N) - val O = Value(VK_O) - val P = Value(VK_P) - val Q = Value(VK_Q) - val R = Value(VK_R) - val S = Value(VK_S) - val T = Value(VK_T) - val U = Value(VK_U) - val V = Value(VK_V) - val W = Value(VK_W) - val X = Value(VK_X) - val Y = Value(VK_Y) - val Z = Value(VK_Z) - val OpenBracket = Value(VK_OPEN_BRACKET) - val BackSlash = Value(VK_BACK_SLASH) - val CloseBracket = Value(VK_CLOSE_BRACKET) - val Numpad0 = Value(VK_NUMPAD0) - val Numpad1 = Value(VK_NUMPAD1) - val Numpad2 = Value(VK_NUMPAD2) - val Numpad3 = Value(VK_NUMPAD3) - val Numpad4 = Value(VK_NUMPAD4) - val Numpad5 = Value(VK_NUMPAD5) - val Numpad6 = Value(VK_NUMPAD6) - val Numpad7 = Value(VK_NUMPAD7) - val Numpad8 = Value(VK_NUMPAD8) - val Numpad9 = Value(VK_NUMPAD9) - val Multiply = Value(VK_MULTIPLY) - val Add = Value(VK_ADD) - val Separator = Value(VK_SEPARATOR) - val Subtract = Value(VK_SUBTRACT) - val Decimal = Value(VK_DECIMAL) - val Divide = Value(VK_DIVIDE) - val Delete = Value(VK_DELETE) - val NumLock = Value(VK_NUM_LOCK) - val ScrollLock = Value(VK_SCROLL_LOCK) - val F1 = Value(VK_F1) - val F2 = Value(VK_F2) - val F3 = Value(VK_F3) - val F4 = Value(VK_F4) - val F5 = Value(VK_F5) - val F6 = Value(VK_F6) - val F7 = Value(VK_F7) - val F8 = Value(VK_F8) - val F9 = Value(VK_F9) - val F10 = Value(VK_F10) - val F11 = Value(VK_F11) - val F12 = Value(VK_F12) - val F13 = Value(VK_F13) - val F14 = Value(VK_F14) - val F15 = Value(VK_F15) - val F16 = Value(VK_F16) - val F17 = Value(VK_F17) - val F18 = Value(VK_F18) - val F19 = Value(VK_F19) - val F20 = Value(VK_F20) - val F21 = Value(VK_F21) - val F22 = Value(VK_F22) - val F23 = Value(VK_F23) - val F24 = Value(VK_F24) - val Printscreen = Value(VK_PRINTSCREEN) - val Insert = Value(VK_INSERT) - val Help = Value(VK_HELP) - val Meta = Value(VK_META) - val BackQuote = Value(VK_BACK_QUOTE) - val Quote = Value(VK_QUOTE) - val KpUp = Value(VK_KP_UP) - val KpDown = Value(VK_KP_DOWN) - val KpLeft = Value(VK_KP_LEFT) - val KpRight = Value(VK_KP_RIGHT) - val DeadGrave = Value(VK_DEAD_GRAVE) - val DeadAcute = Value(VK_DEAD_ACUTE) - val DeadCircumflex = Value(VK_DEAD_CIRCUMFLEX) - val DeadTilde = Value(VK_DEAD_TILDE) - val DeadMacron = Value(VK_DEAD_MACRON) - val DeadBreve = Value(VK_DEAD_BREVE) - val DeadAbovedot = Value(VK_DEAD_ABOVEDOT) - val DeadDiaeresis = Value(VK_DEAD_DIAERESIS) - val DeadAbovering = Value(VK_DEAD_ABOVERING) - val DeadDoubleacute = Value(VK_DEAD_DOUBLEACUTE) - val DeadCaron = Value(VK_DEAD_CARON) - val DeadCedilla = Value(VK_DEAD_CEDILLA) - val DeadOgonek = Value(VK_DEAD_OGONEK) - val DeadIota = Value(VK_DEAD_IOTA) - val DeadVoicedSound = Value(VK_DEAD_VOICED_SOUND) - val DeadSemivoicedSound = Value(VK_DEAD_SEMIVOICED_SOUND) - val Ampersand = Value(VK_AMPERSAND) - val Asterisk = Value(VK_ASTERISK) - val Quotedbl = Value(VK_QUOTEDBL) - val Less = Value(VK_LESS) - val Greater = Value(VK_GREATER) - val Braceleft = Value(VK_BRACELEFT) - val Braceright = Value(VK_BRACERIGHT) - val At = Value(VK_AT) - val Colon = Value(VK_COLON) - val Circumflex = Value(VK_CIRCUMFLEX) - val Dollar = Value(VK_DOLLAR) - val EuroSign = Value(VK_EURO_SIGN) - val ExclamationMark = Value(VK_EXCLAMATION_MARK) - val InvertedExclamationMark = Value(VK_INVERTED_EXCLAMATION_MARK) - val LeftParenthesis = Value(VK_LEFT_PARENTHESIS) - val NumberSign = Value(VK_NUMBER_SIGN) - val Plus = Value(VK_PLUS) - val RightParenthesis = Value(VK_RIGHT_PARENTHESIS) - val Underscore = Value(VK_UNDERSCORE) - val Windows = Value(VK_WINDOWS) - val ContextMenu = Value(VK_CONTEXT_MENU) - val Final = Value(VK_FINAL) - val Convert = Value(VK_CONVERT) - val Nonconvert = Value(VK_NONCONVERT) - val Accept = Value(VK_ACCEPT) - val Modechange = Value(VK_MODECHANGE) - val Kana = Value(VK_KANA) - val Kanji = Value(VK_KANJI) - val Alphanumeric = Value(VK_ALPHANUMERIC) - val Katakana = Value(VK_KATAKANA) - val Hiragana = Value(VK_HIRAGANA) - val FullWidth = Value(VK_FULL_WIDTH) - val HalfWidth = Value(VK_HALF_WIDTH) - val RomanCharacters = Value(VK_ROMAN_CHARACTERS) - val AllCandidates = Value(VK_ALL_CANDIDATES) - val PreviousCandidate = Value(VK_PREVIOUS_CANDIDATE) - val CodeInput = Value(VK_CODE_INPUT) - val JapaneseKatakana = Value(VK_JAPANESE_KATAKANA) - val JapaneseHiragana = Value(VK_JAPANESE_HIRAGANA) - val JapaneseRoman = Value(VK_JAPANESE_ROMAN) - val KanaLock = Value(VK_KANA_LOCK) - val InputMethodOnOff = Value(VK_INPUT_METHOD_ON_OFF) - val Cut = Value(VK_CUT) - val Copy = Value(VK_COPY) - val Paste = Value(VK_PASTE) - val Undo = Value(VK_UNDO) - val Again = Value(VK_AGAIN) - val Find = Value(VK_FIND) - val Props = Value(VK_PROPS) - val Stop = Value(VK_STOP) - val Compose = Value(VK_COMPOSE) - val AltGraph = Value(VK_ALT_GRAPH) - val Begin = Value(VK_BEGIN) - val Undefined = Value(VK_UNDEFINED) -} diff --git a/src/swing/scala/swing/Menu.scala b/src/swing/scala/swing/Menu.scala index 7f85688125..3d7c71a8a0 100644 --- a/src/swing/scala/swing/Menu.scala +++ b/src/swing/scala/swing/Menu.scala @@ -14,7 +14,7 @@ class MenuBar extends Component with SequentialContainer.Wrapper { def menus: Seq[Menu] = contents.filter(_.isInstanceOf[Menu]).map(_.asInstanceOf[Menu]) // Not implemented by Swing - //def helpMenu: Menu = Component.wrapperFor(peer.getHelpMenu) + //def helpMenu: Menu = UIElement.cachedWrapper(peer.getHelpMenu) //def helpMenu_=(m: Menu) { peer.setHelpMenu(m.peer) } } diff --git a/src/swing/scala/swing/Oriented.scala b/src/swing/scala/swing/Oriented.scala index b9caff5da2..4403b06810 100644 --- a/src/swing/scala/swing/Oriented.scala +++ b/src/swing/scala/swing/Oriented.scala @@ -4,7 +4,9 @@ package scala.swing * Something that can have an orientation. */ trait Oriented { - def peer: javax.swing.JComponent { + def peer: javax.swing.JComponent with OrientedMixin + + protected trait OrientedMixin { def getOrientation(): Int def setOrientation(n: Int) } diff --git a/src/swing/scala/swing/ProgressBar.scala b/src/swing/scala/swing/ProgressBar.scala index 68d815f181..1dd7f547be 100644 --- a/src/swing/scala/swing/ProgressBar.scala +++ b/src/swing/scala/swing/ProgressBar.scala @@ -10,7 +10,8 @@ import event._ * @see javax.swing.JProgressBar */ class ProgressBar extends Component with Orientable { - override lazy val peer: javax.swing.JProgressBar = new javax.swing.JProgressBar + override lazy val peer: javax.swing.JProgressBar with OrientedMixin = + new javax.swing.JProgressBar with OrientedMixin def min: Int = peer.getMinimum def min_=(v: Int) { peer.setMinimum(v) } diff --git a/src/swing/scala/swing/RichWindows.scala b/src/swing/scala/swing/RichWindows.scala new file mode 100644 index 0000000000..f3e8208580 --- /dev/null +++ b/src/swing/scala/swing/RichWindows.scala @@ -0,0 +1,165 @@ +package scala.swing + +import java.awt.{Image, Window => AWTWindow} +import javax.swing._ +import Swing._ + +object RichWindow { + /** + * Mixin this trait if you want an undecorated window. + */ + trait Undecorated extends RichWindow { + peer.setUndecorated(true) + } +} + +/** + * A window that adds some functionality to the plain Window class and serves as + * the common base class for frames and dialogs. + * + * Implementation note: this class is sealed since we need to know that a rich + * window is either a dialog or a frame at some point. + */ +sealed trait RichWindow extends Window { + def peer: AWTWindow with InterfaceMixin + + trait InterfaceMixin extends super.InterfaceMixin { + def getJMenuBar: JMenuBar + def setJMenuBar(b: JMenuBar) + def setUndecorated(b: Boolean) + def setTitle(s: String) + def getTitle: String + def setResizable(b: Boolean) + def isResizable: Boolean + } + + def title: String = peer.getTitle + def title_=(s: String) = peer.setTitle(s) + + def menuBar: MenuBar = UIElement.cachedWrapper(peer.getJMenuBar) + def menuBar_=(m: MenuBar) = peer.setJMenuBar(m.peer) + + def resizable_=(b: Boolean) { peer.setResizable(b) } + def resizable = peer.isResizable +} + +/** + * A window with decoration such as a title, border, and action buttons. + * + * An AWT window cannot be wrapped dynamically with this class, i.e., you cannot + * write something like new Window { def peer = myAWTWindow } + * + * @see javax.swing.JFrame + */ +class Frame extends RichWindow { + override lazy val peer: JFrame with InterfaceMixin = new JFrame with InterfaceMixin with SuperMixin + + protected trait SuperMixin extends JFrame { + override protected def processWindowEvent(e: java.awt.event.WindowEvent) { + super.processWindowEvent(e) + if (e.getID() == java.awt.event.WindowEvent.WINDOW_CLOSING) + closeOperation() + } + } + + def iconImage: Image = peer.getIconImage + def iconImage_=(i: Image) { peer.setIconImage(i) } +} + +/** + * Simple predefined dialogs. + * + * @see javax.swing.JOptionPane + */ +object Dialog { + /** + * The message type of a dialog. + */ + object Message extends Enumeration { + val Error = Value(JOptionPane.ERROR_MESSAGE) + val Info = Value(JOptionPane.INFORMATION_MESSAGE) + val Warning = Value(JOptionPane.WARNING_MESSAGE) + val Question = Value(JOptionPane.QUESTION_MESSAGE) + val Plain = Value(JOptionPane.PLAIN_MESSAGE) + } + + /** + * The possible answers a user can select. + */ + object Options extends Enumeration { + val Default = Value(JOptionPane.DEFAULT_OPTION) + val YesNo = Value(JOptionPane.YES_NO_OPTION) + val YesNoCancel = Value(JOptionPane.YES_NO_CANCEL_OPTION) + val OkCancel = Value(JOptionPane.OK_CANCEL_OPTION) + } + + /** + * The selected result of dialog. + */ + object Result extends Enumeration { + val Yes = Value(JOptionPane.YES_OPTION) + val Ok = Yes + val No = Value(JOptionPane.NO_OPTION) + val Cancel = Value(JOptionPane.CANCEL_OPTION) + val Closed = Value(JOptionPane.CLOSED_OPTION) + } + + + def showConfirmation(parent: Component, message: String, title: String, + optionType: Options.Value, messageType: Message.Value, icon: Icon): Result.Value = + Result(JOptionPane.showConfirmDialog(nullPeer(parent), message, title, + optionType.id, messageType.id, Swing.wrapIcon(icon))) + def showConfirmation(parent: Component, message: String, title: String, + optionType: Options.Value): Result.Value = + Result(JOptionPane.showConfirmDialog(nullPeer(parent), message, title, + optionType.id)) + + def showOptions(parent: Component, message: String, title: String, + optionType: Options.Value, messageType: Message.Value, icon: Icon, + entries: Seq[Any], initialEntry: Int): Result.Value = { + val r = JOptionPane.showOptionDialog(nullPeer(parent), message, title, + optionType.id, messageType.id, Swing.wrapIcon(icon), + entries.map(_.asInstanceOf[AnyRef]).toArray, entries(initialEntry)) + Result(r) + } + + def showInput[A](parent: Component, message: String, title: String, + messageType: Message.Value, icon: Icon, + entries: Seq[A], initialEntry: A): Option[A] = { + val e = if (entries.isEmpty) null + else entries.map(_.asInstanceOf[AnyRef]).toArray + val r = JOptionPane.showInputDialog(nullPeer(parent), message, title, + messageType.id, Swing.wrapIcon(icon), + e, initialEntry) + Swing.toOption(r) + } + def showMessage(parent: Component, message: String, title: String, + messageType: Message.Value, icon: Icon) { + JOptionPane.showMessageDialog(nullPeer(parent), message, title, + messageType.id, Swing.wrapIcon(icon)) + } + + def showMessage(parent: Component, message: String) { + JOptionPane.showMessageDialog(nullPeer(parent), message) + } +} + +/** + * A dialog window. + * + * @see javax.swing.JDialog + */ +class Dialog(owner: Window) extends RichWindow { + override lazy val peer: JDialog with InterfaceMixin = + if (owner == null) new JDialog with InterfaceMixin + else owner match { + case f: Frame => new JDialog(f.peer) with InterfaceMixin + case d: Dialog => new JDialog(d.peer) with InterfaceMixin + } + + def this() = this(null) + + def modal_=(b: Boolean) { peer.setModal(b) } + def modal = peer.isModal +} + diff --git a/src/swing/scala/swing/RootPanel.scala b/src/swing/scala/swing/RootPanel.scala index 3efc4045af..6e0d51d71b 100644 --- a/src/swing/scala/swing/RootPanel.scala +++ b/src/swing/scala/swing/RootPanel.scala @@ -13,7 +13,7 @@ trait RootPanel extends Container { */ def contents: Seq[Component] = { Swing.toOption[Any](peer.getContentPane.getComponent(0)).map { c => - Component.wrapperFor(c.asInstanceOf[javax.swing.JComponent]) + UIElement.cachedWrapper(c.asInstanceOf[javax.swing.JComponent]) }.toList } def contents_=(c: Component) { diff --git a/src/swing/scala/swing/ScrollPane.scala b/src/swing/scala/swing/ScrollPane.scala index 0228ae6361..829a02854d 100644 --- a/src/swing/scala/swing/ScrollPane.scala +++ b/src/swing/scala/swing/ScrollPane.scala @@ -15,7 +15,7 @@ class ScrollPane extends Component with Container { viewportView = c } def contents: Seq[Component] = - List(Component.wrapperFor(peer.getViewport.getView.asInstanceOf[javax.swing.JComponent])) + List(UIElement.cachedWrapper(peer.getViewport.getView.asInstanceOf[javax.swing.JComponent])) /** * Sets the single child. @@ -29,11 +29,11 @@ class ScrollPane extends Component with Container { * want to let the row header be a list view with the same row height as * the viewport component. */ - def rowHeaderView: Option[Component] = Swing.toOption(peer.getRowHeader.getView).map(Component.wrapperFor(_)) + def rowHeaderView: Option[Component] = Swing.toOption(peer.getRowHeader.getView).map(UIElement.cachedWrapper(_)) def rowHeaderView_=(c: Component) = peer.setRowHeaderView(c.peer) def rowHeaderView_=(c: Option[Component]) = peer.setRowHeaderView(Swing.toNull(c.map(_.peer))) - def viewportView: Option[Component] = Swing.toOption(peer.getViewport.getView).map(Component.wrapperFor(_)) + def viewportView: Option[Component] = Swing.toOption(peer.getViewport.getView).map(UIElement.cachedWrapper(_)) def viewportView_=(c: Component) = peer.setViewportView(c.peer) def viewportView_=(c: Option[Component]) = peer.setViewportView(Swing.toNull(c.map(_.peer))) } diff --git a/src/swing/scala/swing/Separator.scala b/src/swing/scala/swing/Separator.scala index 94e467a3b0..a76bc3dcfa 100644 --- a/src/swing/scala/swing/Separator.scala +++ b/src/swing/scala/swing/Separator.scala @@ -8,6 +8,6 @@ import javax.swing._ * @see javax.swing.JSeparator */ class Separator(o: Orientation.Value) extends Component with Oriented { - override lazy val peer: JSeparator = new JSeparator(o.id) + override lazy val peer: JSeparator with OrientedMixin = new JSeparator(o.id) with OrientedMixin def this() = this(Orientation.Horizontal) } diff --git a/src/swing/scala/swing/SequentialContainer.scala b/src/swing/scala/swing/SequentialContainer.scala index 5de7e15a22..c4146eaabe 100644 --- a/src/swing/scala/swing/SequentialContainer.scala +++ b/src/swing/scala/swing/SequentialContainer.scala @@ -6,7 +6,7 @@ object SequentialContainer { /** * Utility trait for wrapping sequential containers. */ - trait Wrapper extends Component with SequentialContainer with Container.Wrapper { + trait Wrapper extends SequentialContainer with Container.Wrapper { override val contents: Buffer[Component] = new Content //def contents_=(c: Component*) { contents.clear(); contents ++= c } } diff --git a/src/swing/scala/swing/SimpleGUIApplication.scala b/src/swing/scala/swing/SimpleGUIApplication.scala index 200d324a47..878ff459fb 100644 --- a/src/swing/scala/swing/SimpleGUIApplication.scala +++ b/src/swing/scala/swing/SimpleGUIApplication.scala @@ -5,10 +5,24 @@ import javax.swing._ /** * Extend this class for most simple UI applications. Clients need to implement the * top method. Framework intialization is done by this class. + * + * In order to conform to Swing's threading policy, never implement top or any additional + * member that created Swing components as a value unless component creation happens on + * the EDT (see Swing.onEDT and Swing.onEDTWait). Lazy values are okay for the same reason + * if they are intialized on the EDT always. */ abstract class SimpleGUIApplication extends GUIApplication { + + /** + * A GUI application's version of the main method. Called by the default + * main method implementation provided by this class. + * Implement to return the top-level frame of this application. + */ def top: Frame + /** + * Calls top, packs the frame, and displays it. + */ def main(args: Array[String]) = run { val t = top t.pack() diff --git a/src/swing/scala/swing/SplitPane.scala b/src/swing/scala/swing/SplitPane.scala index 2cd06e7a5d..9ff9ba9854 100644 --- a/src/swing/scala/swing/SplitPane.scala +++ b/src/swing/scala/swing/SplitPane.scala @@ -11,7 +11,8 @@ import Swing._ * @see javax.swing.JSplitPane */ class SplitPane(o: Orientation.Value, left: Component, right: Component) extends Component with Container with Orientable { - override lazy val peer: javax.swing.JSplitPane = new javax.swing.JSplitPane(o.id, left.peer, right.peer) + override lazy val peer: javax.swing.JSplitPane with OrientedMixin = + new javax.swing.JSplitPane(o.id, left.peer, right.peer) with OrientedMixin def this(o: Orientation.Value) = this(o, new Component {}, new Component {}) def this() = this(Orientation.Horizontal) @@ -21,9 +22,9 @@ class SplitPane(o: Orientation.Value, left: Component, right: Component) extends peer.setRightComponent(right.peer) } - def topComponent: Component = Component.wrapperFor(peer.getTopComponent.asInstanceOf[javax.swing.JComponent]) + def topComponent: Component = UIElement.cachedWrapper(peer.getTopComponent.asInstanceOf[javax.swing.JComponent]) def topComponent_=(c: Component) { peer.setTopComponent(c.peer) } - def bottomComponent: Component = Component.wrapperFor(peer.getBottomComponent.asInstanceOf[javax.swing.JComponent]) + def bottomComponent: Component = UIElement.cachedWrapper(peer.getBottomComponent.asInstanceOf[javax.swing.JComponent]) def bottomComponent_=(c: Component) { peer.setBottomComponent(c.peer) } def leftComponent: Component = topComponent diff --git a/src/swing/scala/swing/Swing.scala b/src/swing/scala/swing/Swing.scala index b10f2a50ed..636c5d2841 100644 --- a/src/swing/scala/swing/Swing.scala +++ b/src/swing/scala/swing/Swing.scala @@ -4,7 +4,7 @@ import java.awt.event._ import javax.swing.event._ import java.awt.{Color, Dimension, Point, Rectangle} import javax.swing.border._ -import javax.swing.{JComponent, Icon, BorderFactory} +import javax.swing.{JComponent, Icon, BorderFactory, SwingUtilities} /** * Helpers for this package. @@ -121,4 +121,16 @@ object Swing { def TitledBorder(border: Border, title: String) = BorderFactory.createTitledBorder(border, title) + + /** + * Schedule the given code to be executed on the Swing event dispatching + * thread (EDT). Returns immediately. + */ + def onEDT(op: =>Unit) = SwingUtilities invokeLater op + + /** + * Schedule the given code to be executed on the Swing event dispatching + * thread (EDT). Blocks until after the code has been run. + */ + def onEDTWait(op: =>Unit) = SwingUtilities invokeAndWait op } diff --git a/src/swing/scala/swing/SwingActor.scala b/src/swing/scala/swing/SwingActor.scala new file mode 100644 index 0000000000..7477825df5 --- /dev/null +++ b/src/swing/scala/swing/SwingActor.scala @@ -0,0 +1,22 @@ +package scala.swing + +import scala.actors._ + +/*object SwingActor { + /** + * Similar to Actor.actor, but creates an instance of a SwingActor. + */ + def apply(body: => Unit): Actor = + new SwingActor { def act() = body }.start() +} + +/** + * An actor that runs on the Swing event dispatching thread (EDT). + */ +abstract class SwingActor extends Actor { + override val scheduler = new SchedulerAdapter { + def execute(op: =>Unit) = Swing onEDT op + def onTerminate(a: Actor)(op: => Unit) {} + def terminated(a: Actor) {} + } +}*/ diff --git a/src/swing/scala/swing/UIElement.scala b/src/swing/scala/swing/UIElement.scala index 389dccf95b..8148526d9e 100644 --- a/src/swing/scala/swing/UIElement.scala +++ b/src/swing/scala/swing/UIElement.scala @@ -1,6 +1,37 @@ package scala.swing import java.awt.{Color, Cursor, Font, Dimension, Rectangle} +import scala.collection.mutable.HashMap +import scala.ref._ +import java.util.WeakHashMap + +object UIElement { + private val ClientKey = "scala.swingWrapper" + private[this] val wrapperCache = new WeakHashMap[java.awt.Component, WeakReference[UIElement]] + + private def cache(e: UIElement) = e.peer match { + case p: javax.swing.JComponent => p.putClientProperty(ClientKey, e) + case _ => wrapperCache.put(e.peer, new WeakReference(e)) + } + + /** + * Returns the wrapper for a given peer, null if there is no cached wrapper + * for the given component. + */ + private[swing] def cachedWrapper[C<:UIElement](c: java.awt.Component): C = (c match { + case c: javax.swing.JComponent => c.getClientProperty(ClientKey) + case _ => wrapperCache.get(c) + }).asInstanceOf[C] + + /** + * Wraps a given AWT component in a UIElement. + */ + def wrap(c: java.awt.Component): UIElement = { + val w = cachedWrapper(c) + if (w != null) w + else new UIElement { def peer = c } + } +} /** * The base trait of all user interface elements. Subclasses belong to one @@ -20,6 +51,8 @@ trait UIElement extends Proxy { def peer: java.awt.Component def self = peer + UIElement.cache(this) + def foreground: Color = peer.getForeground def foreground_=(c: Color) = peer.setForeground(c) def background: Color = peer.getBackground @@ -51,6 +84,7 @@ trait UIElement extends Proxy { def visible: Boolean = peer.isVisible def visible_=(b: Boolean) { peer.setVisible(b) } def showing: Boolean = peer.isShowing + def displayable: Boolean = peer.isDisplayable def repaint() { peer.repaint } def repaint(rect: Rectangle) { peer.repaint(rect.x, rect.y, rect.width, rect.height) } diff --git a/src/swing/scala/swing/Views.scala b/src/swing/scala/swing/Views.scala deleted file mode 100644 index 0b7305e54d..0000000000 --- a/src/swing/scala/swing/Views.scala +++ /dev/null @@ -1,7 +0,0 @@ -package scala.swing - -//object Views { - //implicit def action2MenuItem(a: Action): MenuItem = new MenuItem(a) - //implicit def action2Button(a: Action): Button = new Button(a) - //implicit def string2Label(s: String): Label = new Label(s) -//} diff --git a/src/swing/scala/swing/Window.scala b/src/swing/scala/swing/Window.scala new file mode 100644 index 0000000000..a2d88845c6 --- /dev/null +++ b/src/swing/scala/swing/Window.scala @@ -0,0 +1,64 @@ +package scala.swing + +import java.awt.{Image, Point, Window => AWTWindow} +import javax.swing._ +import event._ + +/** + * A window with decoration such as a title, border, and action buttons. + * + * An AWT window cannot be wrapped dynamically with this class, i.e., you cannot + * write something like new Window { def peer = myAWTWindow } + * + * @see javax.swing.JFrame + */ +abstract class Window extends UIElement with RootPanel with Publisher { outer => + def peer: AWTWindow with InterfaceMixin + + protected trait InterfaceMixin extends javax.swing.RootPaneContainer { + def getRootPane: JRootPane + //protected def setRootPane(p: JRootPane) + } + + /** + * This method is called when the window is closing, after all other window + * event listeners have been processed. + */ + def closeOperation() {} + + override def contents_=(c: Component) { + super.contents_=(c) + peer.pack() // pack also validates, which is generally required after an add + } + def defaultButton: Option[Button] = + Swing.toOption(peer.getRootPane.getDefaultButton).map(UIElement.cachedWrapper(_)) + def defaultButton_=(b: Button) { + peer.getRootPane.setDefaultButton(b.peer) + } + def defaultButton_=(b: Option[Button]) { + peer.getRootPane.setDefaultButton(Swing.toNull(b.map(_.peer))) + } + + def dispose() { peer.dispose() } + + def pack(): this.type = { peer.pack(); this } + + def setLocationRelativeTo(c: UIElement) { peer.setLocationRelativeTo(c.peer) } + def centerOnScreen() { peer.setLocationRelativeTo(null) } + def location_=(p: Point) { peer.setLocation(p) } + + def owner: Window = UIElement.cachedWrapper(peer.getOwner) + + def open() { peer.show() } + def close() { peer.hide() } + + peer.addWindowListener(new java.awt.event.WindowListener { + def windowActivated(e: java.awt.event.WindowEvent) { publish(WindowActivated(outer)) } + def windowClosed(e: java.awt.event.WindowEvent) { publish(WindowClosed(outer)) } + def windowClosing(e: java.awt.event.WindowEvent) { publish(WindowClosing(outer)) } + def windowDeactivated(e: java.awt.event.WindowEvent) { publish(WindowDeactivated(outer)) } + def windowDeiconified(e: java.awt.event.WindowEvent) { publish(WindowDeiconified(outer)) } + def windowIconified(e: java.awt.event.WindowEvent) { publish(WindowIconified(outer)) } + def windowOpened(e: java.awt.event.WindowEvent) { publish(WindowOpened(outer)) } + }) +} \ No newline at end of file diff --git a/src/swing/scala/swing/event/InputEvent.scala b/src/swing/scala/swing/event/InputEvent.scala index ae24d537a7..6cfffb9442 100644 --- a/src/swing/scala/swing/event/InputEvent.scala +++ b/src/swing/scala/swing/event/InputEvent.scala @@ -1,6 +1,9 @@ package scala.swing.event trait InputEvent extends ComponentEvent { - val when: Long - val modifiers: Int + def peer: java.awt.event.InputEvent + def when: Long = peer.getWhen + def modifiers: Int + def consume() { peer.consume() } + def consumed: Boolean = peer.isConsumed } diff --git a/src/swing/scala/swing/event/Key.scala b/src/swing/scala/swing/event/Key.scala new file mode 100644 index 0000000000..c19186ff81 --- /dev/null +++ b/src/swing/scala/swing/event/Key.scala @@ -0,0 +1,216 @@ +package scala.swing.event + +object Key extends Enumeration { + import java.awt.event.KeyEvent._ + + object Location extends Enumeration { + val Left = Value(java.awt.event.KeyEvent.KEY_LOCATION_LEFT) + val Right = Value(java.awt.event.KeyEvent.KEY_LOCATION_RIGHT) + val Numpad = Value(java.awt.event.KeyEvent.KEY_LOCATION_NUMPAD) + val Standard = Value(java.awt.event.KeyEvent.KEY_LOCATION_STANDARD) + val Unknown = Value(java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN) + } + + object Modifier { + import java.awt.event.InputEvent._ + val Shift = SHIFT_DOWN_MASK + val Control = CTRL_DOWN_MASK + val Alt = ALT_DOWN_MASK + val AltGraph = ALT_GRAPH_DOWN_MASK + val Meta = META_DOWN_MASK + def text(mods: Int) = java.awt.event.KeyEvent.getKeyModifiersText(mods) + } + + //def text(k: Value) = java.awt.event.KeyEvent.getKeyText(k.id) + + val Shift = Value(VK_SHIFT, getKeyText(VK_SHIFT)) + val Control = Value(VK_CONTROL, getKeyText(VK_CONTROL)) + val Alt = Value(VK_ALT, getKeyText(VK_ALT)) + val AltGraph = Value(VK_ALT_GRAPH, getKeyText(VK_ALT_GRAPH)) + val Meta = Value(VK_META, getKeyText(VK_META)) + + val Enter = Value(VK_ENTER, getKeyText(VK_ENTER)) + val BackSpace = Value(VK_BACK_SPACE, getKeyText(VK_BACK_SPACE)) + val Tab = Value(VK_TAB, getKeyText(VK_TAB)) + val Cancel = Value(VK_CANCEL, getKeyText(VK_CANCEL)) + val Clear = Value(VK_CLEAR, getKeyText(VK_CLEAR)) + + val Pause = Value(VK_PAUSE, getKeyText(VK_PAUSE)) + val CapsLock = Value(VK_CAPS_LOCK, getKeyText(VK_CAPS_LOCK)) + val Escape = Value(VK_ESCAPE, getKeyText(VK_ESCAPE)) + val Space = Value(VK_SPACE, getKeyText(VK_SPACE)) + val PageUp = Value(VK_PAGE_UP, getKeyText(VK_PAGE_UP)) + val PageDown = Value(VK_PAGE_DOWN, getKeyText(VK_PAGE_DOWN)) + val End = Value(VK_END, getKeyText(VK_END)) + val Home = Value(VK_HOME, getKeyText(VK_HOME)) + val Left = Value(VK_LEFT, getKeyText(VK_LEFT)) + val Up = Value(VK_UP, getKeyText(VK_UP)) + val Right = Value(VK_RIGHT, getKeyText(VK_RIGHT)) + val Down = Value(VK_DOWN, getKeyText(VK_DOWN)) + val Comma = Value(VK_COMMA, getKeyText(VK_COMMA)) + val Minus = Value(VK_MINUS, getKeyText(VK_MINUS)) + val Period = Value(VK_PERIOD, getKeyText(VK_PERIOD)) + val Slash = Value(VK_SLASH, getKeyText(VK_SLASH)) + val Key0 = Value(VK_0, getKeyText(VK_0)) + val Key1 = Value(VK_1, getKeyText(VK_1)) + val Key2 = Value(VK_2, getKeyText(VK_2)) + val Key3 = Value(VK_3, getKeyText(VK_3)) + val Key4 = Value(VK_4, getKeyText(VK_4)) + val Key5 = Value(VK_5, getKeyText(VK_5)) + val Key6 = Value(VK_6, getKeyText(VK_6)) + val Key7 = Value(VK_7, getKeyText(VK_7)) + val Key8 = Value(VK_8, getKeyText(VK_8)) + val Key9 = Value(VK_9, getKeyText(VK_9)) + val Semicolon = Value(VK_SEMICOLON, getKeyText(VK_SEMICOLON)) + val Equals = Value(VK_EQUALS, getKeyText(VK_EQUALS)) + val A = Value(VK_A, getKeyText(VK_A)) + val B = Value(VK_B, getKeyText(VK_B)) + val C = Value(VK_C, getKeyText(VK_C)) + val D = Value(VK_D, getKeyText(VK_D)) + val E = Value(VK_E, getKeyText(VK_E)) + val F = Value(VK_F, getKeyText(VK_F)) + val G = Value(VK_G, getKeyText(VK_G)) + val H = Value(VK_H, getKeyText(VK_H)) + val I = Value(VK_I, getKeyText(VK_I)) + val J = Value(VK_J, getKeyText(VK_J)) + val K = Value(VK_K, getKeyText(VK_K)) + val L = Value(VK_L, getKeyText(VK_L)) + val M = Value(VK_M, getKeyText(VK_M)) + val N = Value(VK_N, getKeyText(VK_N)) + val O = Value(VK_O, getKeyText(VK_O)) + val P = Value(VK_P, getKeyText(VK_P)) + val Q = Value(VK_Q, getKeyText(VK_Q)) + val R = Value(VK_R, getKeyText(VK_R)) + val S = Value(VK_S, getKeyText(VK_S)) + val T = Value(VK_T, getKeyText(VK_T)) + val U = Value(VK_U, getKeyText(VK_U)) + val V = Value(VK_V, getKeyText(VK_V)) + val W = Value(VK_W, getKeyText(VK_W)) + val X = Value(VK_X, getKeyText(VK_X)) + val Y = Value(VK_Y, getKeyText(VK_Y)) + val Z = Value(VK_Z, getKeyText(VK_Z)) + val OpenBracket = Value(VK_OPEN_BRACKET, getKeyText(VK_OPEN_BRACKET)) + val BackSlash = Value(VK_BACK_SLASH, getKeyText(VK_BACK_SLASH)) + val CloseBracket = Value(VK_CLOSE_BRACKET, getKeyText(VK_CLOSE_BRACKET)) + val Numpad0 = Value(VK_NUMPAD0, getKeyText(VK_NUMPAD0)) + val Numpad1 = Value(VK_NUMPAD1, getKeyText(VK_NUMPAD1)) + val Numpad2 = Value(VK_NUMPAD2, getKeyText(VK_NUMPAD2)) + val Numpad3 = Value(VK_NUMPAD3, getKeyText(VK_NUMPAD3)) + val Numpad4 = Value(VK_NUMPAD4, getKeyText(VK_NUMPAD4)) + val Numpad5 = Value(VK_NUMPAD5, getKeyText(VK_NUMPAD5)) + val Numpad6 = Value(VK_NUMPAD6, getKeyText(VK_NUMPAD6)) + val Numpad7 = Value(VK_NUMPAD7, getKeyText(VK_NUMPAD7)) + val Numpad8 = Value(VK_NUMPAD8, getKeyText(VK_NUMPAD8)) + val Numpad9 = Value(VK_NUMPAD9, getKeyText(VK_NUMPAD9)) + val Multiply = Value(VK_MULTIPLY, getKeyText(VK_MULTIPLY)) + val Add = Value(VK_ADD, getKeyText(VK_ADD)) + val Separator = Value(VK_SEPARATOR, getKeyText(VK_SEPARATOR)) + val Subtract = Value(VK_SUBTRACT, getKeyText(VK_SUBTRACT)) + val Decimal = Value(VK_DECIMAL, getKeyText(VK_DECIMAL)) + val Divide = Value(VK_DIVIDE, getKeyText(VK_DIVIDE)) + val Delete = Value(VK_DELETE, getKeyText(VK_DELETE)) + val NumLock = Value(VK_NUM_LOCK, getKeyText(VK_NUM_LOCK)) + val ScrollLock = Value(VK_SCROLL_LOCK, getKeyText(VK_SCROLL_LOCK)) + val F1 = Value(VK_F1, getKeyText(VK_F1)) + val F2 = Value(VK_F2, getKeyText(VK_F2)) + val F3 = Value(VK_F3, getKeyText(VK_F3)) + val F4 = Value(VK_F4, getKeyText(VK_F4)) + val F5 = Value(VK_F5, getKeyText(VK_F5)) + val F6 = Value(VK_F6, getKeyText(VK_F6)) + val F7 = Value(VK_F7, getKeyText(VK_F7)) + val F8 = Value(VK_F8, getKeyText(VK_F8)) + val F9 = Value(VK_F9, getKeyText(VK_F9)) + val F10 = Value(VK_F10, getKeyText(VK_F10)) + val F11 = Value(VK_F11, getKeyText(VK_F11)) + val F12 = Value(VK_F12, getKeyText(VK_F12)) + val F13 = Value(VK_F13, getKeyText(VK_F13)) + val F14 = Value(VK_F14, getKeyText(VK_F14)) + val F15 = Value(VK_F15, getKeyText(VK_F15)) + val F16 = Value(VK_F16, getKeyText(VK_F16)) + val F17 = Value(VK_F17, getKeyText(VK_F17)) + val F18 = Value(VK_F18, getKeyText(VK_F18)) + val F19 = Value(VK_F19, getKeyText(VK_F19)) + val F20 = Value(VK_F20, getKeyText(VK_F20)) + val F21 = Value(VK_F21, getKeyText(VK_F21)) + val F22 = Value(VK_F22, getKeyText(VK_F22)) + val F23 = Value(VK_F23, getKeyText(VK_F23)) + val F24 = Value(VK_F24, getKeyText(VK_F24)) + val Printscreen = Value(VK_PRINTSCREEN, getKeyText(VK_PRINTSCREEN)) + val Insert = Value(VK_INSERT, getKeyText(VK_INSERT)) + val Help = Value(VK_HELP, getKeyText(VK_HELP)) + val BackQuote = Value(VK_BACK_QUOTE, getKeyText(VK_BACK_QUOTE)) + val Quote = Value(VK_QUOTE, getKeyText(VK_QUOTE)) + val KpUp = Value(VK_KP_UP, getKeyText(VK_KP_UP)) + val KpDown = Value(VK_KP_DOWN, getKeyText(VK_KP_DOWN)) + val KpLeft = Value(VK_KP_LEFT, getKeyText(VK_KP_LEFT)) + val KpRight = Value(VK_KP_RIGHT, getKeyText(VK_KP_RIGHT)) + val DeadGrave = Value(VK_DEAD_GRAVE, getKeyText(VK_DEAD_GRAVE)) + val DeadAcute = Value(VK_DEAD_ACUTE, getKeyText(VK_DEAD_ACUTE)) + val DeadCircumflex = Value(VK_DEAD_CIRCUMFLEX, getKeyText(VK_DEAD_CIRCUMFLEX)) + val DeadTilde = Value(VK_DEAD_TILDE, getKeyText(VK_DEAD_TILDE)) + val DeadMacron = Value(VK_DEAD_MACRON, getKeyText(VK_DEAD_MACRON)) + val DeadBreve = Value(VK_DEAD_BREVE, getKeyText(VK_DEAD_BREVE)) + val DeadAbovedot = Value(VK_DEAD_ABOVEDOT, getKeyText(VK_DEAD_ABOVEDOT)) + val DeadDiaeresis = Value(VK_DEAD_DIAERESIS, getKeyText(VK_DEAD_DIAERESIS)) + val DeadAbovering = Value(VK_DEAD_ABOVERING, getKeyText(VK_DEAD_ABOVERING)) + val DeadDoubleacute = Value(VK_DEAD_DOUBLEACUTE, getKeyText(VK_DEAD_DOUBLEACUTE)) + val DeadCaron = Value(VK_DEAD_CARON, getKeyText(VK_DEAD_CARON)) + val DeadCedilla = Value(VK_DEAD_CEDILLA, getKeyText(VK_DEAD_CEDILLA)) + val DeadOgonek = Value(VK_DEAD_OGONEK, getKeyText(VK_DEAD_OGONEK)) + val DeadIota = Value(VK_DEAD_IOTA, getKeyText(VK_DEAD_IOTA)) + val DeadVoicedSound = Value(VK_DEAD_VOICED_SOUND, getKeyText(VK_DEAD_VOICED_SOUND)) + val DeadSemivoicedSound = Value(VK_DEAD_SEMIVOICED_SOUND, getKeyText(VK_DEAD_SEMIVOICED_SOUND)) + val Ampersand = Value(VK_AMPERSAND, getKeyText(VK_AMPERSAND)) + val Asterisk = Value(VK_ASTERISK, getKeyText(VK_ASTERISK)) + val Quotedbl = Value(VK_QUOTEDBL, getKeyText(VK_QUOTEDBL)) + val Less = Value(VK_LESS, getKeyText(VK_LESS)) + val Greater = Value(VK_GREATER, getKeyText(VK_GREATER)) + val Braceleft = Value(VK_BRACELEFT, getKeyText(VK_BRACELEFT)) + val Braceright = Value(VK_BRACERIGHT, getKeyText(VK_BRACERIGHT)) + val At = Value(VK_AT, getKeyText(VK_AT)) + val Colon = Value(VK_COLON, getKeyText(VK_COLON)) + val Circumflex = Value(VK_CIRCUMFLEX, getKeyText(VK_CIRCUMFLEX)) + val Dollar = Value(VK_DOLLAR, getKeyText(VK_DOLLAR)) + val EuroSign = Value(VK_EURO_SIGN, getKeyText(VK_EURO_SIGN)) + val ExclamationMark = Value(VK_EXCLAMATION_MARK, getKeyText(VK_EXCLAMATION_MARK)) + val InvertedExclamationMark = Value(VK_INVERTED_EXCLAMATION_MARK, getKeyText(VK_INVERTED_EXCLAMATION_MARK)) + val LeftParenthesis = Value(VK_LEFT_PARENTHESIS, getKeyText(VK_LEFT_PARENTHESIS)) + val NumberSign = Value(VK_NUMBER_SIGN, getKeyText(VK_NUMBER_SIGN)) + val Plus = Value(VK_PLUS, getKeyText(VK_PLUS)) + val RightParenthesis = Value(VK_RIGHT_PARENTHESIS, getKeyText(VK_RIGHT_PARENTHESIS)) + val Underscore = Value(VK_UNDERSCORE, getKeyText(VK_UNDERSCORE)) + val Windows = Value(VK_WINDOWS, getKeyText(VK_WINDOWS)) + val ContextMenu = Value(VK_CONTEXT_MENU, getKeyText(VK_CONTEXT_MENU)) + val Final = Value(VK_FINAL, getKeyText(VK_FINAL)) + val Convert = Value(VK_CONVERT, getKeyText(VK_CONVERT)) + val Nonconvert = Value(VK_NONCONVERT, getKeyText(VK_NONCONVERT)) + val Accept = Value(VK_ACCEPT, getKeyText(VK_ACCEPT)) + val Modechange = Value(VK_MODECHANGE, getKeyText(VK_MODECHANGE)) + val Kana = Value(VK_KANA, getKeyText(VK_KANA)) + val Kanji = Value(VK_KANJI, getKeyText(VK_KANJI)) + val Alphanumeric = Value(VK_ALPHANUMERIC, getKeyText(VK_ALPHANUMERIC)) + val Katakana = Value(VK_KATAKANA, getKeyText(VK_KATAKANA)) + val Hiragana = Value(VK_HIRAGANA, getKeyText(VK_HIRAGANA)) + val FullWidth = Value(VK_FULL_WIDTH, getKeyText(VK_FULL_WIDTH)) + val HalfWidth = Value(VK_HALF_WIDTH, getKeyText(VK_HALF_WIDTH)) + val RomanCharacters = Value(VK_ROMAN_CHARACTERS, getKeyText(VK_ROMAN_CHARACTERS)) + val AllCandidates = Value(VK_ALL_CANDIDATES, getKeyText(VK_ALL_CANDIDATES)) + val PreviousCandidate = Value(VK_PREVIOUS_CANDIDATE, getKeyText(VK_PREVIOUS_CANDIDATE)) + val CodeInput = Value(VK_CODE_INPUT, getKeyText(VK_CODE_INPUT)) + val JapaneseKatakana = Value(VK_JAPANESE_KATAKANA, getKeyText(VK_JAPANESE_KATAKANA)) + val JapaneseHiragana = Value(VK_JAPANESE_HIRAGANA, getKeyText(VK_JAPANESE_HIRAGANA)) + val JapaneseRoman = Value(VK_JAPANESE_ROMAN, getKeyText(VK_JAPANESE_ROMAN)) + val KanaLock = Value(VK_KANA_LOCK, getKeyText(VK_KANA_LOCK)) + val InputMethodOnOff = Value(VK_INPUT_METHOD_ON_OFF, getKeyText(VK_INPUT_METHOD_ON_OFF)) + val Cut = Value(VK_CUT, getKeyText(VK_CUT)) + val Copy = Value(VK_COPY, getKeyText(VK_COPY)) + val Paste = Value(VK_PASTE, getKeyText(VK_PASTE)) + val Undo = Value(VK_UNDO, getKeyText(VK_UNDO)) + val Again = Value(VK_AGAIN, getKeyText(VK_AGAIN)) + val Find = Value(VK_FIND, getKeyText(VK_FIND)) + val Props = Value(VK_PROPS, getKeyText(VK_PROPS)) + val Stop = Value(VK_STOP, getKeyText(VK_STOP)) + val Compose = Value(VK_COMPOSE, getKeyText(VK_COMPOSE)) + val Begin = Value(VK_BEGIN, getKeyText(VK_BEGIN)) + val Undefined = Value(VK_UNDEFINED, getKeyText(VK_UNDEFINED)) +} diff --git a/src/swing/scala/swing/event/KeyEvent.scala b/src/swing/scala/swing/event/KeyEvent.scala new file mode 100644 index 0000000000..3a379608b5 --- /dev/null +++ b/src/swing/scala/swing/event/KeyEvent.scala @@ -0,0 +1,29 @@ +package scala.swing.event + +import javax.swing.JComponent + +sealed abstract class KeyEvent extends InputEvent { + def peer: java.awt.event.KeyEvent +} + +case class KeyTyped(val source: Component, char: Char, val modifiers: Int, + location: Key.Location.Value) + (val peer: java.awt.event.KeyEvent) extends KeyEvent { + def this(e: java.awt.event.KeyEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), + e.getKeyChar, e.getModifiersEx, + Key.Location(e.getKeyLocation))(e) +} + +case class KeyPressed(val source: Component, key: Key.Value, val modifiers: Int, + location: Key.Location.Value) + (val peer: java.awt.event.KeyEvent) extends KeyEvent { + def this(e: java.awt.event.KeyEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), + Key(e.getKeyCode), e.getModifiersEx, Key.Location(e.getKeyLocation))(e) +} + +case class KeyReleased(val source: Component, key: Key.Value, val modifiers: Int, + location: Key.Location.Value) + (val peer: java.awt.event.KeyEvent) extends KeyEvent { + def this(e: java.awt.event.KeyEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), + Key(e.getKeyCode), e.getModifiersEx, Key.Location(e.getKeyLocation))(e) +} diff --git a/src/swing/scala/swing/event/MouseEvent.scala b/src/swing/scala/swing/event/MouseEvent.scala index 3b671bfa6b..f7a6ec2fee 100644 --- a/src/swing/scala/swing/event/MouseEvent.scala +++ b/src/swing/scala/swing/event/MouseEvent.scala @@ -1,32 +1,60 @@ package scala.swing.event import java.awt.Point +import javax.swing.JComponent -class MouseEvent(val source: Component, point: Point, val modifiers: Int)(val when: Long) extends InputEvent +sealed abstract class MouseEvent extends InputEvent { + def peer: java.awt.event.MouseEvent + def point: Point +} -class MouseButtonEvent(source: Component, point: Point, override val modifiers: Int, - clicks: Int, triggersPopup: Boolean)(when: Long) - extends MouseEvent(source, point, modifiers)(when) -case class MouseClicked(override val source: Component, point: Point, override val modifiers: Int, - clicks: Int, triggersPopup: Boolean)(when: Long) - extends MouseButtonEvent(source, point, modifiers, clicks, triggersPopup)(when) -case class MousePressed(override val source: Component, point: Point, override val modifiers: Int, - clicks: Int, triggersPopup: Boolean)(when: Long) - extends MouseButtonEvent(source, point, modifiers, clicks, triggersPopup)(when) -case class MouseReleased(override val source: Component, point: Point, override val modifiers: Int, - clicks: Int, triggersPopup: Boolean)(when: Long) - extends MouseButtonEvent(source, point, modifiers, clicks, triggersPopup)(when) +sealed abstract class MouseButtonEvent extends MouseEvent { + def clicks: Int + def triggersPopup: Boolean +} +case class MouseClicked(val source: Component, point: Point, val modifiers: Int, + clicks: Int, triggersPopup: Boolean)(val peer: java.awt.event.MouseEvent) + extends MouseButtonEvent { + def this(e: java.awt.event.MouseEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), + e.getPoint, e.getModifiersEx, e.getClickCount, e.isPopupTrigger)(e) +} +case class MousePressed(val source: Component, point: Point, val modifiers: Int, + clicks: Int, triggersPopup: Boolean)(val peer: java.awt.event.MouseEvent) + extends MouseButtonEvent { + def this(e: java.awt.event.MouseEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), + e.getPoint, e.getModifiersEx, e.getClickCount, e.isPopupTrigger)(e) +} +case class MouseReleased(val source: Component, point: Point, val modifiers: Int, + clicks: Int, triggersPopup: Boolean)(val peer: java.awt.event.MouseEvent) + extends MouseButtonEvent { + def this(e: java.awt.event.MouseEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), + e.getPoint, e.getModifiersEx, e.getClickCount, e.isPopupTrigger)(e) +} -class MouseMotionEvent(source: Component, point: Point, modifiers: Int)(when: Long) - extends MouseEvent(source, point, modifiers)(when) -case class MouseMoved(override val source: Component, point: Point, override val modifiers: Int)(when: Long) - extends MouseMotionEvent(source, point, modifiers)(when) -case class MouseDragged(override val source: Component, point: Point, override val modifiers: Int)(when: Long) - extends MouseMotionEvent(source, point, modifiers)(when) -case class MouseEntered(override val source: Component, point: Point, override val modifiers: Int)(when: Long) - extends MouseMotionEvent(source, point, modifiers)(when) -case class MouseExited(override val source: Component, point: Point, override val modifiers: Int)(when: Long) - extends MouseMotionEvent(source, point, modifiers)(when) +sealed abstract class MouseMotionEvent extends MouseEvent +case class MouseMoved(val source: Component, point: Point, val modifiers: Int)(val peer: java.awt.event.MouseEvent) + extends MouseMotionEvent { + def this(e: java.awt.event.MouseEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), + e.getPoint, e.getModifiersEx)(e) +} +case class MouseDragged(val source: Component, point: Point, val modifiers: Int)(val peer: java.awt.event.MouseEvent) + extends MouseMotionEvent { + def this(e: java.awt.event.MouseEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), + e.getPoint, e.getModifiersEx)(e) +} +case class MouseEntered(val source: Component, point: Point, val modifiers: Int)(val peer: java.awt.event.MouseEvent) + extends MouseMotionEvent { + def this(e: java.awt.event.MouseEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), + e.getPoint, e.getModifiersEx)(e) +} +case class MouseExited(val source: Component, point: Point, val modifiers: Int)(val peer: java.awt.event.MouseEvent) + extends MouseMotionEvent { + def this(e: java.awt.event.MouseEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), + e.getPoint, e.getModifiersEx)(e) +} -case class MouseWheelMoved(override val source: Component, point: Point, override val modifiers: Int, rotation: Int)(when: Long) - extends MouseEvent(source, point, modifiers)(when) \ No newline at end of file +case class MouseWheelMoved(val source: Component, point: Point, val modifiers: Int, rotation: Int)(val peer: java.awt.event.MouseEvent) + extends MouseEvent { + def this(e: java.awt.event.MouseWheelEvent) = this(UIElement.cachedWrapper(e.getSource.asInstanceOf[JComponent]), + e.getPoint, e.getModifiersEx, e.getWheelRotation)(e) +} \ No newline at end of file diff --git a/src/swing/scala/swing/event/WindowActivated.scala b/src/swing/scala/swing/event/WindowActivated.scala index c2ed2f688a..dfed4f1a99 100644 --- a/src/swing/scala/swing/event/WindowActivated.scala +++ b/src/swing/scala/swing/event/WindowActivated.scala @@ -1,3 +1,3 @@ package scala.swing.event -case class WindowActivated(override val source: Frame) extends WindowEvent(source) +case class WindowActivated(override val source: Window) extends WindowEvent(source) diff --git a/src/swing/scala/swing/event/WindowClosed.scala b/src/swing/scala/swing/event/WindowClosed.scala index d719e476f1..3f5f9a33e2 100644 --- a/src/swing/scala/swing/event/WindowClosed.scala +++ b/src/swing/scala/swing/event/WindowClosed.scala @@ -1,3 +1,3 @@ package scala.swing.event -case class WindowClosed(override val source: Frame) extends WindowEvent(source) +case class WindowClosed(override val source: Window) extends WindowEvent(source) diff --git a/src/swing/scala/swing/event/WindowClosing.scala b/src/swing/scala/swing/event/WindowClosing.scala index 5f753651cd..3fb8087c23 100644 --- a/src/swing/scala/swing/event/WindowClosing.scala +++ b/src/swing/scala/swing/event/WindowClosing.scala @@ -1,3 +1,3 @@ package scala.swing.event -case class WindowClosing(override val source: Frame) extends WindowEvent(source) +case class WindowClosing(override val source: Window) extends WindowEvent(source) diff --git a/src/swing/scala/swing/event/WindowDeactivated.scala b/src/swing/scala/swing/event/WindowDeactivated.scala index ca5f330073..5d15f9fcfe 100644 --- a/src/swing/scala/swing/event/WindowDeactivated.scala +++ b/src/swing/scala/swing/event/WindowDeactivated.scala @@ -1,3 +1,3 @@ package scala.swing.event -case class WindowDeactivated(override val source: Frame) extends WindowEvent(source) +case class WindowDeactivated(override val source: Window) extends WindowEvent(source) diff --git a/src/swing/scala/swing/event/WindowDeiconified.scala b/src/swing/scala/swing/event/WindowDeiconified.scala index 828a65ae6e..1eac0c7f22 100644 --- a/src/swing/scala/swing/event/WindowDeiconified.scala +++ b/src/swing/scala/swing/event/WindowDeiconified.scala @@ -1,3 +1,3 @@ package scala.swing.event -case class WindowDeiconified(override val source: Frame) extends WindowEvent(source) +case class WindowDeiconified(override val source: Window) extends WindowEvent(source) diff --git a/src/swing/scala/swing/event/WindowEvent.scala b/src/swing/scala/swing/event/WindowEvent.scala index c0caf2bee9..1e648f958d 100644 --- a/src/swing/scala/swing/event/WindowEvent.scala +++ b/src/swing/scala/swing/event/WindowEvent.scala @@ -1,3 +1,3 @@ package scala.swing.event -abstract class WindowEvent(override val source: Frame) extends UIEvent +abstract class WindowEvent(override val source: Window) extends UIEvent diff --git a/src/swing/scala/swing/event/WindowIconified.scala b/src/swing/scala/swing/event/WindowIconified.scala index 1a18d7179c..b150840768 100644 --- a/src/swing/scala/swing/event/WindowIconified.scala +++ b/src/swing/scala/swing/event/WindowIconified.scala @@ -1,3 +1,3 @@ package scala.swing.event -case class WindowIconified(override val source: Frame) extends WindowEvent(source) +case class WindowIconified(override val source: Window) extends WindowEvent(source) diff --git a/src/swing/scala/swing/event/WindowOpened.scala b/src/swing/scala/swing/event/WindowOpened.scala index e6f45dc747..4e93fee9ae 100644 --- a/src/swing/scala/swing/event/WindowOpened.scala +++ b/src/swing/scala/swing/event/WindowOpened.scala @@ -1,3 +1,3 @@ package scala.swing.event -case class WindowOpened(override val source: Frame) extends WindowEvent(source) +case class WindowOpened(override val source: Window) extends WindowEvent(source) diff --git a/src/swing/scala/swing/test/CelsiusConverter2.scala b/src/swing/scala/swing/test/CelsiusConverter2.scala index a7a6f427ee..96565d78c1 100644 --- a/src/swing/scala/swing/test/CelsiusConverter2.scala +++ b/src/swing/scala/swing/test/CelsiusConverter2.scala @@ -4,9 +4,9 @@ import swing._ import event._ object CelsiusConverter2 extends SimpleGUIApplication { - val ui = new FlowPanel { - val Celsius = new TextField { columns = 5 } - val Fahrenheit = new TextField { columns = 5 } + lazy val ui = new FlowPanel { + val Celsius = new TextField { text = "0"; columns = 5 } + val Fahrenheit = new TextField { text = "0"; columns = 5 } contents.append(Celsius, new Label(" Celsius = "), Fahrenheit, new Label(" Fahrenheit")) border = Swing.EmptyBorder(15, 10, 10, 10) diff --git a/src/swing/scala/swing/test/ComboBoxes.scala b/src/swing/scala/swing/test/ComboBoxes.scala index c5e730a1a5..87bb21dc33 100644 --- a/src/swing/scala/swing/test/ComboBoxes.scala +++ b/src/swing/scala/swing/test/ComboBoxes.scala @@ -14,7 +14,7 @@ import javax.swing.{Icon, ImageIcon} */ object ComboBoxes extends SimpleGUIApplication { import ComboBox._ - val ui = new FlowPanel { + lazy val ui = new FlowPanel { contents += new ComboBox(List(1,2,3,4)) val patterns = List("dd MMMMM yyyy", diff --git a/src/swing/scala/swing/test/Dialogs.scala b/src/swing/scala/swing/test/Dialogs.scala index dfee916fb1..a2e8b1b9ba 100644 --- a/src/swing/scala/swing/test/Dialogs.scala +++ b/src/swing/scala/swing/test/Dialogs.scala @@ -6,8 +6,8 @@ import swing.event._ object Dialogs extends SimpleGUIApplication { import TabbedPane._ - val label = new Label("No Result yet") - val tabs = new TabbedPane { + lazy val label = new Label("No Result yet") + lazy val tabs = new TabbedPane { pages += new Page("File", new GridBagPanel { grid => import GridBagPanel._ val buttonText = new TextField("Click Me") @@ -101,10 +101,10 @@ object Dialogs extends SimpleGUIApplication { val mutex = new ButtonGroup val pick = new RadioButton("Pick one of several choices") val enter = new RadioButton("Enter some text") - //val nonClosing = new RadioButton("Non-auto-closing dialog") - //val validate = new RadioButton("Input-validating dialog (with custom message area)") - //val nonModal = new RadioButton("Non-modal dialog") - val radios = List(pick, enter)//, nonClosing, validate, nonModal) + val custom = new RadioButton("Custom") + val customUndec = new RadioButton("Custom undecorated") + val custom2 = new RadioButton("2 custom dialogs") + val radios = List(pick, enter, custom, customUndec, custom2) mutex.buttons ++= radios mutex.select(pick) val buttons = new BoxPanel(Orientation.Vertical) { @@ -141,18 +141,33 @@ object Dialogs extends SimpleGUIApplication { label.text = "Green eggs and... " + s.get + "!" else label.text = "Come on, finish the sentence!" + case `custom` => + val dialog = new Dialog(top) + dialog.open() + dialog.contents = Button("Close Me!") { dialog.close() } + case `customUndec` => + val dialog = new Dialog with RichWindow.Undecorated + dialog.open() + dialog.contents = Button("Close Me!") { dialog.close() } + case `custom2` => + val d1 = new Dialog + val d2 = new Dialog(d1) + d1.open() + d2.open() + d1.contents = Button("Close Me! I am the owner and will automatically close the other one") { d1.close() } + d2.contents = Button("Close Me!") { d2.close() } } })) = Position.South }) } - val ui = new BorderPanel { + lazy val ui: Panel = new BorderPanel { layout(tabs) = BorderPanel.Position.Center layout(label) = BorderPanel.Position.South } - def top = new MainFrame { + lazy val top = new MainFrame { title = "Dialog Demo" contents = ui } diff --git a/src/swing/scala/swing/test/GridBagDemo.scala b/src/swing/scala/swing/test/GridBagDemo.scala index e47d0ae4ca..2b6b6b73ad 100644 --- a/src/swing/scala/swing/test/GridBagDemo.scala +++ b/src/swing/scala/swing/test/GridBagDemo.scala @@ -6,7 +6,7 @@ import GridBagPanel._ import java.awt.Insets object GridBagDemo extends SimpleGUIApplication { - val ui = new GridBagPanel { + lazy val ui = new GridBagPanel { val c = new Constraints val shouldFill = true if (shouldFill) { diff --git a/src/swing/scala/swing/test/HelloWorld.scala b/src/swing/scala/swing/test/HelloWorld.scala index e4d70cd84b..d4219f72ca 100644 --- a/src/swing/scala/swing/test/HelloWorld.scala +++ b/src/swing/scala/swing/test/HelloWorld.scala @@ -2,9 +2,12 @@ package scala.swing.test import swing._ +/** + * A simple swing demo. + */ object HelloWorld extends GUIApplication { def main(args: Array[String]) = run { - val frame = new Frame { + val frame = new MainFrame { title = "HelloWorldSwing" contents = new Label("Hello World") } diff --git a/src/swing/scala/swing/test/LabelTest.scala b/src/swing/scala/swing/test/LabelTest.scala new file mode 100644 index 0000000000..ac2b0c6ee0 --- /dev/null +++ b/src/swing/scala/swing/test/LabelTest.scala @@ -0,0 +1,24 @@ +package scala.swing.test + +import scala.swing._ +import scala.swing.event._ + +object LabelTest extends SimpleGUIApplication{ + def top = new MainFrame{ + contents = new Label { + text = "Hello" + import java.awt.event._ + /*peer.addMouseListener (new MouseAdapter{ + override def mousePressed(e : MouseEvent ) { + println("Mouse pressed") + } + })*/ + listenTo(Mouse.clicks) + reactions += { + case MousePressed(_,_,_,_,_) => + println("Mouse pressed2") + } + } + } +} + diff --git a/src/swing/scala/swing/test/TableSelection.scala b/src/swing/scala/swing/test/TableSelection.scala index e0a3a77a74..52d50e39aa 100644 --- a/src/swing/scala/swing/test/TableSelection.scala +++ b/src/swing/scala/swing/test/TableSelection.scala @@ -11,7 +11,7 @@ object TableSelection extends SimpleGUIApplication { List("Sharon", "Zakhour", "Speed reading", 5, false).toArray, List("Philip", "Milne", "Pool", 5, false).toArray) - val ui = new BoxPanel(Orientation.Vertical) { + lazy val ui = new BoxPanel(Orientation.Vertical) { val table = new Table(model, Array("First Name", "Last Name", "Sport", "# of Years", "Vegetarian")) { preferredViewportSize = new Dimension(500, 70) val l = new Table.LabelRenderer[String] diff --git a/src/swing/scala/swing/test/UIDemo.scala b/src/swing/scala/swing/test/UIDemo.scala index 5f1cd93bb8..b1bab2ace1 100644 --- a/src/swing/scala/swing/test/UIDemo.scala +++ b/src/swing/scala/swing/test/UIDemo.scala @@ -95,6 +95,7 @@ object UIDemo extends SimpleGUIApplication { } pages += new Page("Password", password) + pages += new Page("Painting", LinePainting.ui) } val list = new ListView(tabs.pages) { -- cgit v1.2.3