Scala, aplicación swing sencilla

Pequeño programa swing donde se hace uso de los componentes visuales más sencillos.
La ventana tendrá la siguiente apariencia.




package com.me.vr
import java.io.File
import com.me.vr.classes.RenameFiles
import scala.collection.mutable.ArrayBuffer
import scala.swing._
import scala.swing.event._
/**
  * Clase Singleton.
  */
object GuiProgramOne {
  /**
    * Método main de la clase
    * @param args
    */
  def main(args: Array[String]) {
    val ui = new UI
    ui.visible = true
    // Este mensaje aparece y la ventana sigue ejecutandose, ya que la libreria swing se ocupa de ello
    println("Fin Main function")
  }
}
/**
  * Clase Main que genera la parte visual.
  * La clase UI hereda de scala.swing.MainFrame, la cual es una ventana que puede aparecer en pantalla.
  */
class UI extends MainFrame {
  // En el constructor de esta clase se establecen 3 de los campos heredados de MainFrame
  // Título de la ventana
  title = "UI en Scala"
  // Dimensión de la ventana
  preferredSize = new Dimension(400, 300)
  val lblName = new Label("Texto:")
  val txtName = new TextField(columns = 32)
  val lblCombo = new Label("ComboBox")
  val combo = new ComboBox[String](List("opcion 1", "Opción 2", "Opción 3"))
  val checkBox = new CheckBox("Mayor de edad")
  checkBox.selected = true
  val rbA = new RadioButton("Grupo A")
  val rbB = new RadioButton("Grupo B")
  val rbC = new RadioButton("Grupo C")
  rbC.selected = true
  val btnGroup = new ButtonGroup(rbA, rbB, rbC)
  val btnData = new Button("Obtener datos")
  val btnChangeText = new Button("Cambiar texto")
  val btnExit = new Button("Salir")
  var defaultColor = java.awt.Color.RED
  // contents es lo que se mostrará dentro de la ventana, debe ser un objeto que herede de
  // scala.swing.Component. En el creamos la estructura de componentes de nuestra aplicación
  def restrictHeight(s: Component) {
    s.maximumSize = new Dimension(Short.MaxValue, s.preferredSize.height)
  }
  restrictHeight(txtName)
  restrictHeight(combo)
  contents = new BoxPanel(Orientation.Vertical) {
    contents += new BoxPanel(Orientation.Horizontal) {
      contents += lblName
      contents += Swing.HStrut(5)
      contents += txtName
    }
    contents += Swing.VStrut(5)
    contents += new BoxPanel(Orientation.Horizontal) {
      contents += lblCombo
      contents += Swing.HStrut(5)
      contents += combo
    }
    contents += Swing.VStrut(5)
    contents += Swing.VStrut(5)
    contents += new BoxPanel(Orientation.Horizontal) {
      contents += checkBox
    }
      contents += new BoxPanel(Orientation.Horizontal) {
      contents += rbA
      contents += Swing.HStrut(5)
      contents += rbB
      contents += Swing.HStrut(5)
      contents += rbC
    }
    contents += new BoxPanel(Orientation.Horizontal) {
      contents += btnData
      contents += Swing.HStrut(5)
      contents += btnChangeText
      contents += Swing.HStrut(5)
      contents += btnExit
      contents += Swing.VStrut(5)
    }
    // Capturar eventos: listenTo(s) le indica a Swing que el objeto UI quiere recibir
    // todos los eventos publicados por el objeto
    listenTo(txtName)
    listenTo(combo.selection)
    listenTo(checkBox)
    listenTo(rbA)
    listenTo(rbB)
    listenTo(rbC)
    listenTo(btnData)
    listenTo(btnChangeText)
    listenTo(btnExit)
    // reactions es un bloque para capturar eventos con varias opciones. Cada opción se encarga de capturar
    // un tipo de evento mediante los nombres de las clases como scala.swing.event.ButtonClicked.
    // El parámetro de estos eventos es el componente a campturar, el que causa el evento.
    // Si se escribe el nombre del componente entre (`), solamente se capturará el indicado. Si se indica en
    // minúscula un nombre como s, entonces coincide con cualquier evento de este tipo y s es una variable
    // que referencia la fuente del evento.
    reactions += {
      case EditDone(`txtName`) => println("Texto: " + txtName.text)
      case SelectionChanged(`combo`) => println("Opción: " + combo.selection.item)
      case ButtonClicked(`checkBox`) => println("Mayor de edad: " + checkBox.selected)
      case ButtonClicked(`rbA`) => println("Opción: " + rbA.text)
      case ButtonClicked(`rbB`) => println("Opción: " + rbB.text)
      case ButtonClicked(`rbC`) => println("Opción: " + rbC.text)
      case ButtonClicked(`btnData`) => getData()
      case ButtonClicked(`btnChangeText`) => changeText()
      case ButtonClicked(`btnExit`) => exit()
        // source: Component, other: Option[Component], temporary: Boolean
      case FocusGained(source, other, temporary) => focusGained(source, other, temporary)
      case FocusLost(source, other, temporary) => focusLost(source, other, temporary)
    }
    for (e <- font="">contents) {
      e.xLayoutAlignment = 0.0
    }
    border = Swing.EmptyBorder(10, 10, 10, 10)
    /*
    * Swing.VStrut(a) es un componente vacío con 1 pixel de altura y 0 de anchura.
    * Swing.HStrut(a) es un componente vacío con 1 pixel de ancho y 0  de altura.
    * Swing.Glue no teiene espacio, pero puede ser extendido tanto como quieras cambiar el tamaño de la ventana.
    * Swing.HGlue y Swing.VGlue, pueden extender solamente horizontalmente y verticalmente.
    */
  }
  /**
    * Mostrar ventana emergente con mensaje
    */
  def getData() {
    // Dialog.showMessage muestra una ventana pop up con un mensaje.
    // El primer argumento es el componente padre, que es usado para posicionar la ventana en el a pantalla. head es el
    // primer e único elemento de contents
    val data = s"Texto: ${txtName.text}\nCombo: ${combo.selection.item}\nMayor edad: ${checkBox.selected}\nGrupo: ${btnGroup.selected.get.text}"
    Dialog.showMessage(contents.head, message=data, title="Dialog.showMessage")
  }
  /**
    * Cambiar el texto
    */
  def changeText() {
    // Dialog.showInput permite al usuario introducir datos. Debes establecer una cadena initial o "" si quieres
    // que el campo inicialmente está vacío en el pop up.
    // El resultado es del tipo Option[String]. Si se introduce algo irá a Some(s) and establecerá la variable s
    // con el valor introducido por el usuario.
    // Si se presiona "Cancel" o Close el resultado será None
    val r = Dialog.showInput(parent=contents.head, message="Nuevo texto",title="Dialog.showInput", initial=lblName.text)
    r match {
      case Some(s) => txtName.text = s
      case None =>
    }
  }
  /**
    * Cerrar ventana
    */
  def exit() {
    // Dialog.showConfirmation muestra un pop up con una pregunta. El valor devuelto indica
    // la elección realizada por el usuario y es una de Dialog.Result.Yes, Dialog.Result.Ok
    // Dialog.Result.No, Dialog.Result.Cancel o Dialog.Result.Closed (si el usuario cierra el dialogo presionando la x
    // de la ventana).
    // El valor opcional optionType permite decidir que botón será mostrado. Los valores posibles son:
    // Dialog.Options.YesNo, Dialog.Options.YesNoCancel y Dialog.Options.OkCancel.
    val res = Dialog.showConfirmation(contents.head,
      "¿Está seguro que desea salir?",
      optionType=Dialog.Options.YesNo,
      title=title)
    if (res == Dialog.Result.Ok)
      sys.exit(0)
  }
  /**
    * Obtener el foco de un componente
    * @param source
    * @param other
    * @param temporary
    */
  def focusGained(source: Component, other: Option[Component], temporary: Boolean): Unit = {
    source.opaque = true
    defaultColor = source.background;
    source.background = java.awt.Color.RED
  }
  /**
    * Perder el foco de un componente
    * @param source
    * @param other
    * @param temporary
    */
  def focusLost(source: Component, other: Option[Component], temporary: Boolean): Unit = {
    source.background = defaultColor
  }
}




Comentarios

Entradas populares de este blog

Java. Texto de colores en la consola

javax.swing.JPasswordField

javax.swing.JList