Fullscreen java app minimizes when screensaver turns on - java

I have an app that sets a fullscreen frame but seems to minimize when the screensaver turns on. I want this app to be the only application that the users of the touchscreen kiosks can use so this is a problem. Is there anyway to prevent this?

The internet says that the cross-platform way to achieve this is to schedule keyboard events with this code:
import java.awt.Robot;
public void disableScreenSaver() throws AWTException {
Robot r = new Robot();
r.waitForIdle();
r.keyPress(KeyEvent.VK_CONTROL);
r.keyRelease(KeyEvent.VK_CONTROL);
}
and to schedule it to run every couple of minutes (e.g. with thread.sleep();). This way the screen-saver will not show up.
I have no idea, though, about a non-hackish, cross-platform solution, and I would be very happy to see one from someone who knows it :)

Another way is to add a window listener and reset state when it's deactivated:
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowDeactivated(WindowEvent e) {
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
// or go to fullscreen mode here
}
});
But disabling screensaver might be the best thing to start with.

Probably (haven't tried it !) you'll get your answer by combining the answers to these questions:
Calling Win32 API method from Java
Need to disable the screen saver / screen locking in Windows C#/.Net
Of course this works only in Windows that's why I asked you about your OS :)

Related

Not able to delay between displaying icons

When the actionPerformed method is invoked I would like it to display the desired icon on the first button, delay for 1 second and then display the icon on the second button. The icons always display simultaneously? Not sure how to correct this.
#Override public void actionPerformed(ActionEvent e)
{
btnTest1.setIcon(img2);
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
btnTest2.setIcon(img2);
}
I'm assuming this is for JavaFX / Java Swing. I'm not too familiar with it, but I believe the threads aren't working is because there are concurrency rules related to using threads in swing apps. I've had similar issues and wrote a question about how to delay something using threads. I found sources for using a timer object. It might be better to implement the timer by doing:
import javax.swing.Timer;
I'm sure other more advanced users may give more detail. This is maybe another option. Oracle might help too:
https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html
The buttons' icons are set with setIcon, but that doesn't mean they are painted immediately. Both icons will only be painted after you return from your actionPerformed method. What you need to do is set the icon for the first button, then use Timer (see zOrigin_'s answer) and after the timer elapses, set the second button's icon.

How can you keep a JPanel from closing on System.exit(0)

I have a program that I am terminating with the System.exit(0); command.
When this happens the JPanel closes. I would like it to rename open so I can view the state at termination. Is there a way of keeping the Jpanel open or is there a better command than System.exit()?
not sure why a down vote I asked a simple question and someone answered it. I can't do it that way so try something else. Going to use a true false to test where to enter the simulation loop.
regarding:
Is there a way of keeping the Jpanel open or is there a better command than System.exit()?
The best solution: Don't call System.exit(...). Why? Because System.exit(0) closes the JVM, and so all Java processes running on that JVM will shut down when System.exit(0) is called.
As for "better command", that all depends on your need. If you just want to close a window such as a JDialog, then call myWindow.setVisible(false);. If you want to close it and release resources, then myWindow.dispose();.
Note: I suspect that you might have multiple windows open, perhaps multiple JFrames. If so, I strongly urge you to read: The Use of Multiple JFrames, Good/Bad Practice?
You also posted in comments:
I would like to keep the Jpanel open, but stop the simulation from running. I need to stop the Sim when certain conditions are met. so I wrote a stop()
So your question is in fact an XY Problem where you ask how to solve a specific code problem (keep a JPanel open after calling System.exit(0)) when the best solution is to use a completely different approach. Better that you tell us the overall problem that you're trying to solve rather than how you're currently trying to solve it, because System.exit isn't going to be part of the best solution.
Likely the best solution is to well separate your simulation model from its view (the GUI), to be able to give the model functionality that allows it to stop without closing down the JVM -- impossible for me to say how given our current level of knowledge about your problem -- and then reflect the stopping of the model in the view, again without shutting down the system.
The key to all of this will lie in the details of your current program, including the logic that underpins your simulation, and if you need more specific and likely more helpful answers, you're again going to want to improve your question, providing us with much more specific information about your code, your problem and with posting of pertinent code, preferably as a minimal example program.
Have you tried an approach similar to:
Do something when the close button is clicked on a JFrame
Basically, you're grabbing the Window closing event by setting a listener on the frame
You can then .dispose() the appropriate jpanel/frame if you want
JFrame is window and JPanel is a container. The moment the JPanel instance loses its reference, it will be garbage collected
How can JPanel be disposed after the panel has been removed from the JFrame
Disposing JFrame by clicking from an inner JPanel
import javax.swing.JOptionPane;
/*Some piece of code*/
frame.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
//delete this code if you want and replace with .dispose() or anything
if (JOptionPane.showConfirmDialog(frame,
"Are you sure to close this window?", "Really Closing?",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION){
//choose to close JVM here if you want
System.exit(0);
}
}
});
Here's a way, by overriding the SecurityManager for the JVM:
//set your security manager
static{
SecurityManager s = new DontCloseOnExitSecurityManager();
System.setSecurityManager(s);
}
static class DontCloseOnExitSecurityManager extends SecurityManager{
public void checkExit(int code){
//here you can put a check to see if you really do want to close - like if the JFrame is still open.
if(/*do some check*/ 13 == code)
super.checkExit(code);
throw new SecurityException("13 is unlucky, you shouldn't system exit on it.");
}
}
}
You'll need to find an appropriate place to put it in, and also how to do your checks (in checkExit).
Apologies for inaccuracies, I'm not in front of an IDE to test this right now.

Java Fullscreen mode not working on Ubuntu

So I'm using Ubuntu and when I want to enter fullscreen mode in Java, a normal window appears with max screen size, instead of a fullscreen window without title bar etc. I admit, I'm not even sure what the fullscreen mode should look like in Java, because I have not tried it on any other OS. But I assume it should be a screen without title bar.
Anyone else who has this problem?
This is the code I use. ; pretty straight forward.
public static void main(String[] args) {
GraphicsEnvironment env = GraphicsEnvironment
.getLocalGraphicsEnvironment();
GraphicsDevice vc = env.getDefaultScreenDevice();
JFrame window = new JFrame();
window.setUndecorated(false);
window.setResizable(false);
vc.setFullScreenWindow(window);
}
On Ubuntu (probably other Linux distros as well) it doesn't work. Full screen mode in Java doesn't cover the full screen. It leaves the toolbars out. Always, whatever you do.
I tried the two examples above and the examples from the official FSEM tutorial and some application I know are using Java/Swing and Full screen mode (FreeCol and TripleX) and noone was able to cover the task/toolbar areas of the screen.
My configuration is Ubuntu 12.10 with either OpenJDK or SUN-JRE 1.7.0_09 and either Unity or Gnome. Interestingly the java call to isFullScreenSupported() returns true. So, while the Java JRE says it supports full screen exclusive, it doesn't.
Some possible explanations might be given in another question.
On win7, with this code (I set the undecorated flag to true as suggested by #Gilberto and added a RED panel) it seems to work OK. If it does not work on Ubuntu, then it may mean that FullScreen mode is unsupported:
import java.awt.Color;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice vc = env.getDefaultScreenDevice();
JFrame window = new JFrame();
JPanel comp = new JPanel();
comp.setBackground(Color.RED);
window.add(comp);
window.setUndecorated(true);
window.setResizable(false);
vc.setFullScreenWindow(window);
}
}
This thread is very old but still comes in ACTUAL search results but with wrong answers. So i'll post actual the real solution.
Swing full screen will be set with the setExtendedState() function, not with the setFullScreenWindow() function!
JFrame myFrame = new JFrame();
....
myFrame.setExtendedState(MAXIMIZED_BOTH);
Then u'll have a decorated full screen window, with all buttons and a correct toolbar optic and it works fine with Ubuntu and any other OS.
Though this might in most cases not be applicable I'd like to share my solution to this problem.
In my case, I frequently need to develop Java/Scala apps for our university institution (psychological tests). To circumpass this issue we decided to install sawfish on our experimental pc's.
If this solution is applicable to your needs you can install (an extremely outdated) sawfish through Ubuntu facilities (Software Center, Aptitute, apt-get) or - what I'd prefer - install or compile an up-to-date sawfish manually.
Other window and/or desktop managers might give similar functionality, but we experienced artifacts when we tried XFCE or LXDE with disabled/deleted panels.

set JFrame Orientation from right to left!

To align my JFrame from righ-to-left, I use:
setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
but this works only if I use the following style (decoration) of the JFrame:
public class RightToLeft {
public static void main(String []args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run() {
try { UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); }
catch (Exception e) { e.printStackTrace(); }
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("العنوان بالعربي");
frame.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
frame.setSize(300,300);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
but I want it to work without this decoration. How to solve this issue?
EDIT:
#mre I want a JFrame like this one:
EDIT2:
I really really need this issue to be fixed, so I offer 500+ to who will give a JFrame like this (with WindowsLookAndFeel):
The following explains what you observe through your code snippet:
ComponentOrientation is applicable only to Swing (and AWT actually) components.
When using JFrame.setDefaultLookAndFeelDecorated(true);, then the whole frame decoration is performed by Swing (the LookAndFeel itself in fact), so this works as expected.
If you don't set this option though, that means that the OS is in charge of the frame decoration, however the OS cannot be aware of the ComponentOrientation used by your Swing components!
I expect the OS (did you mention what OS you use exactly? It seems to be Windows 7 right?) to perform the correct decoration based on the currently selected Locale. Hence if you have an Arabic locale setup and selected on your OS, I guess all windows decorations are right to left. Did you try changing that Locale (through the "Region and Language" control panel)? Did it work?
Note: I don't think that you can change these OS settings directly from Java, but you can read them with Locale.getDefault().
To sum up:
first of all, you have to ensure that your OS is properly configured in terms of text orientation; sorry I can't help much here because I don't have any right-to-left languages installed on my Windows machine.
then, use the system look and feel and ensure that JFrame.setDefaultLookAndFeelDecorated(false);
if that doesn't work, then you may consider posting your code snippet, along with your system configuration to Oracle Java bugs list
What follows are extra notes on how to improve this part of your code (but this is not a fix for your issue)
By the way, if you let the user define its OS language preferences, then you shouldn't explicitly hard-code frame.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); but rather use something like:
frame.applyComponentOrientation(
ComponentOrientation.getOrientation(Locale.getDefault()));
Where Locale.getDefault(), unless explicitly changed within your application, will return the OS-level currently selected Locale.
Also note that it is preferable to use applyComponentOrientation() rather than setComponentOrientation(), because the former recursively sets the given orientation to the whole hierarchy of components.
Finally, you will have to ensure in your windows that the LayoutManager used is right-to-left aware; this is normally OK with all standard Swing layouts, but not for all 3rd-party layout managers, if you use some.
#Eng.Fouad
just joke and this one ???...
code:
import java.awt.ComponentOrientation;
import javax.swing.JFrame;
import javax.swing.UIManager;
import org.pushingpixels.substance.api.skin.SubstanceOfficeSilver2007LookAndFeel;
public class RightToLeft {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
//UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
UIManager.setLookAndFeel(new SubstanceOfficeSilver2007LookAndFeel());
} catch (Exception e) {
e.printStackTrace();
}
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("العنوان بالعربي");
frame.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
});
}
private RightToLeft() {
}
}
I suspect it has to do more with the OS. Normally (if you don't call setDefaultLookAndFeelDecorated) it is the OS that provides the frame decoration, not the LAF.
You should try changing your preferences in the OS to say you want right to left orientation.
Sorry, I don't know where those settings would be.
Once you do this, then you should be able to remove the call to setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
as the LAF will pick up the OS settings from the Locale.
EDIT
This Link describes how to enable right-to-left text on Windows 7. Then I think you would also need to change your locale.
It looks like the Component Orientation feature is not supported with the Windows LookAndFeel (at least not for the title bar)
Here is one posibility. This utility is designed for Mac users who have switched to Windows and want the window buttons on the left, but it should serve the same needs as yours.
This solution has nothing to do with Java (so I don't know if it's even acceptable for your needs) and sounds like it would be external to your application. I have not been able to try it out myself (I'm not running Windows), so I can't vouch for it, but it might be worth a try.
You only need to add this line of code and I am sure it works 100%.
frame.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);

Swing app global modal

Simple question:
Can a swing frame be completely modal ( block all others windows ) ?
I tried the following, but I can still click on other apps windows ( like this browser )
JDialog myDialog = ....
myDialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
Plase paste some code if this is possible.
Dialogs are not meant to be globally modal. Every modern OS strongly discourages global modality in its HIG, and they may even have deprecated the functionality (as indicated by the fact that you can't get it to work). Your app should never steal events from the entire system; that's not only bad design, it's near-criminal in my book.
Ignoring the fact that most people like to multi-task between several apps, what about the scenario where you open a globally modal dialog and then your application freezes? Ctrl+Alt+Del should work on Windows to kill the app, but I'm not sure about Cmd+Opt+Escape on Mac with a globally modal dialog (does Cocoa even have global modality?). None of the Linux platforms have any nice way of killing apps which have taken over complete control of the UI as you are suggesting (you would have to kill X11 completely and start a new instance from scratch).
My answer: find another way. I don't care what your client is asking for, they don't want this.
JFrame is not designed to be modal. Use JDialog for it, but you will loose some JFrame functionality doing so.
If you can't live with the loss, you have to block the EventQueue and replace it with your own to only accept events from the blocking one.
See Creating Modal Internal Frames for an explanation using internal frames that should be applicable to JFrame also.
Edit:
Oups, my answer seems a bit off, since your code example shows you are already using a Dialog subclass for this.
I don't know about global modal, but here's an idea.
Take the screenshot of the desktop.
Go full screen.
Pop up your dialog.
Since the desktop is fake screenshot, you can ignore any attempt to click into it.
Full screen sample:
private void toggleFullScreenWindow() {
GraphicsEnvironment graphicsEnvironment
= GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice graphicsDevice
= graphicsEnvironment.getDefaultScreenDevice();
if(graphicsDevice.getFullScreenWindow()==null) {
dialog.dispose(); //destroy the native resources
dialog.setUndecorated(true);
dialog.setVisible(true); //rebuilding the native resources
graphicsDevice.setFullScreenWindow(dialog);
}else{
graphicsDevice.setFullScreenWindow(null);
dialog.dispose();
dialog.setUndecorated(false);
dialog.setVisible(true);
dialog.repaint();
}
requestFocusInWindow();
}
FYI: Full-Screen Exclusive Mode API.

Categories