问题
I am creating a GUI using Scala which should play a signal dependent on the algorithm but into the textField, eg. sin(2*Pi*400*t). The playing function works perfectly, however the issue is the input for the GUI. The textField takes the function and converts it to a string, now I was wondering is there a simple way to convert the string back into a function. I was considering matching the input to various valid functions, however I don't want to restrict the possible functions, as I want the user to be more create
I am still relatively new to Scala, hopefully one of you have a better idea. Here is the code I have so far, its a basic setup focusing on functionality.
object PlayApp extends SimpleGUIApplication {
def top = new MainFrame {
title = "Play Function App"
val label = new Label("Type in function to be played")
object Function extends TextField ( columns = 10)
val label2 = new Label("Type in length of time to play")
object Time extends TextField { columns = 10}
val button = new Button("Play")
contents = new BoxPanel(Orientation.Vertical) {
contents += label
contents += Function
contents += label2
contents += Time
contents += button
border = Swing.EmptyBorder(50, 50, 20, 50)
}
var f = "sin(t)"
var x = 0
listenTo(Function, Time, button)
reactions += {
case EditDone(Function) =>
f = Function.text.toString
case EditDone(Time) =>
x = Time.text.toInt
case ButtonClicked(b) =>
play(t => f.toDouble,0,x)
}
}
}
回答1:
You want to compile the line of code that the user enters, with some useful preamble.
I haven't done this so I don't have a snippet handy (but try searching), but you can embed the REPL, have it compile the line of code, and then extract the result.
Here is a snippet that uses ILoop to get some output, but you want to use IMain to get a result with the result class that wraps the user function.
import scala.tools.nsc.interpreter.ILoop
import java.io.StringReader
import java.io.StringWriter
import java.io.PrintWriter
import java.io.BufferedReader
import scala.tools.nsc.Settings
object FuncRunner extends App {
val line = "sin(2 * Pi * 400 * t)"
val lines = """import scala.math._
|var t = 1""".stripMargin
val in = new StringReader(lines + "\n" + line + "\nval f = (t: Int) => " + line)
val out = new StringWriter
val settings = new Settings
val looper = new ILoop(new BufferedReader(in), new PrintWriter(out))
val res = looper process settings
Console println s"[$res] $out"
}
来源:https://stackoverflow.com/questions/13965400/how-to-convert-a-string-from-a-text-input-into-a-function-in-a-scala