I have this piece of code, trying to build a timer that will decrease a given value in a TextField (which is supposed to contain minutes needed to finish a job, but those minutes will be given manually and then be decreased by this clock):
import scala.swing._
class ScalaTimer(val delay: Int) {
val tmr: javax.swing.Timer = new javax.swing.Timer(delay, null)
def start() = tmr.start()
def stop() = tmr.stop()
}
object Test33 { //extends SimpleSwingApplication {
val timer = new ScalaTimer(50)
timer.tmr.start
//def top = new MainFrame {
def main(args: Array[String]) {
timer.tmr.addActionListener(Swing.ActionListener(e => {
println(timer.delay - 1)
}))
}
//}
}
I don't get why it doesn't print anything when I use a main() method, but it prints the current given delay when I use a Frame :|
It won't print anything with your code as it stands because your application exits as soon as it's added the ActionListener, and before anything has had a chance to fire it!
Try adding
Thread.sleep(10000);
just before the end of your main method, and you'll find it'll print 49 repeatedly.
It works as it stands with a Frame because that prevents the application from terminating until the Frame is closed.
Related
I struggle to understand why the window I'm doing with openGL stays black.
I don't see where I made a mistake in my code :
import com.jogamp.opengl.awt.GLCanvas
import com.jogamp.opengl.{GL, GLAutoDrawable, GLCapabilities, GLEventListener, GLProfile}
import javax.swing.{JFrame, WindowConstants}
class Game extends JFrame ("Just a window OMG.") with GLEventListener {
val profile: GLProfile = GLProfile.get(GLProfile.GL4)
val capabilities = new GLCapabilities(profile)
val canvas = new GLCanvas(capabilities)
this.setName("Just a window OMG.")
this.getContentPane.add(canvas)
this.setSize(800, 600)
this.setLocationRelativeTo(null)
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
this.setVisible(true)
this.setResizable(false)
canvas.requestFocusInWindow
def play(): Unit = {
}
override def display(drawable: GLAutoDrawable): Unit = {
val gl = drawable.getGL.getGL4
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
gl.glFlush()
}
override def dispose(drawable: GLAutoDrawable): Unit = {}
override def init(drawable: GLAutoDrawable): Unit = {
val gl = drawable.getGL.getGL4
gl.glClearColor(1f, 0f, 0f, 1.0f)
}
override def reshape(drawable: GLAutoDrawable, x: Int, y: Int, width: Int, height: Int): Unit = {}
}
object Main {
def main(args: Array[String]): Unit = {
val game = new Game()
game.play()
}
}
I also tried to put the glClear inside the display method and also put a glClearColor in the init method.
EDIT:
I found it.
Actually the display and init meth were never called.
The listener wasn't attached to the canvas and then it never received any event.
The problem is that I was missing the line
canvas.addGLEventListener(this)
just after the canvas initialisation.
(this line)
val canvas = new GLCanvas(capabilities)
(I'm answering my own question)
So actually the problem was that the display and init method were never called.
As far as I understood it, the GLEventListener is waiting for event and those would trigger the call of the init and display method.
The "thing" that would notice the GLEventListener is the canvas, yet my canvas and the GLEventListener weren't binded.
To do so I added the line
canvas.addGLEventListener(this)
Just after I initialized the canvas and it then I could notice the init and display method called.
First of all, I'm new to Scala. I have the following (working) Scala method(s) that has to wait up to 15 sec for a record to be completed. Usually, after 7 seconds, the record becomes complete. So, I put an Iterator that goes to maximum 15 seconds, if the record is complete it stops (I didn't know how to stop the iteration other than with drop). If it isn't completed, it should sleep 1 sec. The problem is that I have to give as a parameter, the method checkIfRecordIsComplete because I might use this wait method with other Boolean functions. How can I use wait method with... let's say checkIfOtherIsComplete? Thanks!
def checkIfRecordIsComplete(record: Record) = {
println("record.state="+record.state)
if(record.state.contains(Constants.RecordStatusComplete))
true
else
false
}
def checkIfOtherIsComplete(other: Other) = {
println("other.state="+other.state)
if(other.state.contains(Constants.OtherStatusComplete))
true
else
false
}
def wait(recordId: RecordId, maxW: Int): Unit = {
val it = Iterator.iterate(1){_+1}.take(maxW)
while(it.hasNext) {
val recordList = getRecord(recordId)
recordList.records.foreach {
record => {
if(!checkIfRecordIsComplete(record)){
Thread.sleep(1000)
it.next()
}
else
it.drop(maxW)
}
}
}
}
........................
wait(recordId, 15)
You need to find a type that provides a common functionality for Record and Other. In this case, that might be a trait implemented by both. For example:
trait Completable {
def isComplete: Boolean
}
Now, both Record and Other should extend it:
trait Record extends Completable {
// ...
override def isComplete: Boolean = this.state.contains(Constants.RecordStatusComplete)
}
trait Other extends Completable {
// ...
override def isComplete: Boolean = this.state.contains(Constants.OtherStatusComplete)
}
The wait function should be slightly changed in order to have access to a sequence (list) of Completables. In fact, since the check logic is now inside Record and Other, there is no more need to have dedicated functions like checkIfOtherIsComplete:
// returns the Completable to be checked for completion.
// replaces the former getRecord
private def getItems(recordId: RecordId): Seq[Completable] = ???
def wait(recordId: RecordId, maxW: Int): Unit = {
val it = Iterator.iterate(1){_+1}.take(maxW)
while(it.hasNext) {
getItems(recordId).foreach{
item => if (item.isComplete) {
Thread.sleep(1000)
it.next()
} else {
it.drop(maxW)
}
}
}
}
BTW, I doubt a bit about the reliability of the implemented solution to make such checks using this Iterator approach. But since it works, it's might be OK for your case. If you are interested, we can continue to discuss it.
Update
Another approach to implement the waiting sequence might be to use standard Scala features from scala.concurrent.* package.
We can use a Future and await for its completion. For example:
import scala.concurrent.duration.Duration
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Await, Future}
def wait2(recordId: RecordId, maxW: Int): Unit = {
val waitForAllComplete = Future {
while(!getItems(recordId).forall(_.isComplete)) {
Thread.sleep(1000)
}
}
Await.ready(waitForAllComplete, Duration(maxW, "second"))
}
Now, if the sequence is not complete after maxW seconds, there will be a TimeoutException thrown. This might be helpful if you need to ensure that for all the items in the list the state is expected and to handle the unexpected situation.
End-of-update
I wish to pass the value of var/val from one method to another.
eg, I have
object abc {
def onStart = {
val startTime = new java.sql.Timestamp( new Date())
}
def onEnd = {
//use startTime here
}
}
calling:
onStart()
executeReports(reportName, sqlContexts)
onEnd()
Here onStart() and onEnd() are job monitoring functions for executeReports().
executeReports() runs in a loop for 5 reports.
I have tried using global variables like
object abc{
var startTime : java.sql.Timestamp = _
def onStart = {
startTime = new java.sql.Timestamp( new Date())
}
def onEnd = {
//use startTime here
}
}
but the catch with this is when the loop executes for the next report, the startTime does not change.
I also tried using Singleton Class that did not work for me either.
My requirement is to have a startTime for every iteration i.e, for every report.
Any ideas are welcome here. I'll be happy to provide more clarification on my requirement if needed.
The common Scala solution to this is to write a function that wraps other functions and performs the setup and shutdown internally.
def timeit[T]( fun: => T ): T = {
val start = System.currentTimeMillis //Do your start stuff
val res = fun
println (s"Time ${System.currentTimeMillis - start}") // Do your end stuff
res
}
RussS has the better solution, but if for some reason you're wedded to the design you've described, you might try using a mutable val, i.e. a mutable collection.
I got this to compile and pass some small tests.
object abc {
private val q = collection.mutable.Queue[java.sql.Timestamp]()
def onStart = {
q.enqueue(new java.sql.Timestamp(java.util.Calendar.getInstance().getTime.getTime))
}
def onEnd = {
val startTime = q.dequeue
}
}
Base from your requirements, it might be better to do it this way.
case class Job(report: List<Report>) {
def execute // does the looping on Report by calling start and call end to generate monitoring data
private def start // iterate over each Report and calls it's execute method
private def end // iterate over each Report and uses startTime and executionTime to generate monitoring data.
}
abstract class Report {
var startTime: DateTime //Time started for the report
def doReport // unimplemented method that does the report generation.
def execute // first set stateTime to Now then call doReport, lastly calculate executionTime
}
The subtype of the Report should implement the doReport which does actual reporting.
You can also change the Job.execute method to accept
report: List<Report>
so that you can have a singleton Job (For sure, start and end will be the same for all Job you have.)
I'm using akka to dynamically create actors and destroy them when they're finished with a particular job. I've got a handle on actor creation, however stopping the actors keeps them in memory regardless of how I've terminated them. Eventually this causes an out of memory exception, despite the fact that I should only have a handful of active actors at any given time.
I've used:
self.tell(PoisonPill, self)
and:
context.stop(self)
to try and destroy the actors. Any ideas?
Edit: Here's a bit more to flesh out what I'm trying to do. The program opens up and spawns ten actors.
val system = ActorSystem("system")
(1 to 10) foreach { x =>
Entity.count += 1
system.actorOf(Props[Entity], name = Entity.count.toString())
}
Here's the code for the Entity:
class Entity () extends Actor {
Entity.entities += this
val id = Entity.count
import context.dispatcher
val tick = context.system.scheduler.schedule(0 millis, 100 millis, self, "update")
def receive = {
case "update" => {
Entity.entities.foreach(that => collide(that))
}
}
override def postStop() = tick.cancel()
def collide(that:Entity) {
if (!this.isBetterThan(that)) {
destroyMe()
spawnNew()
}
}
def isBetterThan() :Boolean = {
//computationally intensive logic
}
private def destroyMe(){
Entity.entities.remove(Entity.entities.indexOf(this))
self.tell(PoisonPill, self)
//context.stop(self)
}
private def spawnNew(){
val system = ActorSystem("system")
Entity.count += 1
system.actorOf(Props[Entity], name = Entity.count.toString())
}
}
object Entity {
val entities = new ListBuffer[Entity]()
var count = 0
}
Thanks #AmigoNico, you pointed me in the right direction. It turns out that neither
self.tell(PoisonPill, self)
nor
context.stop(self)
worked for timely Actor disposal; I switched the line to:
system.stop(self)
and everything works as expected.
I have a text field which is supposed to hold some manualy given minutes, then I need this given number (these minutes) to be decreased by a timer (I already have configured a timer to give me ticks every 1 second), but I am struggling to find how I can do it simply; can it help if I try to use
scala.concurrent.duration._
frankly, I haven't take a look on it before. Or any other suggestion is welcomed.
My current solution, for somebody that may need it:
class ScalaTimer(val delay: Int) {
val tmr: javax.swing.Timer = new javax.swing.Timer(delay, null)
def start() = tmr.start()
def stop() = tmr.stop()
}
object Test33 { //extends SimpleSwingApplication {
val timer = new ScalaTimer(1000)
timer.start
var remainedtime: Int = 10
def main(args: Array[String]) {
timer.tmr.addActionListener(Swing.ActionListener(e => {
val tm = remainedtime - 1
remainedtime = tm
println(tm)
}))
Thread.sleep(10000);
}
Lets hope that I may use it now, as I want :)