JavaFX Full Screen Exclusive Mode - java

I am making a JavaFX kiosk application that needs to take full control of the screen and disallow closing, minimising, and certain keypresses. I was wondering is there a way to make a JavaFX application run in full screen exclusive mode, if not are there any alternatives that could achieve the same goal. I have tried using:
stage.setFullScreen(true);
which does successfully make the application full screen, however the user can still exit the application or exit the full screen.

Handle close events.
following code may help!
// Set plat params
Platform.setImplicitExit(false);
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent event) {
// deque it
event.consume();
}
});

I had this same issue recently, hopefully you figured it out (I wouldn't wait 4 years for an answer).
If not:
Before you make a call to stage.show() you need to call setFullScreenExitKeyCombination and pass KeyCombination.NO_MATCH as the only parameter.
so for example...
stage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
stage.show()

This will prevent closing and de-fullscreening w/ESC (but still leave you with a backdoor-y way to remove fullscreen - Shift+PAUSE or F13):
scene.setOnKeyPressed((event) ->
{
if (event.getCode() == KeyCode.PAUSE && event.isShiftDown())
stage.setFullScreen(!stage.isFullScreen());
});
stage.setOnCloseRequest(Event::consume);
stage.setFullScreenExitKeyCombination(new KeyCodeCombination(KeyCode.F13));
In order to close your application you'd have to add a Platform.exit() on some command.

Related

UISpec4J and external application

I am trying to launch an external application for testing using UISpec4J.
Here are the questions and their answers I referred so far:
How to automate a swing java web start application which runs clicking a link into a web application, which is automated with Selenium WebDriver?
Getting all windows using UISpec4J
UISpec4J Capturing modal dialog, before the trigger finish
my.exe referred below is a Java application wrapped in exe using some tool. Internally it uses the jars and is Java GUI application.
This executable launches a splash screen first, then a dialog to choose where you want to connect to and after that main window is shown. Unless I can automate where I can connect to I won't get main window.
Based on these questions I have come up with following code fragments:
this.setAdapter(new UISpecAdapter() {
#Override
public Window getMainWindow() {
return WindowInterceptor.run(new Trigger() {
#Override
public void run() throws Exception {
// running jnlp by netx launcher
Runtime.getRuntime().exec("C:\\my.exe");
Thread.sleep(10000);
}
});
}
});
In the approach above I simple get "No window was shown" error.
this.setAdapter(new UISpecAdapter() {
#Override
public Window getMainWindow() {
final Window[] result = new Window[1];
WindowInterceptor
.init(new Trigger() {
#Override
public void run() throws Exception {
Runtime.getRuntime().exec("C:\\my.exe");
//Thread.sleep(10000);
}
})
//.processTransientWindow()
.process(new WindowHandler() {
public Trigger process(Window window) throws Exception {
result[0] = window;
return Trigger.DO_NOTHING;
}
})
.run();
return result[0];
}
});
In the second approach above, I still get "No window shown" error AND control never reaches to overriden "process" method.
I referred to http://www.uispec4j.org/reports/apidocs/org/uispec4j/interception/WindowInterceptor.html and recommended approach is to use init to capture modal dialog is init\process sequence.
To capture non-modal it is recommended that we should use following:
Window window = WindowInterceptor.run(panel.getButton("open").triggerClick());
But I have NO idea where and how I am supposed to call it..
From the first question I referred, mentioned above, we should be able to do that because the answer to it mentions launching jnlp application which is external application.
I tried with jre 6 update 0 and I can at least run test. In java update 37, from the third question I referred above, I get abstract method not implemented error.
What am I doing wrong? Any idea?
I am using latest UISpec4J package - version 2.4.
Thanks in advance,
-Neel.
I'm very new to UISpec4J but I'm guessing it needs to run in the same JVM in order to intercept and interact with the GUI components. When you start the exe file with exec, it will create a new process and a new, separate JVM. That'll not work, if I understand UISpec4J correctly.
Regarding the non-modal example, the documentation says "You would retrieve the window from within the test...", so in a setup method or in a test should work.

JavaFX: Stage close handler

I want to save a file before closing my JavaFX application.
This is how I'm setting up the handler in Main::start:
primaryStage.setOnCloseRequest(event -> {
System.out.println("Stage is closing");
// Save file
});
And the controller calling Stage::close when a button is pressed:
#FXML
public void exitApplication(ActionEvent event) {
((Stage)rootPane.getScene().getWindow()).close();
}
If I close the window clicking the red X on the window border (the normal way) then I get the output message "Stage is closing", which is the desired behavior.
However, when calling Controller::exitApplication the application closes without invoking the handler (there's no output).
How can I make the controller use the handler I've added to primaryStage?
If you have a look at the life-cycle of the Application class:
The JavaFX runtime does the following, in order, whenever an
application is launched:
Constructs an instance of the specified Application class
Calls the init() method
Calls the start(javafx.stage.Stage) method
Waits for the application to finish, which happens when either of the following occur:
the application calls Platform.exit()
the last window has been closed and the implicitExit attribute on Platform is true
Calls the stop() method
This means you can call Platform.exit() on your controller:
#FXML
public void exitApplication(ActionEvent event) {
Platform.exit();
}
as long as you override the stop() method on the main class to save the file.
#Override
public void stop(){
System.out.println("Stage is closing");
// Save file
}
As you can see, by using stop() you don't need to listen to close requests to save the file anymore (though you can do it if you want to prevent window closing).
Suppose you want to ask the user if he want to exit the application without saving the work. If the user choose no, you cannot avoid the application to close within the stop method. In this case you should add an EventFilter to your window for an WINDOW_CLOSE_REQUEST event.
In your start method add this code to detect the event:
(Note that calling Platform.exit(); doesn't fire the WindowEvent.WINDOW_CLOSE_REQUEST event, see below to know how to fire the event manually from a custom button)
// *** Only for Java >= 8 ****
// ==== This code detects when an user want to close the application either with
// ==== the default OS close button or with a custom close button ====
primaryStage.getScene().getWindow().addEventFilter(WindowEvent.WINDOW_CLOSE_REQUEST, this::closeWindowEvent);
Then add your custom logic. In my example i use an Alert popup to ask the user if he/she want to close the application without saving.
private void closeWindowEvent(WindowEvent event) {
System.out.println("Window close request ...");
if(storageModel.dataSetChanged()) { // if the dataset has changed, alert the user with a popup
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.getButtonTypes().remove(ButtonType.OK);
alert.getButtonTypes().add(ButtonType.CANCEL);
alert.getButtonTypes().add(ButtonType.YES);
alert.setTitle("Quit application");
alert.setContentText(String.format("Close without saving?"));
alert.initOwner(primaryStage.getOwner());
Optional<ButtonType> res = alert.showAndWait();
if(res.isPresent()) {
if(res.get().equals(ButtonType.CANCEL))
event.consume();
}
}
}
The event.consume() method prevents the application from closing. Obviously you should add at least a button that permit the user to close the application to avoid the force close application by the user, that in some cases can corrupt data.
Lastly, if you have to fire the event from a custom close button, you can use this :
Window window = Main.getPrimaryStage() // Get the primary stage from your Application class
.getScene()
.getWindow();
window.fireEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSE_REQUEST));
Ahh this is a known bug in JavaFX where the Stage will not close if a modal dialog is present at the time of closing. I will link you to the bug report which I just saw today. I think it is fixed in the latest release.
Here you go:
https://bugs.openjdk.java.net/browse/JDK-8093147?jql=text%20~%20%22javafx%20re-entrant%22
resolved in 8.4 it says. I think this what you are describing.
public Stage getParentStage() {
return (Stage) getFxmlNode().getScene().getWindow();
}
btnCancel.setOnAction(e -> {
getParentStage().close();
});

How to terminate a scheduled thread when JavaFX Runtime exits?

I'm looking over similar examples to this problem. We have a JavaFX app which runs some GUI updates via thread running from: ScheduledExecutorService::scheduleAtFixedRate.
This is similar to a couple of other questions. The two I recognised as most like my situation are these:
JavaFX Task threads not terminating
how to stop "JavaFX Application Thread"
The question I need to resolve, however, is about the next step. My target is for an embedded application and there's no opportunity to manually kill the JVM-task, or the other easy answers, etc. I'm afraid a reboot is reserved for something critically-serious.
We need to ensure that all threads are closed off in an orderly way. What I'm looking for is some kind of call back or event that lets me register a clean-up routine to close-down my stuff?
I was thinking that there ought to be 'something' in the base class, JavaFX javafx.application.Application to do the deed.
http://docs.oracle.com/javafx/2/api/javafx/application/Application.html
Is the Stop method something I might use or can I register to be called when there is a stop from my FXMLController?
At present when I run my JavaFX app from Netbeans, the JVM process persists. This stops any further build scripts and locks the JAR file. Netbeans gives you an option to kill the task. The true solution means that the application/JVM closes-down orderly and neatly.
(update) ... I looked into the javafx.Application class that you use to launch the JavaFX app. I implemented a Stop() method. Here I make sure that I've called Platform.exit() ...
/////
// #see
// -- http://docs.oracle.com/javafx/2/api/javafx/application/Application.html#stop%28%29
//
public void stop()
{
Platform.exit();
}
This doesn't cure the problem when running from NetBeans. Sometimes you need to click the stop [X] button two times, but the process does stop when you use the kill button. If you are interested in progress this is reported as bug: [Bug 245284], there's a small clock example to demonstrate the problem. When you close the window, the NetBeans process running panel is still 'running'. You can't build because the JAR file is locked. At least we know to manually kill the development program.
Suggestions welcome . . .
I have a partial solution to cover fellow developers who get caught in this situation. Declare a stop() method in in your JavaFX app (called "MainApp" by the Netbeans Maven JavaFX template). There are questions of course, but first the method.
See: JavaFX Application
Stop is called at the end of your program. I had the call to call Platform.exit() to close-down JavaFX runtime. I've added a call to shutdown other active Executor threads, which I kept in an list for now, to test the solution.
public class MainApp extends Application
{
#Override
public void start(Stage stage) throws Exception
{
.....
}
/**
* Close down the application
* #see
* -- http://docs.oracle.com/javafx/2/api/javafx/application/Application.html#stop%28%29
**/
#Override
public void stop()
{
Platform.exit();
for( ScheduledExecutorService sched : activeExecutorServices )
{
sched.shutdown();
}
}
}//MainAppl class
So by commenting-out the call to shutdown and running my JavaFX program, the application finishes but won't exit, and Netbeans show a running task. You need to manually click on the kill-button in Netbeans.
Uncomment the shutdown() call. When the JavaFX application exits, it also dissappears from the Netbeans running jobs. That appears to be a resolotion.
The remaining questions:
What is the correct order between Platform.exit() and shutdown()?
With more than one ScheduledExecutorService does it matter which order is used to shut them-off? LIFO or FIFO?
Is there a better way?
Ought Netbeans be able to detect the 'process overrun' and report this as a problem. That at least leave you and I with the option to ignore it or fix the program.
Hopefyully that will assist the next someone who faces a similar problem :-)
you can use setOnCloseRequest
#Override
public void start(Stage primaryStage) {
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent event) {
ThreadPool.shutdown();
}
});
initGui(primaryStage);
initData();
}

I want to run the application in background of mobile without any GUI in mobile using J2ME?

I am developing the network application in which I want to run my J2ME MIDP application in background without any GUI so that is any way to construct the application is such manner.
try this
set your current Display to null. so there will not be any form or alert running on the screen. But however your code will be running in the background.
Display display = Display.getDisplay(this); // here 'this' points to Midlet
display.setCurrent(null);
it easy just have a code of line on any event for example in the click of button
Display.getDisplay (this).setCurrent (null);
and return back the control via
Display.getDisplay (this).setCurrent (mycanvas);
Yes this code works Good,
display = Display.getDisplay(this);
public void startApp()
{
display.setCurrent(form);
}
public void pauseApp()
{
}
public void hide()
{
Display.getDisplay (this).setCurrent (null);
}
This is will work like, make a button can after clicking it call hide Function, or you call this hide function in constructor so it will hide itself when app start, can you keep unHide statement in appStart() so if you Tab the program then it will unHide app again.
NOTE: you said you are working on Network app, but some mobile will turn off the Internet Connection, when the Mobile screen Turn Off. please check this. and If you found any solution It will be Good to share here.

Rendering Problem with Swing App and Modal Dialogs

I have a Java/Swing desktop application (Java 6u16 on Windows XP) which occasionally appears to the users to hang. I say appears to because in reality what is happening is that the application is showing a modal dialog but this dialog is not being rendered. If the user uses Alt-Tab to switch away from the application and then subsequently returns to it, the dialog gets rendered correctly. Additionally, if a remote user connects to the session via NetOp (a VNC/Remote Desktop workalike) this also causes the GUI to be redrawn correctly.
The app runs via JavaWebstart. Since I've heard of rendering issues being caused by DirectDraw, I added the following to the JNLP
<property name="sun.java2d.noddraw" value="true"/>
but the problem still occurs (If I have understood correctly, this will switch off DirectDraw and Direct3d completely: see http://download.oracle.com/javase/1.5.0/docs/guide/2d/flags.html#noddraw)
I'm out of ideas on this one, any suggestions would be greatly appreciated.
Thanks,
Phil
Edit...
I have an abstract dialog class which extends JDialog and which all other dialogs extend. It contains the following method:
public void showDialog() {
initKeyBindings();
Application.getApplication().deactivateScannerListener();
setVisible(true);
}
Whenever I want to display a dialog, I call showDialog(). The initKeyBindings method sets up an ActionMap while the second line is application specific (Application is a singleton, I'm disabling the JPOS scanner listener while the dialog is displaying).
There is a corresponding hideDialog() method as follows:
public void hideDialog() {
setVisible(false);
Application.getApplication().activateScannerListener();
dispose();
}
Thanks,
Phil
Edit...
Sorry about this, one more edit: all of the dialogs have a parent. The AbstractDialog class will default to the main application frame if no other parent is specified.
FYI
For anyone following this, I've added the following to my code:
if (SwingUtilities.isEventDispatchThread()) {
initialiseAndShowDialog();
} else {
SwingUtilities.invokeAndWait(new Runnable() {
#Override
public void run() {
initialiseAndShowDialog();
}
});
}
This ensures that the dialog is only opened from the EDT.
Which thread are you calling showDialog() from? Swing components should be accessed on the Event Dispatch Thread only.
You could try SwingUtilities.invokeAndWait()
and the Runnable argument passed to it should call showDialog().
Let us know if it fixed the problem.

Categories