JavaFX freeze window - java

I encountered a problem when I filter a treeView (long process) my application freezes. I tried to do this in a separate thread (Thread), but then I got the error "Not on FX application thread; currentThread = Thread-5"
void InitBtnFind() {
//Event Button Search
btnFind.setOnAction(event -> {
newFind();
if (Config.isRoot()) {
String finalSFilterExt = filterExt.getText();
String finalSearchW = searchWord.getText();
Platform.runLater(() -> {
try {
// imitation of work
Thread.sleep(5000);
fileView.setRoot(treeView.filterChanged(finalSFilterExt, finalSearchW));
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
System.out.println("lol");
});
}
});
}
You can give a sample code to solve my problem.
P.s. Do not lower my reputation, I am really interested in this matter
P.s. my attempt to do this with thread
//Event Button Search
btnFind.setOnAction(event -> {
newFind();
if (Config.isRoot()) {
String finalSFilterExt = filterExt.getText();
String finalSearchW = searchWord.getText();
if (findThread != null && findThread.isAlive())
findThread.interrupt();
findThread = new Thread(() -> {
try {
fileView.setRoot(treeView.filterChanged(finalSFilterExt, finalSearchW));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("lol");
});
findThread.setName("findThread");
findThread.setDaemon(true);
findThread.start();
}
System.out.println("kek");
});

I fixed it this way, I don’t know how correct it is. But it worked for me. I hope it will be useful.
//Event Button Search
btnFind.setOnAction(event -> {
newFind();
if (Config.isRoot()) {
String finalSFilterExt = filterExt.getText();
String finalSearchW = searchWord.getText();
if (findThread != null && findThread.isAlive())
findThread.interrupt();
findThread = new Thread(() -> {
try {
Thread.sleep(2000);
System.out.println("++++++++++++++");
var q =treeView.filterChanged(finalSFilterExt, finalSearchW);
Platform.runLater(()->{fileView.setRoot(q);});
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
});
findThread.setName("findThread");
findThread.setDaemon(true);
findThread.start();
}
});

Related

How can I answer to callback in Java telegram bot?

I'm writing a Java bot with https://github.com/rubenlagus/TelegramBots, and I have a problem, when I click inline keyboard button, this little clock:
appears and after some time it says that my bot is not responding. My bot is actually fully functional except this one thing. Here is how I receive callbacks:
#Override
public void onUpdateReceived(Update update) {
var messagesToSend = updateReceiver.handle(update);
if (messagesToSend != null && !messagesToSend.isEmpty()) {
messagesToSend.forEach(response -> {
if (response instanceof SendMessage) {
try {
execute((SendMessage) response);
} catch (TelegramApiException e) {
e.printStackTrace();
}
} else if (response instanceof SendPhoto) {
try {
execute((SendPhoto) response);
} catch (TelegramApiException e) {
e.printStackTrace();
}
} else if (response instanceof FileSaveRequest) {
FileSaveRequest request = (FileSaveRequest) response;
try {
saveFile(request);
} catch (TelegramApiException | IOException e) {
e.printStackTrace();
}
}
});
}
}
=
This is only part of the whole code
} else if (update.hasCallbackQuery()) {
final CallbackQuery callbackQuery = update.getCallbackQuery();
final long chatId = callbackQuery.getFrom().getId();
final User user = userRepository.findById(chatId)
.orElseGet(() -> userRepository.save(new User(chatId)));
AnswerCallbackQuery acceptCallback = new AnswerCallbackQuery();
acceptCallback.setShowAlert(false);
acceptCallback.setCallbackQueryId(String.valueOf(update.getCallbackQuery().getId()));
acceptCallback.setCacheTime(1000);
List<PartialBotApiMethod<? extends Serializable>> resultList =
new ArrayList<>(
getHandlerByCallBackQuery(callbackQuery.getData())
.handle(user, callbackQuery.getData()));
resultList.add(acceptCallback);
return resultList;
}
As you can see, I still attach AnswerCallbackQuery but it still doesent work. What's wrong?
you must use answercallbackquery
I just already solve that issue. It's not problem on Library but it could error in some exceptions.
var messagesToSend = updateReceiver.handle(update);
if (messagesToSend != null && !messagesToSend.isEmpty()) {
I dont have full your code but I think there's some confused written and happen exception before if (update.callbackQuery())...
Here is my sample:
#Override
public void onUpdateReceived(Update update) {
// I have error, cannot getCallbackQuery because of print which call method getMessage.getText() is null -> happen exception error on the println
// -> System.out.println(update.getMessage.getText());
if (update.hasMessage() && !update.getMessage().getText().isEmpty()) {
String chat_id = update.getMessage().getChatId().toString();
if (update.getMessage().getText().equals("/start")) {
SendMessage sendMessage = new SendMessage();
sendMessage.setText("Here is option:");
sendMessage.setChatId(chat_id);
sendMessage.setParseMode(ParseMode.MARKDOWN);
InlineKeyboardMarkup inlineKeyboardMarkup = new InlineKeyboardMarkup();
List<List<InlineKeyboardButton>> listInlineButton = new ArrayList<>();
List<InlineKeyboardButton> reportSaleBtn = new ArrayList<>();
List<InlineKeyboardButton> reportBuyBtn = new ArrayList<>();
List<InlineKeyboardButton> reportPriceBtn = new ArrayList<>();
InlineKeyboardButton saleBtn = new InlineKeyboardButton();
InlineKeyboardButton buyBtn = new InlineKeyboardButton();
InlineKeyboardButton priceBtn = new InlineKeyboardButton();
saleBtn.setText(Constant.SALE_REPORT_TEXT);
saleBtn.setCallbackData(Constant.SALE_REPORT);
buyBtn.setText(Constant.BUY_REPORT_TEXT);
buyBtn.setCallbackData(Constant.BUY_REPORT);
priceBtn.setText(Constant.PRICE_TEXT);
priceBtn.setCallbackData(Constant.PRICE_REPORT);
reportSaleBtn.add(saleBtn);
reportBuyBtn.add(buyBtn);
reportPriceBtn.add(priceBtn);
listInlineButton.add(reportSaleBtn);
listInlineButton.add(reportBuyBtn);
listInlineButton.add(reportPriceBtn);
inlineKeyboardMarkup.setKeyboard(listInlineButton);
sendMessage.setReplyMarkup(inlineKeyboardMarkup);
try {
execute(sendMessage);
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
}
else if (update.hasCallbackQuery()) {
CallbackQuery callbackQuery = update.getCallbackQuery();
String data = callbackQuery.getData();
String chat_id = callbackQuery.getMessage().getChat().getId().toString();
SendChatAction sendChatAction = new SendChatAction();
if (data.equals(Constant.SALE_REPORT)) {
sendChatAction.setChatId(chat_id);
SendMessage sendMessage = new SendMessage();
sendMessage.setText("Generating report, please wait!");
sendMessage.setChatId(chat_id);
try {
sendChatAction.setAction(ActionType.TYPING);
execute(sendChatAction);
execute(sendMessage);
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
}
Why it got an error. Click we click on /start Bot will display all inlinekeyboard.
In the button you only setText() and setCallbackData(). So update.GetMessage() is null.
In while update.getMessage().getText() is null cannot print out. So it is error and it skip the else if (update.hasCallbackQuery()) {...}
I think you can check again your code below:
#Override
public void onUpdateReceived(Update update) {
//check carefully before if may there's exception error before if
}
I hope what I explain may solve your problems too.

Returning values from thread

I am running selenium tests inside a for loop which takes time.
I needed to indicate the progress of those tests using javafx progressbar.
So I replaced the code inside for loop with a task.
Following is my code
The runTests() method returns a String which is displayed as an Alert
I cannot return a String from inside Task<Void> as the return type is Void
The test code is inside runTest(data) method which returns true or false
#FXML
private void handleRunTestButton(ActionEvent aEvent) throws IOException {
String testResultMessage = runTests();
if (!testResultMessage.equals("Testing Complete!")) {
Alert alert = DialogUtils.getAlert("Info", "Information", testResultMessage, "info");
alert.showAndWait();
} else {
Alert alert = DialogUtils.getAlert("Error", "Error(s)", testResultMessage, "error");
alert.showAndWait();
}
}
private String runTests() {
/* xlsx read */
FileInputStream fis = null;
File testDataFile = null;
try {
fis = new FileInputStream(selectedTestDataFile);
} catch (FileNotFoundException e) {
return "File Input Stream Error: File Not Found";
}
// Finds the workbook instance for XLSX file
XSSFWorkbook myWorkBook = null;
try {
myWorkBook = new XSSFWorkbook(fis);
} catch (IOException e) {
return "XSSFWorkbook I/O Error";
}
// Return first sheet from the XLSX workbook
XSSFSheet mySheet = myWorkBook.getSheetAt(0);
int totalWids = mySheet.getLastRowNum();
final Task<Void> task = new Task<Void>() {
#Override
protected Void call() throws Exception {
for (int rowIndex = 1; rowIndex <= totalWids; rowIndex++) {
updateProgress(rowIndex, totalWids);
Row row = mySheet.getRow(rowIndex);
if (row != null) {
String data = "";
Cell cellData = row.getCell(2);
if (cellData != null) {
data = cellWid.getStringCellValue();
boolean testresult = runTest(data);
System.out.println(rowIndex + ". data = " + data + ", testresult = " + testresult);
}
}
}
return null;
}
};
progressBar.progressProperty().bind(task.progressProperty());
progressIndicator.progressProperty().bind(task.progressProperty());
final Thread thread = new Thread(task, "task-thread");
thread.setDaemon(true);
thread.start();
/* xlsx read */
FileOutputStream fos = null;
try {
fos = new FileOutputStream(selectedTestDataFile);
} catch (FileNotFoundException e) {
try {
myWorkBook.close();
} catch (IOException e1) {
return "Error: Please Close Workbook";
}
return "Error: File Not Found";
}
try {
myWorkBook.write(fos);
} catch (IOException e) {
try {
myWorkBook.close();
} catch (IOException e1) {
return "Error: Please Close Workbook";
}
return "Error: Workbook Write";
}
try {
fos.close();
} catch (IOException e) {
try {
myWorkBook.close();
} catch (IOException e1) {
return "Error: Please Close Workbook";
}
return "Error: File Output Stream";
}
try {
myWorkBook.close();
} catch (IOException e) {
return "Error: Please Close Workbook";
}
try {
fis.close();
} catch (IOException e) {
return "Error: Input file format";
}
return "Testing Complete!";
}
However, now it returns Testing Complete! while the tests are still running.
I am new to multithreading. Please suggest me how to structure the code.
How can I make the runTests() method return a String value from inside
final Task<Void> task = new Task<Void>() {
#Override
protected Void call() throws Exception {
for () {
}
return null;
}
};
Before this, when I didn't use Task my code showed the alert properly however the progress bar did not update despite of setting the progress from within the for loop.
Your code, in general, seems pretty solid, but there are several problems.
The task you created does the trick, and the progress bar will work, but it uses a thread so returning that the tests are complete without confirming the progress of the thread is wrong. Because the tests are in a thread and the method returns a value without being dependent on it, the value is returned before the tests are done.
When calling thread.start() the thread starts execution seperatly from your current thread, meaning that your code continues to execute as usual even if the thread was not done.
You have 2 possible options: keep the thread, or don't. If you don't keep the thread, that means that the tests are executed in the method which causes the javaFX event that called it to wait for the tests to finish. This is a bad idea because now the javaFX thread is stuck and the window can't handle any other events (basically, iresponsive).
A good option is to keep the thread, only that at the end of the thread you could show a dialog indicating whether the tests were complete or not. To do that you can use Platform.runLater(runnable) and pass it a Runnable object which shows the dialog:
Platform.runLater(()->{
//show dialog
});
It is required because you can't show a dialog while not in the javaFX thread. This allows you to run something in the javaFX thread.
Another issue is the fact that you're accessing the files outside of your thread. Meaning that at the same time the thread runs your test, you attempt to access the files and write to them. Instead of doing that, you should either write to the file in the thread or before it is started.
To summerize it all, you should use your thread to execute the tests and show the dialogs which indicate whether or not the tests were completed. Writing to your test file should not be done while the thread is still executing tests, but rather after the thread was finished, so you can do it at the end of the task.
public void runTests(){
if(testsRunning) return;
testsRunning = true;
final Task<Void> task = new Task<Void>() {
#Override
protected Void call() throws Exception {
FileInputStream fis = null;
File testDataFile = null;
try {
fis = new FileInputStream(selectedTestDataFile);
} catch (FileNotFoundException e) {
displayResponse("File Input Stream Error: File Not Found");
}
// Finds the workbook instance for XLSX file
XSSFWorkbook myWorkBook = null;
try {
myWorkBook = new XSSFWorkbook(fis);
} catch (IOException e) {
displayResponse("XSSFWorkbook I/O Error");
}
// displayResponse(first sheet from the XLSX workbook
XSSFSheet mySheet = myWorkBook.getSheetAt(0);
int totalWids = mySheet.getLastRowNum();
for (int rowIndex = 1; rowIndex <= totalWids; rowIndex++) {
updateProgress(rowIndex, totalWids);
Row row = mySheet.getRow(rowIndex);
if (row != null) {
String data = "");
Cell cellData = row.getCell(2);
if (cellData != null) {
data = cellWid.getStringCellValue();
boolean testresult = runTest(data);
System.out.println(rowIndex + ". data = " + data + ", testresult = " + testresult);
}
}
}
/* xlsx read */
FileOutputStream fos = null;
try {
fos = new FileOutputStream(selectedTestDataFile);
} catch (FileNotFoundException e) {
try {
myWorkBook.close();
} catch (IOException e1) {
displayResponse("Error: Please Close Workbook");
}
displayResponse("Error: File Not Found");
}
try {
myWorkBook.write(fos);
} catch (IOException e) {
try {
myWorkBook.close();
} catch (IOException e1) {
displayResponse("Error: Please Close Workbook");
}
displayResponse("Error: Workbook Write");
}
try {
fos.close();
} catch (IOException e) {
try {
myWorkBook.close();
} catch (IOException e1) {
displayResponse("Error: Please Close Workbook");
}
displayResponse("Error: File Output Stream");
}
try {
myWorkBook.close();
} catch (IOException e) {
displayResponse("Error: Please Close Workbook");
}
try {
fis.close();
} catch (IOException e) {
displayResponse("Error: Input file format");
}
displayResponse("Testing Complete!");
return null;
}
private void displayResponse(String testResultMessage){
Platform.runLater(()->{
if (testResultMessage.equals("Testing Complete!")) {
Alert alert = DialogUtils.getAlert("Info", "Information", testResultMessage, "info");
alert.showAndWait();
} else {
Alert alert = DialogUtils.getAlert("Error", "Error(s)", testResultMessage, "error");
alert.showAndWait();
}
testsRunning = false;
});
}
};
progressBar.progressProperty().bind(task.progressProperty());
progressIndicator.progressProperty().bind(task.progressProperty());
final Thread thread = new Thread(task, "task-thread");
thread.setDaemon(true);
thread.start();
}
So this code now does everything test related in the thread and doesn't interrupt your window from handling events. There is one problem from this: someone might press the runTests button again, while the tests are running. One option is to use a boolean indicating whether the tests are already active and check its value when runTests is called which I added and is called testsRunning. displayResponse is called when the tests where finished (completed or not) and it displayes the response dialog.
Hope I helped, and sorry for the long answer.
First off, you can't return a value from the thread in the sense you want it to without blocking. Instead, try calling a method when the thread is done.
Let say we have this thread that runs some intensive task (in this case a simple forloop) and you want it to "return" the sum when it is done:
private void startMyThread() {
Thread t = new Thread( () -> {
System.out.println("Thread Started.");
// Some intensive task
int sum = 0;
for(int i = 0; i < 1000000; i++) {
sum++;
}
System.out.println("Thread ending.");
threadIsDone(sum);
});
System.out.println("Starting Thread.");
t.start();
}
Instead of getting your return value from startMyThread() you wait to execute your action until threadIsDone() is called:
private void threadIsDone(int sum) {
Platform.runLater( () -> {
/* Update Progress Bar */
System.out.println("Updated Progress Bar");
});
System.out.println("Thread ended.");
}
You'll notice I use Platform.runLater() inside the method because all updates to JavaFx elements needs to be done on the main thread and since we called threadIsDone() from a different thread, we need to tell JavaFx that we want it to do this action on the main thread and not the current thread.

A `try catch //this is a workaround` in the method. How should it be rewrtten?

A project source code has a Java method for SQL handling. The method does work, but it uses a questionable workaround: try-catch block at the very end of the method for normal execution. What is the correct way to implement it?
public void run() {
if (running) {
return;
}
running = true;
while(null == Common.server || null == Common.database || !ConnectionsPool.isInitialized()) {
// Wait until the database is set before continuing...
try {
Thread.sleep(1000);
}
catch(Exception ex) {}
}
while(running) {
final Connections cs = ConnectionsPool.getConnections();
Connection c = null;
while(!entries.isEmpty()) {
if (null == c) {
c = cs.getConnection();
}
SQLLogEntry entry = entries.remove();
if (null != entry) {
try {
write(entry, c); //find usages
}
catch (SQLException ex) {
writeLogFile("Could not write entry to SQL", ex);
}
}
}
if (null != c) {
try {
c.commit();
}
catch (SQLException ex) {
writeLogFile("Could commit to SQL", ex);
try {
c.rollback();
}
catch (SQLException ex1) {
}
// log
final StringWriter err = new StringWriter();
ex.printStackTrace(new PrintWriter(err));
EditorTransactionUtil.writeLogFile(err.toString());
// for user
final String msg = "Exception: " + EditorUtil.getErrorMessage(ex.getMessage());
try {
SwingUtilities.invokeAndWait(() -> {
JOptionPane.showMessageDialog(null, msg);
});
}
catch (Throwable ex1) {
}
}
finally {
cs.returnConnection(c);
}
c = null;
}
synchronized(entries) {
try {
entries.wait(1000);
}
catch (InterruptedException ex) {
// This is a workaround to process this loop...
}
}
}
writeLogFile("SQLMsgLogger run loop stopping...");
}
Problems with this code start here.
If(running) return;
running=true;
This is clearly an attempt to make sure that only one thread executes. This is a wrong way to check concurrency. Second tread might kick in right when if check ended, but assignment didn't start yet. You need to use syncronizible interface.
As for the disposed try catch block - as Konrad pointed out it will not be executed without Thread.interrupt() call. It might be dead code left from previous versions.

J2ME media player doesn't play

public class Midlet extends MIDlet implements CommandListener{
Player p;
public void startApp() {
Display.getDisplay(this).setCurrent(new SongsList(this));
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
notifyDestroyed();
}
public void commandAction(Command cmnd, Displayable dsplbl) {
if (cmnd.getLabel().equals("Exit"))
{
destroyApp(true);
}
else
{
try {
//InputStream is = getClass().getResourceAsStream("/res/getlucky.mpeg");
//p = Manager.createPlayer(is, "audio/mpeg");
p = Manager.createPlayer("http://puu.sh/6n9jC.mp3");
p.realize();
p.start();
} catch (IOException ex) {
ex.printStackTrace();
} catch (MediaException ex) {
ex.printStackTrace();
}
}
}
}
this is the songslist class :
public class SongsList extends List{
public SongsList(Midlet midlet)
{
super("Songs", List.IMPLICIT);
append("get lucky", null);
addCommand(new Command("Exit", Command.EXIT, 0));
addCommand(new Command("Select", Command.OK, 0));
setCommandListener(midlet);
}
}
tried use via file stored in project (its under src/res):
inputStream = getClass().getResourceAsStream("res/getlucky.mpg");
audioPlayer = Manager.createPlayer(inputStream, "audio/mpg");
as well as from HTTP:
//audioPlayer = Manager.createPlayer("http://puu.sh/6n9jC.mp3");
Nothing works, what am I doing wrong?
EDIT:
I've tried to delete my application and just copy paste it to a new project and it worked for some reason.. now I encounter new problems:
1) I try to play a song - this is the link http://puu.sh/6n9jC.mp3
its not playing so I guess there's a limited file size for what can be played can someone tell me what is this limit ?
2) Im trying to record the audio with RecordPlayer but its always null
public AudioAnalyzer()
{
try {
thread = new Thread(this);
recordFinished = false;
//inputStream = getClass().getResourceAsStream("res/getlucky.mpg");
//audioPlayer = Manager.createPlayer(inputStream, "audio/mpg");
audioPlayer = Manager.createPlayer("http://puu.sh/35YTG.mp3");
//audioPlayer = Manager.createPlayer("http://puu.sh/6n9jC.mp3");
audioPlayer.realize();
System.out.println(System.getProperty("supports.audio.capture"));
recordControl = (RecordControl)audioPlayer.getControl("RecordControl");
recordOutput = new ByteArrayOutputStream();
recordControl.setRecordStream(recordOutput);
recordControl.startRecord();
audioPlayer.start();
//thread.start();
} catch (MediaException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
I even tried to print if the system is supporting audio capture and the result were true but I get NullPointException at this line :
recordOutput = new ByteArrayOutputStream();
although I tried to get the recordcontrol from the player it is still null :
recordControl = (RecordControl)audioPlayer.getControl("RecordControl");
I think I read that it'll always give NullPointerException unless you run it on a real device and not an emulator is that true ? can someone verify it ? and if so what can I do if I don't own a device currently any other way to use recordcontrol feature in emulator (assuming recordcontrol isn't working on emulators).
File size is 8MB (maybe play on your phone), try to this code
public void initMedia(final String aFileUrl) {
if (m_player == null) {
try {
m_player = Manager.createPlayer(aFileUrl);
m_player.addPlayerListener(this);
m_player.realize();
m_player.prefetch();
m_volumeControl = (VolumeControl) m_player.getControl("VolumeControl");
} catch (IOException ex) {
} catch (Exception ex) {
} catch (OutOfMemoryError e) {
}
}
}
In your code, i guess you miss "m_player.prefetch()", try this. And print your Exception message...
This code in general for file, resourcce, http...
public void initMedia(final String aProtocol, final String aMediaSource) {
if (m_player == null) {
try {
if (aMediaSource.indexOf("file://") == 0) {
InputStream iRecordStream = Connector.openInputStream(aMediaSource);
m_player = Manager.createPlayer(iRecordStream, "audio/amr");
} else {
m_player = Manager.createPlayer(aProtocol);
}
m_player.addPlayerListener(this);
m_player.realize();
boolean isPrefetch = true;
try {
m_player.prefetch();
} catch (Exception ex) {
isPrefetch = false;
}
// trick to pass prefetch error
if (!isPrefetch) {
if (m_player != null) {
m_player.close();
m_player = null;
}
if (aMediaSource.indexOf("file://") == 0) {
InputStream iRecordStream = Connector.openInputStream(aMediaSource);
m_player = Manager.createPlayer(iRecordStream, "audio/amr");
} else {
m_player = Manager.createPlayer(aProtocol);
}
m_player.addPlayerListener(this);
m_player.realize();
m_player.prefetch();
}
m_volumeControl = (VolumeControl) m_player.getControl("VolumeControl");
} catch (IOException ex) {
} catch (Exception ex) {
} catch (OutOfMemoryError e) {
}
}
}
In general when it comes to J2ME development, you should always test your app on multiple real devices.
Emulators can't be trusted.
Also, J2ME is very fragmented, and various devices have various bugs and behaves differently with the same code. This will affect any app on many areas. One area being audio playback.
For example, some devices requires that you use the realize() and prefetch() methods, while other devices will crash if you use prefetch(). The only possible solution (if you wish to support as many devices as possible) is to use multiple try/catch blocks.
See this link for a detailed explanation and other tips'n'tricks on audio playback with MIDP2.0
http://indiegamemusic.com/help.php?id=1

Java: EDT, SwingUtilities & GUILock

I am using an actionListener to trigger an sequence of events and ultimatley this code is called:
public class ScriptManager {
public static Class currentScript;
private Object ScriptInstance;
public int State = 0;
// 0 = Not Running
// 1 = Running
// 2 = Paused
private Thread thread = new Thread() {
public void run() {
try {
currentScript.getMethod("run").invoke(ScriptInstance);
} catch(Exception e) {
e.printStackTrace();
}
}
};
public void runScript() {
try {
ScriptInstance = currentScript.newInstance();
new Thread(thread).start();
State = 1;
MainFrame.onPause();
} catch (Exception e) {
e.printStackTrace();
}
}
public void pauseScript() {
try {
thread.wait();
System.out.println("paused");
State = 2;
MainFrame.onPause();
} catch (Exception e) {
e.printStackTrace();
}
}
public void resumeScript() {
try {
thread.notify();
System.out.println("resumed");
State = 1;
MainFrame.onResume();
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopScript() {
try {
thread.interrupt();
thread.join();
System.out.println("stopped");
State = 0;
MainFrame.onStop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The runnable is created and ran, however, the problem occurs when I try to use the any of the other methods, they lock my UI. (I'm assuming this is because im running this on the EDT) Does anyone know how to fix this?
That's not how you use wait and notify. They need to be executed on the thread that you are trying to pause and resume. Which means you need to send a message to the other thread somehow. There are various ways to do this, but the other thread needs to be listening for this message, or at least check for it occassionally.

Categories

Resources