JavaFX: can you create a stage that doesn't show on the task bar and is undecorated? - javafx-8

I'm trying to create a stage that doesn't appear on the Windows task bar and is undecorated (no borders and no close/minimize/maximize buttons). My end goal is to create a tray icon application that will pop up notification windows.
It's similar to this question where I want the behavior of both StageStyle.UTILITY (which prevents the stage from showing on the task bar) and StageStyle.TRANSPARENT (which is a completely undecorated window).
The referenced question doesn't work for me because I don't have a parent stage from which to make a modal window. Any ideas on how to get this to work? Thanks

I was able to workaround this issue with the following code:
Stage stage = new Stage();
stage.initStyle(StageStyle.UTILITY);
stage.setMaxHeight(0);
stage.setMaxWidth(0);
stage.setX(Double.MAX_VALUE);
StageStyle.UTILITY will avoid creating a taskbar icon. I set the width and height to 0 make the window small and then use stage.setX(Double.MAX_VALUE) to place it far off screen so it doesn't show up. It's a bit hokey, but it seems to work fine.

JavaFX doesn't support the feature you request
You cannot do what you are asking (not show a task bar icon for an undecorated or transparent stage) using just the core Java 8 classes.
If you wish, file a feature request for this in the JavaFX issue tracker.
You could write some native JNI code and perhaps tell Windows not to display a task bar icon for your application. I do not know how you would do this.
Suggestion on task bar icons
I think it is fairly standard windowing toolkit behaviour to show the main application window in the task bar when the main application window is not hidden, so I suggest not trying to circumvent that standard behaviour.
Suggestion on notifications and tray icons
This isn't directly related to your question title, but is just comment on the end goal of your task - notifications for tray icons.
Most tray based applications I have seen don't have a task bar icon when the window associated with the tray icon is hidden, but do have a task bar icon when the window associated with the tray icon is displayed - so I suggest you stick with that setup.
Also, notifications are a standard part of the system tray icon infrastructure itself, so I suggest you use the standard mechanisms for system tray icon notifications, rather than using your own. This will also allow the user to configure whether the tray icon and it's notifications are shown using the standard OS tray icon and notification management UIs.
I created a sample application which uses the AWT SystemTray API to provide a System tray for a JavaFX application which uses some of the suggestions from this section. You can try it out if you like.
Full system tray support will come to JavaFX (probably with Java 9) when RT-17503 Provide system tray support is implemented.

This question is not really fresh, but I had the same problem and found no solution at first, but here is my workaround :)
The best solution I found was to set the primaryStage to style Utility and to make all childStages to Style Undecorated. Then set the opacity of the primaryStage to 0.0 so its not visible:
PrimaryStage:
primaryStage.initStyle(StageStyle.UTILITY);
primaryStage.setOpacity(0);
primaryStage.show();
Childs:
this.initOwner(owner);
this.initStyle(StageStyle.UNDECORATED);
Example code
public void start(Stage primaryStage) throws IOException{
//make primaryStage utility
primaryStage.initStyle(StageStyle.UTILITY);
primaryStage.setOpacity(0);
Stage secondaryStage = new Stage();
secondaryStage.initOwner(primaryStage);
//make secondaryStage transparent
secondaryStage.initStyle(StageStyle.TRANSPARENT);
//load ui via FXMLLoader
FXMLLoader loader = new FXMLLoader(getClass().getResource("/ui.fxml"));
AnchorPane pane = loader.load();//example with anchor pane
Scene scene = new Scene(pane,400,400); //example width and height
scene.setFill(Color.TRANSPARENT); //make scene transparent as well
secondaryStage.setScene(scene);
primaryStage.show();
secondaryStage.show();
}

Inspired by #Loki solution with a little upgrade (in my opinion)
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class TransparentAndUtilityStageApp extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.initStyle(StageStyle.UTILITY);
primaryStage.setOpacity(0.);
primaryStage.show();
Stage stage = new Stage();
Label label = new Label("Rainmeter");
StackPane stackPane = new StackPane(label);
stackPane.setPrefSize(600, 400);
stackPane.setStyle("-fx-background-color: transparent;");
Scene scene = new Scene(stackPane);
scene.setFill(null);
stage.initOwner(primaryStage);
stage.initStyle(StageStyle.TRANSPARENT);
stage.setScene(scene);
stage.show();
}
}

JavaFX DOES support that.
Don't put the main() method in your Application class. Just create another class to be your main class:
public class FxApplication extends Application {
}
public class Main {
public static void main(String[] args) {
PlatformImpl.setTaskbarApplication(false);
Application.launch(FxApplication.class, args);
}
}

As far as I know, JavaFX and Swing are interoperable and swing supports this feature. So if you can use Swing, integrate something like this into your application:
class MyFrame extends JFrame {
// ...
MyFrame() {
setUndecorated(true);
setType(Type.UTILITY);
}
// ...
}
I haven't tried this but other SO questions like this will probably help you on how to use Swing in JavaFX.

Related

How to add Perspective Bar Switcher to pure eclipse 4 rcp application

I have created a pure Eclipse e4 rich client platform application application model. I created multiple perspectives using perspective stack, but I am unable to switch other perspective because there is no default perspective bar or switcher icon present in Eclipse e4. How to implement a perspective switcher in pure Eclipse e4?
EPartService.switchPerspective will do the actual switch, but you will have to design and implement the UI.
You could use a ToolBar in the window Trim Bar with buttons for each perspective. Alternatively a Combo as a Tool Control with a list of the perspectives, it is up to you.
To put a control at the right of a Trim Bar you need to add two Tool Control objects to the trim. Something like:
The first Tool Control is just a spacer to fill the center of the bar.
On the tags tab for the control add the word stretch to tell e4 to stretch this control over as much space as possible:
You will also have to specify a class for the control. This just needs to create an empty Composite to occupy the space. For example:
public class SpacerControl
{
#PostConstruct
public void postConstruct(final Composite parent)
{
Composite body = new Composite(parent, SWT.NONE);
body.setLayout(new FillLayout());
}
}
The second Tool Control will contain your Combo control for the perspective switch. Something like:
public class ComboControl
{
#PostConstruct
public void createGui(final Composite parent)
{
Combo combo = new Combo(parent, SWT.READ_ONLY);
... initialize Combo, add listeners, ....
}
}
This should end up looking something like this:

JavaFX popup hidden when stage is in fullscreen mode

I am trying to popup a dialog over my fullscreen primary stage in javafx. When I create my popup, it is unexpectedly hidden behind my fullscreen primary stage until the stage is removed from fullscreen mode (via ESC). If I make my primary stage maximized and undecorated instead of fullscreen, then my popup will appear on top of the primary stage as expected.
Am I missing something about how fullscreen mode is different than maximized and undecorated mode? Am I using fullscreen mode improperly?
I am using java version 1.8.0_20 on CentOS 6.5 with Gnome.
Here is my SSCCE:
import javafx.application.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.stage.*;
public class TestApplication extends Application {
private Stage primaryStage;
public static void main(String[] arguments) {
launch(arguments);
}
public void start(Stage stage) {
this.primaryStage = stage;
// Create a fullscreen primary stage.
primaryStage.setTitle("Main Stage");
primaryStage.setScene(new Scene(createRoot()));
primaryStage.setFullScreen(true);
primaryStage.show();
}
private Parent createRoot() {
Button button = new Button("Show popup");
button.setOnAction((event) -> showPopup());
return button;
}
private void showPopup() {
// Create a popup that should be on top of the primary stage.
Stage popupStage = new Stage();
popupStage.setScene(new Scene(createPopupRoot()));
popupStage.setTitle("Popup Stage");
popupStage.initModality(Modality.WINDOW_MODAL);
popupStage.initOwner(primaryStage);
popupStage.show();
}
private Parent createPopupRoot() {
return new Label("This is a popup!");
}
}
After repeating this problem with java version '1.8.0_40', I finally found how to fix this problem!
popupStage.initStyle(StageStyle.UTILITY);
Stage.initStyle(StageStyle) -- JavaFX 8
Giving the popup a style of StageStyle.UTILITY seems to keep the popup in front of the fullscreen window even when clicking outside of the popup.
I saw this same issue when using the new Alert class in java 1.8.0_40, and setting the style to StageStyle.UTILITY fixed that as well (Dialog.initStyle(StageStyle) -- JavaFX 8).
I don't know why this works.
Side Note:
It looks like removing the call to popupStage.initOwner(...) allows the popup to appear above the full screen application, but clicking outside of the popup causes the popup to disappear.
Assuming you're on a Mac, this is a known issue, which is fixed in 8u40. You may need to use the ea version until the full release.
The basic history of this bug is that JavaFX implemented its own full screen implementation, in order to support OS X versions prior to 10.7 (which didn't have a native full-screen mode). That implementation uses an "exclusive mode", which prevents other windows from showing. This can get pretty bad: for example ComboBoxs won't work... The issue is fixed in 8u40 by using the native mode (since OS X versions prior to 10.7 are no longer supported anyway).
Note that if you don't programmatically set full screen mode, and allow the user to go to full screen using the Mac OS button on the window title bar, then the issue should not arise.

CrossUI.Droid.Dialog EntryElement loses focus with text prediction

I'm creating a new Dialog view in Droid platform, using the CrossUI.Droid.Dialog project. I'm also using bindings provided by the MvvmCross Framework.
Here is the code I have in the Droid view, to create and bind the Dialog:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
DroidResources.Initialise(typeof(Resource.Layout));
Root = new RootElement()
{
new Section("Private Configuration")
{
new EntryElement("Name:").Bind(this, "{'Value':{'Path':'Configuration.Name'}}"),
new EntryElement("Description:").Bind(this, "{'Value':{'Path':'Configuration.PrivateDescription'}}"),
new BooleanElement("Active?").Bind(this, "{'Value':{'Path':'Configuration.Active'}}")
},
new Section("Display Configuration")
{
new StringElement("Header Title")
{
Click = (o, e) => GoToHeaderTitleActivity(),
LayoutName = "dialog_rootNavigate"
}
}
};
}
When I run the app, the dialog is shown and the bindings are correct.
The problem I have is when I try to write something in one of the EntryElement, the focus just goes somewhere else... This only happens when I have 'Text Prediction' enabled.
I've checked the sample in Android.Dialog and all seems to work just fine.
I'm using a Galaxy Tab 2 7.0, with ICS 4.0
Does anyone had this problem?
Found the answer!!
Apparently there is a known issue in Android where EditText controls and ListView don't play nice. This is not a problem with MvvmCross or Monodroid.Dialog.
To overcome this (and I'm guessing this is the reason for it's existence?) use the MvxLinearDialogActivity when developing forms using dialog. The issue instantly disappears.
As the comment in the class says:
DialogActivity based on a linear view, this will solve all edittext related focus problems when using elements
suggestions at Focusable EditText inside ListView doesn't help for example

Eclipse: Converting actions in commands for a specific view

My original RCP was started in 3.x and currently I am running it on Juno with the compatibility layer. I was looking into doing a soft migration so I have started to slowly change my practices. One of the things I am doing is to change my actions into commands.
I have a view (which is like a directory explorer) currently that adds actions to the toolbar and popup menu of the view. These actions call specific methods in the view, for example to go up one directory.
It was easy to do this by action because I just create my action in the View class itself and programmatically add them to the toolbar
IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager();
mgr.add(upDirectory);
mgr.add(refresh);
mgr.add(changeRoot);
and the creation of the actions are called from the createPartControl()
upDirectory = new Action("Go up one directory") {
public void run() {
goUpOneDirectory();
}
};
where goUpOneDirectory() is a method in the view
If I want to convert this to a command, I want to be able to access this method of the view in my handler. So I tried the following,
private void createHandlers()
{
IHandlerService handlerService = (IHandlerService) getSite().getService(IHandlerService.class);
IHandler upDirHandler = new AbstractHandler() {
public Object execute(ExecutionEvent event)
throws ExecutionException {
goUpOneDirectory();
return null;
}
};
handlerService.activateHandler("updir.id", upDirHandler);
}
And createHandlers is called in the createPartControl, and the command is added via the plugin.xml to the toolbar of the view. The problem is that the moment my view is out of focus it disables the buttons in the toolbar for these commands.
I want them to remain enabled at all times. How can I do that?
I know that the isEnabled() returns true all the time so I am not sure why it happens. The activateHanlder is called once in createPartControl so I feel that it should remain active all the time.
Edit: Ok I just saw this ,
IHandlerService from the workbench part site is the part handler
service. Any handlers activated through the part handlers service will
only be active when that part is active. Any listeners added to the
part handler service will be removed when the part is disposed, and
any active handlers will be deactivated (but not disposed).
So how can I get this,
IHandlerService from the workbench is the global handler service. it
provides no special activation scoping or lifecycle.
Sorry, I should have waited a bit longer before asking, I figured it out!
I changed the,
IHandlerService handlerService = (IHandlerService) getSite().getService(IHandlerService.class);
to
IHandlerService handlerService = (IHandlerService) PlatformUI.getWorkbench().getService(IHandlerService.class);
and it worked.
I will leave the question in case it helps other people.

Creating a JApplet (swing based applet) with netbeans?

I am starting to learn Java a little after long time. And learning Netbeans 7.0.
I just want to make sure I am doing this ok.
I basically need to make an applet, but not having it AWT based, but instead Swing based.
So I need to extend JApplet, not Applet. I understand in swing draws on a Jpanel instead of awt canvas (or Panel). And so I read on a web site that one needs to override PaintComponent() instead of overrriding paint() as the case with awt applet?
I need to make a very simple applet, say with one button, when I click on it, I want to draw a graphics, say a line or circle, and have the output go to an area below the button.
This is what I did
File->New Project
Select Java and from Projects, select "Java Application"
make sure to Un-check the "create Main class", and click Finish
File->New file
Select "Swing GUI Forms" from under the catagories panel
From the "File types", Select Japplet Form,Next and Finish
From the palette, from Swing Controls, select Button and lay it on the from
Now the tricky part. I need an area to draw on, right? So I from palette, I select, from Swing containers, a "Panel", and lay it on the form, resize it as needed. Do, now I have this:
Am I on the right track so far? Now I open the source file, and I see the init() method.
Now is where I need little help. Not sure what the code I need to insert to just draw a line to the JPanel I just added. I know I need to insert it here:
I tried the "insert Code" feature, and select override, but do not see PaintComponent()?
I know how to do it in swt applet, just add a paint(Graphics g) method. But when I do this, the graphics do not draw inside the Jpanel area. Basically, how do I tell it to draw something to a specific JPanel area?
If someone just tell me what code I need to insert there to draw a line or any graphics2D object to display on that JPanel I added below the bottom, that will great.
thanks,
--Nasser
EDIT 1:
Just a clarrification: If I add this function to paint on the Jpanel:
public void paint(Graphics g)
{
super.paint(g);
g.drawString(....);
}
Then the output does show ok, but it over the main Japnel. And can hide the button and any other UI components are there.
I need the paint output to go to a specific Jpanel which I added earlier below the button. To this one
private javax.swing.JPanel jPanel1;
So, my question is, how to draw/paint to the above object and not to the main Jpanel?
EDIT 2:
I tried just to change the JPanel background color, and it is not working. Here is the code.
I also tried JpanelForm instead of JApplet Form. Can one use JFrame form to make an applet? Since that requires a main() it does not seem possible.
import javax.swing.*;
import java.awt.*;
import java.awt.Graphics;
public class NewJApplet extends javax.swing.JApplet
{
/** Initializes the applet NewJApplet */
public void init()
{
jPanel1 = new JPanel();
try
{
java.awt.EventQueue.invokeAndWait(new Runnable()
{
public void run()
{
initComponents();
}
});
} catch (Exception ex)
{
ex.printStackTrace();
}
}
private void initComponents() {...}
//--------- ADDED THIS
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
{
// TODO add your handling code here:
Rectangle rect=new Rectangle(4,4);
jPanel1.setBackground(Color.RED);
}
//---------------
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JPanel jPanel1;
// End of variables declaration
}
NetBeans "does" support JApplet. After creating a new project, rt-click on the project's package in "projects" pane which is to the left of your coding area and choose New -> JApplet
netbeans does not support making JApplets, only applets. Use standard text editor to design the JApplet interface then compile the source code using javac.
I went through the same thing just now, you just need to take the package name out from the file and just compile it. You will get a message in netbeans that the applet is not initialized which is ok, just go to the source folder where .class files are stored you will find multiple NewJApplet.class files, You will see some with a $ sign in them too.
Copy all the .class files put it together with the html file and that is it. View your JApplet created using the form on the browser. Makes creating anything with java so much fun.