3

I have a very simple scala swing app and I want to return a value to the command line app from where the Swing app was triggered. If I select value "b", I want the GUI to return value "b" to me as soon as the button is pressed. How do I make the app wait for the correct user input and how do I return the value to the calling app?

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?
}

Thanks!

Edit: At the moment I am not packaging it into a jar. Just compiling it and then running it with scala...

I need to return the selected value from the "GUI" to the "GuiDemo" scala app to do some further processing in scala.

So question really is:

How to wait for the GUI part to finish and then return (hand over) the selected value to GuiDemo.

4

3 回答 3

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)
于 2013-06-24T19:01:10.827 回答
0

你可能已经知道你会得到的答案是“不要那样做”。相反,您可以设置一个Reactor监听按钮并在其中执行您的代码。

但是,如果你真的想为你的 main 方法返回一个值,你可以使用Scala 2.10中的Futures 和 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
于 2013-06-28T22:03:42.983 回答
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 “转换”为父级,因此不会产生额外的对话框。

于 2013-06-25T00:01:25.800 回答