My program loads a webpage and i do not want to let user load webpage (for example : if i load google.com i do not want let load yahoo.com) .
my program execute correctly but cpu usage is very high when run my program because of this part of my code:
wv.getEngine().locationProperty().addListener((observable, oldValue, newValue) -> {
if(!newValue.contains(oldValue)){
wv.getEngine().load(oldValue);
}
});
When i close my program i see its steel running in task manager
You're not closing your application.
class zzz extends Application{
public static void main (String[] args){
Launch(args);
}
public void start(Stage s){
// bla di bla
s.setOnCloseRequest((event) -> {// <----------- this is what you need
Platform.exit();
}
}
... you should restart your pc(or kill all the java processes you're starting), apply this fix to actually close your applications, and it will reduce your CPU load because you won't have stray runtimes
Related
I've been looking for ages for direction on this matter and I finally post here.
I have a JavaFX application with MediaPlayer. One day, seeking at a later position in video (that had not been accessed previously) started hanging the player. No status change before it gets to PLAYING, the buffer is loaded, status at READY before I call seek().
First I thought it is because I went out of Application thread, tried to put the MediaPlayer back on the root to be sure, and the seek method worked as before, fast enough for me.
But then for a reason I can't get, it started hanging again all the time, with same symptoms.
Now, even with the most simple code, it hangs too.
I'm desperate, the waiting time can be 30 seconds to reach a position 2 minutes later in the video. Looks like the Media Player is scanning again all video until it finds the good position it's seeking, thus taking more time for a later position. If the position has been accessed before though, seek() won't hang...
Am I the only one with this problem?
I'm on Mac os EL Capitan, but tried on Windows VM too and I get the same behaviour.
Here is a standalone code, but I don't see how it will help, I don't even hope for ppl to reproduce:
public class VideoPlayerExample extends Application {
public static void main(String[] args) throws Exception {
launch(args);
}
#Override
public void start(final Stage stage) throws Exception {
File file = new FileChooser().showOpenDialog(stage);
Media media = new Media(file.toURI().toString());
MediaPlayer mp = new MediaPlayer(media);
mp.statusProperty().addListener(new ChangeListener<MediaPlayer.Status>() {
#Override
public void changed(ObservableValue<? extends Status> observable, Status oldValue, Status newValue) {
System.out.println(newValue);
}
});
Group gp = new Group(new MediaView(mp));
Button buttonTest = new Button("It's gonna hang...");
buttonTest.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
mp.pause();
System.out.println(mp.getCurrentTime().toMillis());
mp.seek(new Duration(mp.getCurrentTime().toMillis() +10000));
mp.play();
}
});
gp.getChildren().add(buttonTest);
stage.setScene(new Scene(gp, 540, 208));
stage.show();
}
}
Any help will be so greatly appreciated!
You're right - I can't reproduce your problem. I have macOS Sierra 10.12.6. All I can say is check the type of movie you're trying to play - not all encodings are supported. Also, according to the documentation, if the movie's duration is Duration.INDEFINITE, seek() will have no effect.
Place the seek method in a new thread not on your JavaFX thread.
new Thread(() -> mp.seek(new Duration(mp.getCurrentTime().toMillis() +10000)))).start();
I have a desktop application that will be used on computers with no keyboard, input will be on a touch screen. I can get the virtual keyboard to show up on textfields fine when running from eclipse. I used these arguments
-Dcom.sun.javafx.touch=true
-Dcom.sun.javafx.isEmbedded=true
-Dcom.sun.javafx.virtualKeyboard=none
The following link shows me where to add the arguments.
how to add command line parameters when running java code in Eclipse?
When I make a runnable jar file the keyboard does not show up. I am looking for a way to set these arguments programmatically so that the runnable jar file will display the virtual keyboard on any computer. Any help will be greatly appreciated.
The only working solution I could find came from here
Gradle build for javafx application: Virtual Keyboard is not working due to missing System property
Create a wrapper class and set the system properties before invoking the applications original main method.
public class MainWrapper {
public static void main(String[] args) throws Exception
{ // application - package name
Class<?> app = Class.forName("application.Main");
Method main = app.getDeclaredMethod("main", String[].class);
System.setProperty("com.sun.javafx.isEmbedded", "true");
System.setProperty("com.sun.javafx.touch", "true");
System.setProperty("com.sun.javafx.virtualKeyboard", "javafx");
Object[] arguments = new Object[]{args};
main.invoke(null, arguments);
}
}
When making the runnable jar file just point to the MainWrapper class for the launch configuration.
The -D option to the JVM sets a system property. So you can achieve the same by doing the following:
public class MyApplication extends Application {
#Override
public void init() {
System.setProperty("com.sun.javafx.touch", "true");
System.setProperty("com.sun.javafx.isEmbedded", "true");
System.setProperty("com.sun.javafx.virtualKeyboard", "none");
}
#Override
public void start(Stage primaryStage) {
// ...
}
}
In my JavaFX application, I want to show an error dialog and exit the app whenever some unexpected exception occurs. So in my main-method I have set up a default uncaught exception handler before launching the app:
setDefaultUncaughtExceptionHandler((thread, cause) -> {
try {
cause.printStackTrace();
final Runnable showDialog = () -> {
// create dialog and show
};
if (Platform.isFxApplicationThread()) {
showDialog.run();
} else {
runAndWait(showDialog);
}
} catch (Throwable t) {
// ???
} finally {
System.exit(-1);
}
});
launch(MyApp.class);
Explanation: When the uncaught exception handler is executed on the JavaFX Application Thread (FXAT), I just run the code for showing the dialog. This of course doesn't work when the exception handler is not invoked by the FXAT. In this case, I have to push the code onto the FXAT. But I can't use Platform.runLater because then my app would exit before the dialog is shown. So, I made that custom method runAndWait which internally pushes the runnable via Platform.runLater, but waits until the execution of the runnable (with some countdown latch mechanism).
Now the problem with this: When an exception occurs in my start() method then my app gets stuck. Because it tries to wait until the execution of the dialog showing, but the FXAT never does this execution. I guess this is because when the start() method fails with an exception, the FXAT is just dead? I'm not sure whether this is a special case for the start() method or whether this will happen in any situation when an exception is thrown and not caught within code that is executed by the FXAT.
In Swing as I know the EDT is a complex architecture consisting of several threads. It wasn't the case that when some execution on the EDT failed that the entire Swing broke down. But here this is what seems to happen?
So what can I do here? How can I show to the user that the application cannot start?
Well....
I have a solution but I don't particularly recommend it. By default, Application.launch() will catch the exception thrown by the start method, exit the FX Platform, and then rethrow the exception. Since the FX Application Thread has shut down when your default uncaught exception handler executes, waiting for something to happen on the FX Application Thread just blocks indefinitely.
The exception to this is when the FX Application is running in web start. The way that the launcher checks for this is to check for the presence of a security manager. So a (really, really ugly) workaround is to install a security manager so that it looks like you are running in web start mode. This line will install a permissive security manager:
System.setSecurityManager(new SecurityManager(){
#Override
public void checkPermission(Permission perm) {}
});
Here's a SSCCE:
import java.lang.Thread.UncaughtExceptionHandler;
import java.security.Permission;
import java.util.concurrent.FutureTask;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
public class ShowDialogOnException {
public static final UncaughtExceptionHandler ALERT_EXCEPTION_HANDLER = (thread, cause) -> {
try {
cause.printStackTrace();
final Runnable showDialog = () -> {
Alert alert = new Alert(AlertType.ERROR);
alert.setContentText("An unknown error occurred");
alert.showAndWait();
};
if (Platform.isFxApplicationThread()) {
showDialog.run();
} else {
FutureTask<Void> showDialogTask = new FutureTask<Void>(showDialog, null);
Platform.runLater(showDialogTask);
showDialogTask.get();
}
} catch (Throwable t) {
t.printStackTrace();
} finally {
System.exit(-1);
}
};
public static void main(String[] args) {
System.setSecurityManager(new SecurityManager(){
#Override
public void checkPermission(Permission perm) {}
});
Thread.setDefaultUncaughtExceptionHandler(ALERT_EXCEPTION_HANDLER);
Application.launch(App.class, args);
}
}
and a test app:
import javafx.application.Application;
import javafx.stage.Stage;
public class App extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
throw new Exception("An exception");
}
#Override
public void stop() {
System.out.println("Stop");
}
}
As I said, this is really something of a big hack, and I don't really recommend this unless you have no other option.
I got some operations in my Controller class which could take some time. So I want to show a loading dialog while this operation is running.
I tried this:
Platform.runLater(new Runnable() {
#Override
public void run() {
loadingDialog.show();
}
});
Boolean opSuccess = myService.operate();
Platform.runLater(new Runnable() {
#Override
public void run() {
loadingDialog.hide();
}
});
if (opSuccess) {
// continue
}
Now, the Problem is, the loadingDialog is never show. The UI only blocks for some time and than continues on "//continue".
So it seems, the runLater call is blocked by the blocking operation (operate)?
I also tried CoundDownLatch, to wait for loadingDialog.show() to complete, before running myService.operate(). But the latch.await() method never completes.
So my question is, how my I show the loadingDialog until myService.operate() finished and returned true or false? Do I have to put the operate() call into another thread and run it async or is there an easier way?
Thanks for help.
Are you sure your entire code does not run in the JavaFX Thread?
Methods of your controller class usually do and I assume it due to your description.
However, better use the Task class. Here you'll find a tutorial and a short snippet for your application:
// here runs the JavaFX thread
// Boolean as generic parameter since you want to return it
Task<Boolean> task = new Task<Boolean>() {
#Override public Boolean call() {
// do your operation in here
return myService.operate();
}
};
task.setOnRunning((e) -> loadingDialog.show());
task.setOnSucceeded((e) -> {
loadingDialog.hide();
Boolean returnValue = task.get();
// process return value again in JavaFX thread
});
task.setOnFailed((e) -> {
// eventual error handling by catching exceptions from task.get()
});
new Thread(task).start();
I assumed Java 8 and the possibility to use Lambda expressions. Of course it is possible without them.
You are better off making use of concurrency mechanisms/Worker interfaces in JavaFx - Tasks and services instead of using Platform.runLater(). The tasks and services allow you to manage the long running tasks in a separate thread. They also provide callbacks to indicate the progress of the tasks.
You could explore further at http://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm
Also have a look at the Ensemble JavaFX samples for Tasks and Services - http://www.oracle.com/technetwork/java/javase/overview/javafx-samples-2158687.html
I am writing a JavaFX program under ecilpse, It works well on my local machine i.e., I can execute the runable jar after I export. However, when I put the executable jar to another machine, the UI was not responding. Here are the codes I launch the javaFX program.
#Override
public void start(Stage primaryStage) {
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent e) {
Platform.exit();
System.exit(0);
}
});
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Server Simulator");
context = new ClassPathXmlApplicationContext("classpath:PrTrSim.xml");
this.displayQueue = (LinkedBlockingQueue<Message>) context.getBean("displayQueue");
this.userInputQueue = (LinkedBlockingQueue<Message>) context.getBean("userInputQueue");
this.outgoingQueue = (LinkedBlockingQueue<Message>) context.getBean("outgoingQueue");
this.incomingQueue = (LinkedBlockingQueue<Message>) context.getBean("incomingQueue");
addQueue.add(this.displayQueue);
addQueue.add(this.outgoingQueue);
addQueue.add(this.incomingQueue);
initRootLayout();
showSimOverview();
}
public static void main(String[] args) {
launch(args);
}
The PrTrSim.xml is for initialization of two components(messageProcessor and SocketIO reader) which are running behind.The 4 blocking queues are for message receiving and handling.
To avoid blocking of the main thread you should use the JavaFX concept of tasks or services as explained in details here: http://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm