I'm trying to set the string of a Text object from a Thread but it's giving me this error:
Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(Unknown Source)
at javafx.scene.Scene.addToDirtyList(Unknown Source)
at javafx.scene.Node.addToSceneDirtyList(Unknown Source)
at javafx.scene.Node.impl_markDirty(Unknown Source)
at javafx.scene.shape.Shape.impl_markDirty(Unknown Source)
at javafx.scene.Node.impl_geomChanged(Unknown Source)
at javafx.scene.text.Text.impl_geomChanged(Unknown Source)
at javafx.scene.text.Text.needsTextLayout(Unknown Source)
at javafx.scene.text.Text.needsFullTextLayout(Unknown Source)
at javafx.scene.text.Text.access$200(Unknown Source)
at javafx.scene.text.Text$2.invalidated(Unknown Source)
at javafx.beans.property.StringPropertyBase.markInvalid(Unknown Source)
at javafx.beans.property.StringPropertyBase.set(Unknown Source)
at javafx.beans.property.StringPropertyBase.set(Unknown Source)
at javafx.scene.text.Text.setText(Unknown Source)
at uy.com.vincent.fx.handling.TableController$1.run(TableController.java:70)
Handler Class:
#FXML
private Text timer;
#Override
public void initialize(URL url, ResourceBundle rb) {
init();
new Thread() {
public void run() {
while(true) {
Calendar cal = new GregorianCalendar();
int hour = cal.get(cal.HOUR);
int minute = cal.get(cal.MINUTE);
int second = cal.get(cal.SECOND);
int AM_PM = cal.get(cal.AM_PM);
String time = hour + "" + minute + "" + second;
timer.setText(time);
}
}
}.start();
}
I'm following a tutorial.
The guy in the tutorial is not using JavaFX.
I have tried using Platform.runLater(), it does work but it crashes my program.
I also tried creating a Timer on the Platform.runLater(new Runnable() { }) method but it gives me the same error as before.
Wrap timer.setText() in Platform.runLater(). Outside it, inside the while loop, add Thread.sleep(1000);
The reason behind Illegal State Exception is you are trying to update UI on some thread other than JavaFX Application thread.
The reason why your app was crashing when you added it was you were overloading the UI thread by adding a process to be executed on the UI thread infinitely. Making the thread sleep for 1000ms will help you overcome the issue.
If possible replace while(true) with a Timer or TimerTask.
For more options follow this link
Related
When I start TimerTask and then I finish, and then start again it shows this error, why?
this error:
[16:30:02] [Client thread/INFO] [MacroSK]: KEY_L
[16:30:06] [Client thread/INFO] [MacroSK]: KEY_O
[16:30:08] [Client thread/INFO] [MacroSK]: KEY_L
[16:30:08] [Client thread/ERROR] [FML]: Exception caught during firing event net.minecraftforge.fml.common.gameevent.TickEvent$ClientTickEvent#1bc14017:
java.lang.IllegalStateException: Task already scheduled or cancelled
at java.util.Timer.sched(Unknown Source) ~[?:1.8.0_161]
at java.util.Timer.scheduleAtFixedRate(Unknown Source) ~[?:1.8.0_161]
at com.skelletonx.MacroSK.handler.KeybindHandler.Shopmsg(KeybindHandler.java:53) ~[KeybindHandler.class:?]
at com.skelletonx.MacroSK.handler.KeybindHandler.onTickEvent(KeybindHandler.java:63) ~[KeybindHandler.class:?]
at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_6_KeybindHandler_onTickEvent_ClientTickEvent.invoke(.dynamic) ~[?:?]
at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:55) ~[ASMEventHandler.class:?]
at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:140) [EventBus.class:?]
at net.minecraftforge.fml.common.FMLCommonHandler.onPostClientTick(FMLCommonHandler.java:371) [FMLCommonHandler.class:?]
at net.minecraft.client.Minecraft.func_71407_l(Minecraft.java:2152) [bsu.class:?]
at net.minecraft.client.Minecraft.func_71411_J(Minecraft.java:1028) [bsu.class:?]
at net.minecraft.client.Minecraft.func_99999_d(Minecraft.java:345) [bsu.class:?]
at net.minecraft.client.main.Main.main(SourceFile:120) [Main.class:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_161]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_161]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_161]
at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_161]
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
my code :
Timer timer = new Timer();
final TimerTask ts = new TimerTask(){
#Override
public void run() {
Minecraft.getMinecraft().thePlayer.sendChatMessage(Ini.getIni("Loja"));
}
};
int delaymsg = Integer.parseInt(Ini.getIni("DelayL"));
public void Shopmsg() {
timer.scheduleAtFixedRate(ts,1000*delaymsg,1000*delaymsg);
}
#SideOnly(Side.CLIENT)
#SubscribeEvent(priority=EventPriority.NORMAL, receiveCanceled=true)
public void onTickEvent(TickEvent.ClientTickEvent event) {
if(event.phase == TickEvent.Phase.END) {
if (mc.inGameHasFocus) {
if (keyBindings[0].isPressed()) {
LogHelper.info("KEY_L");
Shopmsg();
}
if(keyBindings[1].isPressed()) {
LogHelper.info("KEY_O");
ts.cancel();
}
}
}
}
how can I do that when I finish TaskTime, I can start again?
if not stop, stop and restart the tasktime is it possible to pause and resume?
TimerTask can only be scheduled by a Timer once.
Continuing working with Timer, you would need to recreate a new TimerTask ts each time in ShopMsg().
It's worth saying though that Timer has been superseded by ScheduledExecutorService these days. This is generally more flexible...
E.g. to create the executor (in place of Timer):
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
Then to schedule the loop:
ScheduledFuture<?> future = scheduledExecutorService.scheduleAtFixedRate(
() -> Minecraft.getMinecraft().thePlayer.sendChatMessage(Ini.getIni("Loja")),
delaymsg,
delaymsg,
TimeUnit.SECONDS);
And to stop that schedule:
future.cancel(false);
How about this closure-like approach:
(high-level code but still cute and workable)`
...
<inside method>
...
class NewTimerTask extends TimerTask {
#Override
public void run() {
actionToBePerformed.run();
timer.schedule(new TimerTask() {
#Override
public void run() {
NewTimerTask.this.run();
}
}, countOffset(morningHour, eveningHour));
}
}
timer.schedule(new NewTimerTask(), countOffset(morningHour, eveningHour));
I always create a new TimerTask instance and then schedule it with the same instance one of Timer. There are no issues but still I had one report from Firebase Crashlytics and I think it's related to Thread termination of timer:
So it has nothing to do with reusing the same instance of TimerTask cause in my case it's not possible!
So mb we need to recreate Timer instance in try...catch
I'm using the ARIN rest whois service to look up the organizations for a list of IP addresses. Since the list is very long (the one below is just a very small subset), I opted to do this with threads for faster performance.
public class SimpleThreadPool {
public final static String[] ips = {
"192.150.16.64","192.243.232.36","208.77.139.8","63.140.35.160",
"63.140.35.161","63.140.35.162","63.140.59.142","63.140.61.200",
"66.235.132.238","66.235.137.133","66.235.138.18","66.235.138.192",
"66.235.138.195","66.235.139.152","66.235.139.172","66.235.139.204",
"66.235.139.205","66.235.139.206","66.235.139.227","66.235.141.144",
"66.235.141.145","66.235.141.146","66.235.141.16","66.235.142.20",
"66.235.142.24","66.235.141.145","184.106.60.35","207.171.162.26",
"207.171.162.75","207.171.162.95","207.171.185.201","207.171.187.117",
"207.171.187.118","207.171.189.80","207.171.189.81","216.137.37.108",
"216.137.37.122","216.137.37.128","216.137.37.138","216.137.37.140",
"216.137.37.178","216.137.37.183","216.137.37.198","216.137.37.225",
"216.137.37.235","216.137.37.37","216.137.37.52","216.137.37.57",
"216.137.37.6","216.137.37.84"
};
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(4);
for (int i = 0; i < ips.length; i++) {
Runnable worker = new WorkerThread(ips[i]);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {}
System.out.println("All threads finished.");
}
}
And here is WorkerThread:
public class WorkerThread implements Runnable {
private String workingIP;
public WorkerThread(String workingIP) {
this.workingIP = workingIP;
}
#Override
public void run() {
try {
URL url = new URL("http://whois.arin.net/rest/ip/" + workingIP);
InputStream inputStream = null;
HttpURLConnection con = (HttpURLConnection)(url.openConnection());
con.connect();
inputStream = con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String line = null;
while( (line=br.readLine()) != null )
{
if (line.contains("<td>Organization</td><td>")) {
String companyName = line.replace("<td>Organization</td><td>", "").trim();
System.out.println(workingIP + " maps to: " + companyName);
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
On my work machine (w/ an i5-2400, 4GB RAM, 32bit Win7), this code works fine all the way down to around the 45th+ IP address in the array. Then I get java.net.ConnectException errors thrown for the remaining lookups:
...
216.137.37.57 maps to: Amazon.com, Inc.
216.137.37.6 maps to: Amazon.com, Inc.
java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at sun.net.NetworkClient.doConnect(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.<init>(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
If I change the executor's thread pool size to 1, then everything works and no errors are thrown, but obviously the lookups take a lot longer.
The really strange thing is that if I run this same code on my 2011 Core i7 Mac, no errors whatsoever are thrown. Granted, the two are on different networks (my work machine uses my work's network, while my Mac is wirelessly tethered to a smartphone).
Any idea what's going on here, and what I can do to fix it?
You need to write sane error-handling code. It really is that simple. What do you want to do if the connection times out? If you make a lot of connections at once on a slow network, some of them may time out.
I am using Swingworker to request value from url address to dynamically change a version of displayed information. At certain cases this worker is cancelled. The problem is that I get java.lang.InterruptedException sometimes (but not every time I cancel worker). I am not sure what to do with it, moreover I have no idea where it is thrown, I cannot debug it because I get it when I do lots of version changes in short time (I use slider and this happens when I am dragging it for some time) . Everything works fine but I get this annoying error:
java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at sun.plugin2.message.Queue.waitForMessage(Unknown Source)
at sun.plugin2.message.Pipe$2.run(Unknown Source)
at com.sun.deploy.util.Waiter$1.wait(Unknown Source)
at com.sun.deploy.util.Waiter.runAndWait(Unknown Source)
at sun.plugin2.message.Pipe.receive(Unknown Source)
at sun.plugin2.main.client.MessagePassingExecutionContext.doCookieOp(Unknown Source)
at sun.plugin2.main.client.MessagePassingExecutionContext.getCookie(Unknown Source)
at sun.plugin2.main.client.PluginCookieSelector.getCookieFromBrowser(Unknown Source)
at com.sun.deploy.net.cookie.DeployCookieSelector.getCookieInfo(Unknown Source)
at com.sun.deploy.net.cookie.DeployCookieSelector.get(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.setCookieHeader(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.writeRequests(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at org.dbwiki.web.applet.ValueRequester.doInBackground(ValueRequester.java:40)
at org.dbwiki.web.applet.ValueRequester.doInBackground(ValueRequester.java:1)
at javax.swing.SwingWorker$1.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at javax.swing.SwingWorker.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Also after each exception which is showed above additional message is thrown:
sun.plugin2.main.client.PluginMain: unrecognized message ID 46
Interesting thing that exception is only being thrown when program is run in the browser as an applet, if program is run as applet from api no exceptions are thrown.
My StringWorker:
package org.dbwiki.web.applet;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import javax.swing.SwingWorker;
public class ValueRequester extends SwingWorker<Void, Void> {
HtmlGenerator htmlGen;
ArrayList<String[]> versionsData;
String id;
private String dbName;
ValueRequester (HtmlGenerator htmlGen, ArrayList<String[]> versionData, int ver){
try {
this.htmlGen=htmlGen;
if (TreeVisualiser.typeParameter.equals(TreeVisualiser.StructureVisualiserParameter))
this.id=htmlGen.getElem().getVersionElementId(ver);
else if(TreeVisualiser.typeParameter.equals(TreeVisualiser.HistoryVisualiserParameter))
this.id=htmlGen.getElem().getId();
this.dbName=htmlGen.getElem().getDBName();
this.versionsData=versionData;
} catch (Exception e) {
e.printStackTrace();
}
}
protected Void doInBackground() throws Exception {
try{
String value="";
URL historyURL = new URL("http://127.0.0.1:8080/"+dbName+id+"?value");
URLConnection hc = historyURL.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(hc.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
value+=line;
}
in.close();
this.htmlGen.formDisplayerHead();
this.htmlGen.formNodeDataHtml(value,this.versionsData);
this.htmlGen.formDisplayerTail();
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
protected void done()
{
if (!this.isCancelled())
this.htmlGen.dataDisplayer.setText(this.htmlGen.getHtml());
}
}
I have now idea what causes it, how to handle it or at least how to hide it (as everything works normal). Any help would be appreciated.
UPDATE:
I try to catch this exception in the ValueRequester.doInBackround(), however my catch statement don't catch the exception. My updated code of doInBackground():
protected Void doInBackground() throws Exception {
try{
String value="";
URL historyURL = new URL("http://127.0.0.1:8080/"+dbName+id+"?value");
URLConnection hc = historyURL.openConnection();
InputStream inputStrm=hc.getInputStream();
InputStreamReader inputStrmRdr= new InputStreamReader(inputStrm);
this.in = new BufferedReader(inputStrmRdr);
String line;
while ((line = in.readLine()) != null) {
value+=line;
}
this.htmlGen.formDisplayerHead();
this.htmlGen.formNodeDataHtml(value,this.versionsData);
this.htmlGen.formDisplayerTail();
}catch (InterruptedException e){
System.out.println("Interrupted Exception caught!");
// e.printStackTrace();
}
return null;
}
Unfortunately stack trace is still printed instead of my system out message. Any idea what could be wrong here?
As far as I know, an InterruptedException only occurs if some other thread calls Thread.interrupt() on a thread that is blocked. In this case, it is clear that the interrupted thread was in a wait() call at the time.
Looking at the SwingWorker code, it appears that the worker thread will get an interrupt if the thread that scheduled decides to call cancel(true) on it. Depending on what the worker thread is doing at the time, it may get an InterruptedException, or it may just have its Thread.interrupted flag set.
So the solution to your problem would appear to be to find out what is calling cancel(true) on the SwingWorker instance. Then either change it to not do that ... or make your worker class deal with the InterruptedException appropriately. The appropriate behaviour would probably be to catch the exception and quietly return from call(...)
To me it just looks like you are calling worker.cancel(true); (assuming worker is your SwingWorker). The true indicates that if the current Thread is in an interruptible state, the Thread can be interrupted. When this happens, it automatically throws an Exception indicating that the Thread has been interrupted allowing you to release resources and possibly do something. I guess in your case you can safely ignore this and simply close the opened streams.
In your case, depending on how far you are in your "Work", the task may get interrupted or not.
See more information on Thread interruption here.
I just learned how to use threads yesterday and I'm trying to encode some images using threads but I'll get this error
java.lang.IllegalArgumentException: im == null!
I tried doing this exact same thing without threads and it worked fine just kind of slowly, not because of the image io but because of the time it takes to encode images.
the WinDef.HDC is a variable type I got from the JNA library. When I did try it without threads I could easily write out 1000 images (about 60mb).
//The thread class
public class imageEncoderThread extends Thread {
HDC originalImage;
BufferedImage image;
public imageProcessThread (HDC rI) {
originalImage = rI'
}
#Override
public void run() {
//returns a buffered image
image = process(rawImage);
try {
ImageIO.write(image, "jpg", new File (filePath));
} catch (IOException e) {
}
}
}
//full stack trace
Exception in thread "Thread-5" java.lang.IllegalArgumentException: im == null!
at javax.imageio.ImageIO.write(Unknown Source)
at javax.imageio.ImageIO.write(Unknown Source)
at com.capture.SingleImageEncoderThread.run(Thread.java:33)
Exception in thread "Thread-7" java.lang.IllegalArgumentException: im == null!
at javax.imageio.ImageIO.write(Unknown Source)
at javax.imageio.ImageIO.write(Unknown Source)
at com.capture.SingleImageEncoderThread.run(Thread.java:33)
Exception in thread "Thread-6" java.lang.IllegalArgumentException: im == null!
at javax.imageio.ImageIO.write(Unknown Source)
at javax.imageio.ImageIO.write(Unknown Source)
//and so on with the same exception
It's almost certainly the case that you cannot call:
image = JNAScreenShot.encodeRawWindow(rawImage, bounds);
from any thread other than the main ui thread. See:
http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/6398cda5-5393-4b16-b8dc-5bbf8902033f/ (specifically, I do not think HDCs are usable outside the main ui thread).
So, you'll need to create the screenshot first, then pass it to your thread to do the IO (that's probably the slow part, anyway).
I'm trying to do a little program in Java using Eclipse, and I'm a little bit lost.
Could anybody explain me (in a "for dummies way") what do I have to do for repaint a form using a timer?
I'm trying to do something as simple as a clock. I need a timer to repaint it every second.
Something like this:
private void activateTimer()
{
ActionListener myAction;
myAction = new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
whatever.redraw();
}
};
myTimer = new Timer(1000, myAction);
myTimer.start();
}
When the action must be performed, I receive the error:
*Exception in thread "AWT-EventQueue-0" org.eclipse.swt.SWTException: Invalid thread access*
This is the full exception I receive:
Exception in thread "AWT-EventQueue-0" org.eclipse.swt.SWTException: Invalid thread access
at org.eclipse.swt.SWT.error(SWT.java:4282)
at org.eclipse.swt.SWT.error(SWT.java:4197)
at org.eclipse.swt.SWT.error(SWT.java:4168)
at org.eclipse.swt.widgets.Widget.error(Widget.java:468)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:359)
at org.eclipse.swt.widgets.Control.redraw(Control.java:2327)
at default.myTimer$1.actionPerformed(myTimer.java:97)
at javax.swing.Timer.fireActionPerformed(Unknown Source)
at javax.swing.Timer$DoPostEvent.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Any idea or any sample about refreshing a screen every second?
I've followed the instructions in one of the answers but I'm still receiving the same error.
you have to split that to the separete methods, better would be using javax.swing.Action instead of ActionListener
private void activateTimer(){
myTimer = new Timer(1000, myAction);
myTimer.start();
}
private Action myAction = new AbstractAction() {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
whatever.redraw();
}
};
Why not use the timer functionality that is built into the SWT Display class?
private void activateTimer(final Display display)
{
display.timerExec(
1000,
new Runnable() {
public void run() {
whatever.redraw();
// If you want it to repeat:
display.timerExec(1000, this);
}
});
}
This page may be useful.
If you use SWT, do it in SWT way :)
EDIT:
The problem is widget should be updated by eclipse's thread. Try this code.
Job job = new Job("My Job") {
#Override
protected IStatus run(IProgressMonitor monitor) {
Display.getDefault().asyncExec(new Runnable() {
#Override
public void run() {
while(true)
{
Thread.sleep(1000);
whatever.redraw();
}
}
});
return Status.OK_STATUS;
}
};
job.schedule();