从Scala + Swing应用程序返回一个值

时间:2013-06-24 18:38:37

标签: swing scala scala-swing

我有一个非常简单的scala swing应用程序,我想将一个值返回到触发Swing应用程序的命令行应用程序。 如果我选择值“b”,我希望GUI在按下按钮后立即向我返回值“b”。 如何让应用程序等待正确的用户输入以及如何将值返回到调用应用程序?

import swing._
import event.{ButtonClicked}
object GuiDemo extends App {        

  object GUI extends SimpleSwingApplication {
    val button = new Button {
      text = "Go!"
    }

    val comboBox = new ComboBox(List("a", "b", "c"))
    def top = new MainFrame {
      contents = new FlowPanel {
        contents += comboBox
        contents += button
      }
    }

    listenTo(button)

    reactions += {
      case ButtonClicked(`button`) => { 
        val selection = comboBox.item
        button.enabled_= (false)
      } 
    }    
  }  

  println("Before starting the GUI")
  GUI.main(args)  
  val myValue = GUI.comboBox.item
  println("""Now I need to make a complicated transformation in scala 
  with the selected value: """ + myValue.map(_.toUpper) ) 
  // how do I get the selected value from the GUI?
}

谢谢!

修改 目前我没有将它包装成罐子。只需编译它然后用scala运行它......

我需要将选定的值从“GUI”返回到“GuiDemo”scala应用程序,以便在scala中进行进一步处理。

所以问题确实是:

如何等待GUI部分完成,然后将所选值返回(移交)到GuiDemo

3 个答案:

答案 0 :(得分:2)

一旦访问AWT / Swing,它就会启动事件调度线程,应用程序将继续运行。因此,当用户填写GUI时,退回终端所需要做的就是退出应用程序。

要将“返回值返回到命令行应用程序”,我想这会将内容打印到控制台中。所以:

reactions += {
  case ButtonClicked(`button`) =>
    val selection = comboBox.item
    Console.out.println(selection)
    sys.exit(0)
}

请注意,无需嵌套两个对象(GuiDemoGUI),只需使用一个:

import swing._

object GuiDemo extends SimpleSwingApplication {
  lazy val top = new MainFrame {
    val comboBox = new ComboBox(List("a", "b", "c"))
    val button   = Button("Go!") {
      val selection = comboBox.item
      Console.out.println(selection)
      sys.exit(0)
    }

    contents = new FlowPanel(comboBox, button)
  }
}

如果通过解释器执行该操作,使用scala GuiDemo.scala,则需要通过在文件末尾添加以下行来显式调用main方法:

GuiDemo.main(null)

答案 1 :(得分:0)

这是一个基本的JOptionPane示例,未指定父级,导致必须关闭的延迟JFrame:

import swing._

object InputDialogExample extends SimpleSwingApplication {

  val ui = new BorderPanel {
    //content
  }

  def top = new MainFrame {
    title = "Main Frame"
    contents = ui
  }

  println("Before starting the GUI")

  val choices = List( "alpha", "beta", "gamma" )
  // the first arg is null which results in an empty dialog floating around after the choice is made ( not ideal ).
  val selection = Dialog.showInput( null, null, "Choose an option.", Dialog.Message.Plain, null, choices, choices( 0 ) )

  if( !selection.isEmpty )
    println("Now i have the selected value from the gui: " + selection.head )
}

基于我在评论和您的代码中提出的“scala-swing-newbie”链接中的空MainFrame。如果未选择任何选项,则选择为“无”。

我对Scala很新,所以我不知道是否有可能或如何“转换”MainFrame作为父级,因此不会产生额外的对话框。

答案 2 :(得分:0)

您可能已经收集到了您将得到的答案是“不要那样做”。相反,您可以设置Reactor来收听按钮并在其中执行代码。

但是,如果您确实要将值返回到main方法,可以使用Scala 2.10中的Futures and Promises来执行此操作:

部分导入:

  import scala.concurrent._
  import duration._

在您的主要方法中:

  val p = promise[String]

  new Reactor {
    listenTo(GUI.button)
    reactions += {
      case e: ButtonClicked => p.success(GUI.comboBox.item)
    }
  }

  val myValue = Await.result(p.future, Duration.Inf)
    // this blocks until the future is complete