examples.gui.DevGUIActor.scala Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2016-2017, Roberto Casadei, Mirko Viroli, and contributors.
* See the LICENCE.txt file distributed with this work for additional
* information regarding copyright ownership.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package examples.gui
import java.awt._
import java.awt.event._
import javax.swing._
import it.unibo.scafi.incarnations.BasicAbstractActorIncarnation
import it.unibo.scafi.space.Point2D
import scala.concurrent.duration._
import scala.collection.mutable.{ Map => MMap }
import akka.actor.{Props, Actor, ActorRef}
import akka.util.Timeout
import it.unibo.scafi.distrib.actor._
class DevGUIActor(val I: BasicAbstractActorIncarnation,
private var dev: ActorRef) extends Actor with ActionListener {
val width = 750
val height = 400
type ID = I.ID
type LSNS = I.LSNS
type EXPORT = I.EXPORT
val interopId = I.interopID
val interopLsns = I.interopLSNS
dev ! MsgAddObserver(self)
/* Local imports and variables */
import scala.collection._
import context.dispatcher
// Provides the ExecutionContext
protected val Log = akka.event.Logging(context.system, this)
var registry: ActorRef = _
/* GUI-related members */
var frame: JFrame = _
var bAddNbr, bSetSensor: JButton = _
var lId, lExport, lRounds: JTextField = _
var localSensors, neighbors, exps: DefaultListModel[String] = _
BuildFrame()
/* Behavior */
def invokeLater(body: =>Any): Unit = {
SwingUtilities.invokeLater(new Runnable(){
override def run(): Unit = {
body
frame.repaint(); frame.revalidate()
}
})
}
def receive: Receive = {
//case GoOn => { frame.repaint(); frame.revalidate() }
case m:I.MyNameIs=> invokeLater {
lId.setText("Id: " + m.id)
this.frame.setTitle(s"ID = ${m.id}")
}
case MsgWithInput("registry", ref: ActorRef) =>
registry = ref
case m:I.MsgNeighborhood => invokeLater {
neighbors.removeAllElements()
m.nbrs.foreach { n => neighbors.addElement(n.toString)}
}
case m:I.MsgLocalSensorValue[_] => invokeLater {
val index = localSensors.toArray.indexWhere{
case s:String => s.startsWith(m.name.toString)
}
if(index >= 0) localSensors.remove(index)
localSensors.addElement(m.name.toString + ":" + m.value)
if(m.name=="LOCATION_SENSOR") {
val pos = m.value.asInstanceOf[Point2D]
this.frame.setBounds(pos.x.toInt*250,pos.y.toInt*200,240,150)
}
if(m.name.toString=="source" && m.value==true) {
this.frame.setBackground(Color.ORANGE)
}
}
case m:I.MsgNbrSensorValue =>
case m:I.MsgExports => invokeLater {
exps.removeAllElements()
m.exports.keySet.foreach {
k => exps.addElement(k + " -> " +
m.exports(k).get(I.factory.emptyPath()))
}
}
case p:I.MsgExport => invokeLater {
lExport.setText(s"${p.export.root[Double]().toInt}")
}
case p:I.MsgRound => invokeLater {
lRounds.setText(s"Rounds: ${p.n}")
}
}
var toPause: Boolean = true
override def actionPerformed(e: ActionEvent): Unit = {
val s = e.getSource
if(s == bAddNbr){
val nbrId = interopId.fromString(JOptionPane.showInputDialog(
frame,
"Enter neighbor's ID",
"Add NBR",
JOptionPane.PLAIN_MESSAGE));
//dev ! MsgWithExport(nbrId, factory.emptyExport())
import akka.pattern.ask
implicit val timeout: Timeout = 1.second
if(registry!=null){
(registry ? I.MsgLookup(nbrId)).onSuccess {
case m:I.MsgDeviceLocation =>
dev ! I.MsgDeviceLocation(m.id, m.ref)
}
}
}
if(s == bSetSensor){
val sv = JOptionPane.showInputDialog(
frame,
"sensorName=value",
"Set Sensor Value",
JOptionPane.PLAIN_MESSAGE).split('=')
if(sv.length==2) {
val k = interopLsns.fromString(sv(0).trim)
var v = sv(1).trim
val posPattern = """\((\d+(?:\.\d+)?);(\d+(?:\.\d+)?)\)""".r
val posMatch = posPattern.findFirstMatchIn(v)
dev ! I.MsgLocalSensorValue(k, v match {
case _ if posMatch.isDefined => new Point2D(posMatch.get.group(1).toDouble, posMatch.get.group(2).toDouble)
case "true" | "false" => v.toBoolean
case _ if v.forall(_.isDigit) => v.toInt
case _ if v.forall(c => c=="." || c.isDigit) => v.toDouble
case _ => v
})
}
}
}
def BuildFrame(): Unit = {
frame = new javax.swing.JFrame("GUI: " + self.path.name)
frame.setSize(width, height)
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
val panel = new JPanel()
frame.setContentPane(panel)
panel.setLayout(new BorderLayout())
val topPanel = new JPanel()
lId = new JTextField("Id: ")
lId.setEnabled(false)
lId.setFont(new Font("Arial", Font.BOLD, 25))
lExport = new JTextField("")
lExport.setEnabled(false)
lExport.setFont(new Font("Arial", Font.BOLD, 25))
lRounds = new JTextField("Rounds: ")
lRounds.setEnabled(false)
lRounds.setFont(new Font("Arial", Font.BOLD, 18))
//topPanel.add(lId)
topPanel.add(lExport)
//topPanel.add(lRounds)
panel.add(topPanel, BorderLayout.NORTH)
localSensors = new DefaultListModel[String]()
val sensorList = new JList[String](localSensors)
sensorList.setLayoutOrientation(JList.VERTICAL)
sensorList.setVisibleRowCount(-1)
val sensorListWrapper = new JScrollPane()
sensorListWrapper.setViewportView(sensorList)
sensorListWrapper.setBounds(0,0,200,400)
panel.add(sensorListWrapper, BorderLayout.WEST)
exps = new DefaultListModel[String]()
val expsList= new JList[String](exps)
expsList.setLayoutOrientation(JList.VERTICAL)
expsList.setVisibleRowCount(-1)
val expsListWrapper = new JScrollPane()
expsListWrapper.setViewportView(expsList)
expsListWrapper.setBounds(0,0,200,400)
panel.add(expsListWrapper, BorderLayout.CENTER)
neighbors = new DefaultListModel[String]()
val nbrList= new JList[String](neighbors)
nbrList.setLayoutOrientation(JList.VERTICAL)
nbrList.setVisibleRowCount(-1)
val nbrListWrapper = new JScrollPane()
nbrListWrapper.setViewportView(nbrList)
nbrListWrapper.setBounds(0,0,200,400)
panel.add(nbrListWrapper, BorderLayout.EAST)
val cmdPanel = new JPanel()
cmdPanel.setLayout(new FlowLayout())
bAddNbr = new JButton("AddNBR")
bSetSensor = new JButton("SetSensor")
bAddNbr.addActionListener(this)
bSetSensor.addActionListener(this)
cmdPanel.add(bAddNbr)
cmdPanel.add(bSetSensor)
//panel.add(cmdPanel, BorderLayout.SOUTH)
//frame.pack()
frame.setVisible(true)
// GUI will update at 500 ms interval
//context.system.scheduler.schedule(1 second, 100 millis) { self ! GoOn }
context.system.scheduler.scheduleOnce(5.seconds) {
frame.addComponentListener(new ComponentListener {
override def componentShown(e: ComponentEvent): Unit = {}
override def componentHidden(e: ComponentEvent): Unit = {}
override def componentMoved(e: ComponentEvent): Unit = {
val c = e.getSource().asInstanceOf[Component]
val loc = c.getLocationOnScreen()
println(s"Moved to $loc")
val pos = Point2D((loc.getX / 250).round, (loc.getY / 200).round)
//self ! I.MsgLocalSensorValue("LOCATION_SENSOR", pos)
dev ! I.MsgLocalSensorValue("LOCATION_SENSOR", pos)
}
override def componentResized(e: ComponentEvent): Unit = {}
})
}
}
}
object DevGUIActor {
def props(inc: BasicAbstractActorIncarnation, devActorRef: ActorRef) =
Props(classOf[DevGUIActor], inc, devActorRef)
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy