Why not pop-up window when I using SwingTrayIcon - java

I have a problem that the windows cannot pop-up window which setting on the timer. The code below the Block. How can I resolve the problem? Can someone tell me. I very much appreciate it.
I want to get my fortunes to show on the poping window.
When I try this code first, It seems successful, But once. I had never change the code, but it does not work.
I am trying to restart my computer, and I had twice but failed too.
My computer is a system of Windows 10 X64
package systemTray;
import java.awt.*;
import java.io.*;
import java.util.*;
import java.util.List;
import javax.swing.*;
import javax.swing.Timer;
/**
* This program demonstrates the system tray API.
* #version 1.02 2016-05-10
* #author Cay Horstmann
*/
public class SystemTrayTest
{
public static void main(String[] args)
{
SystemTrayApp app = new SystemTrayApp();
app.init();
}
}
class SystemTrayApp
{
public void init()
{
final TrayIcon trayIcon;
if (!SystemTray.isSupported())
{
System.err.println("System tray is not supported.");
return;
}
SystemTray tray = SystemTray.getSystemTray();
Image image = new ImageIcon(getClass().getResource("cookie.png")).getImage();
PopupMenu popup = new PopupMenu();
MenuItem exitItem = new MenuItem("Exit");
exitItem.addActionListener(event -> System.exit(0));
popup.add(exitItem);
trayIcon = new TrayIcon(image, "Your Fortune", popup);
trayIcon.setImageAutoSize(true);
trayIcon.addActionListener(event ->
{
trayIcon.displayMessage("How do I turn this off?",
"Right-click on the fortune cookie and select Exit.",
TrayIcon.MessageType.INFO);
});
try
{
tray.add(trayIcon);
}
catch (AWTException e)
{
System.err.println("TrayIcon could not be added.");
return;
}
//get fortunes to show
final List<String> fortunes = readFortunes();
// I want to pop up window to show message with the timer.
Timer timer = new Timer(10000, event ->
{
int index = (int) (fortunes.size() * Math.random());
trayIcon.displayMessage("Your Fortune", fortunes.get(index),
TrayIcon.MessageType.INFO);
});
timer.start();
}
}

Related

Notification widget within an RCP application

I am looking for a widget or component (SWT), that allows me to notify the user whenever a background job has finished. I am aware of things like MyLyn, that provide ways of creating system notifications. However, I would prefer a widget that displays the notifications within my window. Is there any existing widget out there that I was unable to find?
Thanks.
[EDIT]
I have seen a component do more or less what I want. It is used in the eclipse error reporting as described here: https://eclipsesource.com/blogs/2015/06/23/error-reporting-top-eclipse-mars-feature-2/ However I can't seem to find the underlying widget being used here.
You can use ToolTip as notification which will appear in taskbar tray item. I provide below the code snippet you can try. In windows, it popups like small black popup window in the right lower corner. I have provided button just to simulate. You can implement in your own way once the background long running task is over.
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolTip;
import org.eclipse.swt.widgets.Tray;
import org.eclipse.swt.widgets.TrayItem;
public class ToolTipBalloon {
public static void showNotificationPopup(Shell shell) {
ToolTip tip = new ToolTip(shell, SWT.BALLOON | SWT.ICON_INFORMATION);
tip.setMessage("Your Notification Message");
Display display = shell.getDisplay();
Tray tray = display.getSystemTray();
if (tray != null) {
TrayItem item = new TrayItem(tray, SWT.NONE);
// Image image = new Image(display, "yourFile.gif");
// item.setImage(image);
tip.setText("Notification from a Windows Tray");
item.setToolTip(tip);
} else {
tip.setText("Notification from anywhere");
tip.setLocation(400, 400);
}
tip.setVisible(true);
}
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
// To simulate notification
Button notifyBtn = new Button(shell, SWT.PUSH);
notifyBtn.setText("Press for Notification");
notifyBtn.addListener(
SWT.Selection,
new Listener() {
public void handleEvent(Event event) {
showNotificationPopup(shell);
}
});
notifyBtn.pack();
shell.setBounds(50, 50, 200, 100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
}
I will suggest you can explore Nebula Notifier . You may have to customize it for notification inside your application
Took below code snippet
public class NotifierSnippet {
/**
* #param args
*/
public static void main(final String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setText("Notifier Snippet");
shell.setSize(200, 200);
shell.setLayout(new FillLayout(SWT.VERTICAL));
final int[] counter = new int[1];
counter[0] = 0;
// Yellow theme (default)
final Button testerYellow = new Button(shell, SWT.PUSH);
testerYellow.setText("Push me [Yellow theme]!");
testerYellow.addListener(SWT.Selection, event -> {
Notifier.notify("New Mail message", "Laurent CARON (lcaron#...)<br/><br/>Test message #" + counter[0] + "...");
counter[0]++;
});
// Blue theme
final Button testerBlue = new Button(shell, SWT.PUSH);
testerBlue.setText("Push me [Blue theme]!");
testerBlue.addListener(SWT.Selection, event -> {
Notifier.notify("New Mail message", "Laurent CARON (lcaron#...)<br/><br/>Test message #" + counter[0] + "...", NotifierTheme.BLUE_THEME);
counter[0]++;
});
// Grey theme
final Button testerGrey = new Button(shell, SWT.PUSH);
testerGrey.setText("Push me [Gray theme]!");
testerGrey.addListener(SWT.Selection, event -> {
Notifier.notify("New Mail message", "Laurent CARON (lcaron#...)<br/><br/>Test message #" + counter[0] + "...", NotifierTheme.GRAY_THEME);
counter[0]++;
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}

JPopoupMenu covered by window's title

I am writing a Main-menu + Network traffic monitor. My system runs Linux Cinnamon Mint.
The problem is that the application's title always appears over the menu.
When I click over the iconized window, JFrame opens and the JPopoupMenu appears over it.
While the mouse pointer is inside the panel, the title hovers above the iconized window, as it should, but when I move it over the menu it doesn't disappear.
The mouse pointer wasn't captured but it was inside the panel (over the iconized window) in the left picture and over the menu in the right one.
If I do the same, but without showing the menu (JFrame's window with the same size as the menu), the title only appears when the mouse pointer is inside the panel.
I have tried different components for 'popupMenu.setInvoker(Component)' but in the few cases where the problem disappears the menu loses focus.
Thank you beforehand for your help.
Here is a SSCCE (Main.java) that I cobbled together so you can test the code:
// To run: javac Main.java; java Main
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GraphicsEnvironment;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.WindowConstants;
/**
*
* #author Manuel Iglesias Alonso glesialo#gmail.com
*/
public class Main extends JFrame {
private final MainMenu mainMenu;
private boolean menuPopupEnabled;
public Main(ImageIcon icon, File rootMenuDirectory) {
super();
menuPopupEnabled = false;
setIconImage(icon.getImage());
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
addWindowListener(new WindowAdapter() {
#Override
public void windowDeiconified(WindowEvent e) {
super.windowDeiconified(e);
if (menuPopupEnabled) {
mainMenu.popup(MouseInfo.getPointerInfo().getLocation());
}
}
});
mainMenu = new MainMenu(this, rootMenuDirectory);
pack(); // Before setPreferredSize: smaller window size.
setPreferredSize(new Dimension(0, 0)); // Window is always hidden behind menu, the smaller the better.
setVisible(true);
}
private class MainMenu {
private final int panelHeight = 25;
private final int iconizedWindowWidthPanelHeightRatio = 5; // Iconized window's width / Iconized window' height
private final JFrame frame;
private final File rootMenuDirectory;
private final Rectangle graphicsBounds;
private PopupMenuInFrame popupMenu;
private class PopupMenuInFrame extends JPopupMenu {
#Override
protected void firePopupMenuWillBecomeInvisible() {
super.firePopupMenuWillBecomeInvisible();
frame.setExtendedState(JFrame.ICONIFIED);
}
}
/**
*
* #param rootMenuDirectory Directory where menu files are to be found.
*/
public MainMenu(JFrame frame, File rootMenuDirectory) {
this.frame = frame;
this.rootMenuDirectory = rootMenuDirectory;
graphicsBounds = frame.getGraphicsConfiguration().getBounds();
}
private void newMenu() {
popupMenu = new PopupMenuInFrame();
JMenuItem menuItem = new JMenuItem("1st popup menu item");
menuItem.setToolTipText("1st ToolTip");
popupMenu.add(menuItem);
menuItem = new JMenuItem("2nd popup menu item");
menuItem.setToolTipText("2nd popup menu item ToolTip");
popupMenu.add(menuItem);
menuItem = new JMenuItem("3rd A popup menu item");
menuItem.setToolTipText("menu item ToolTip");
popupMenu.add(menuItem);
menuItem = new JMenuItem("4th popup menu item");
menuItem.setToolTipText("4th popup menu item menu item ToolTip");
popupMenu.add(menuItem);
menuItem = new JMenuItem("5th popup menu item");
menuItem.setToolTipText("ToolTip");
popupMenu.add(menuItem);
menuItem = new JMenuItem("6th popup menu item");
menuItem.setToolTipText("popup menu item menu item ToolTip");
popupMenu.add(menuItem);
}
public void popup(Point mousePointerPosition) {
Point menuPosition;
newMenu();
popupMenu.setInvoker(frame.getContentPane());
menuPosition = new Point(mousePointerPosition.x, mousePointerPosition.y);
if (mousePointerPosition.x < iconizedWindowWidthPanelHeightRatio * panelHeight) { //If pointer near leftmost border (within width of iconized window).
if (mousePointerPosition.y < (panelHeight + 1)
|| mousePointerPosition.y > (graphicsBounds.height - panelHeight - 1)) { //If pointer inside a top or bottom panel
menuPosition.x = 1; // Position: near left border.
}
}
if (mousePointerPosition.y < (panelHeight + 1)) { //If pointer inside a top panel (within panel's height + 1)
menuPosition.y = panelHeight + 1; //Menu's top edge just below the panel's lower edge.
} else {
if (mousePointerPosition.y > (graphicsBounds.height - panelHeight - 1)) { //If pointer inside a bottom panel (within panel's height + 1)
menuPosition.y = graphicsBounds.height - popupMenu.getPreferredSize().height - panelHeight - 1; //Menu's lower edge just above the panel's upper edge.
}
}
frame.setLocation(menuPosition.x + 5, menuPosition.y + 5); // + 5 to make sure window is hidden behind popupMenu.
popupMenu.setLocation(menuPosition.x, menuPosition.y);
popupMenu.setVisible(true);
}
}
public static void main(String[] args) {
final ImageIcon icon;
final File rootMenuDirectory;
icon = new ImageIcon();
rootMenuDirectory = new File("");
Main frame = new Main(icon, rootMenuDirectory);
frame.setTitle("Test title");
try {
Thread.sleep(500);
} catch (Exception e) {
}
if (!GraphicsEnvironment.isHeadless()) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
frame.setExtendedState(JFrame.ICONIFIED); // Start iconified. If setExtendedState used out of run(), window's events are blocked.
frame.menuPopupEnabled = true; // Menu can pop from now on.
}
});
} else {
System.exit(1);
}
}
}
PS: I have modified the SSCCE adding tool-tips to the menu items. There is another problem: Sometimes (while moving the mouse pointer, up and down, over the menu items) the tool-tips do not appear complete:
Nobody helps? :-(
I have almost finished the application. I have added an extra menu item, 'MainMenu: About', so that that item is the only part covered by the damn vindow title (title disappears once the menu operates: submenus, tooltips...). The problem with incomplete tooltips also happens with oracle' tutorial examples (if I add tooltips) so it has nothing to do with my code.
Here is a picture of the running menu (It will move to just over the iconized window when it is on the far left of the panel: first startup application):
The application sends an 'sticky' hint to the Window Manager and the window appears in all workspaces.

trayicon.displaymessage text size java

This is my first post in this forum and I really hope that it will be answered ASAP. I'm new to Java and loves trying different things often. I thought of making simple balloon message application in Java that pops up at certain time in the system tray conveying different message over time. Just wondering if I could change the text size of the balloon message. Also if somebody can help me out with time intervals and delays for the message to appear and disappear. Below is my code that I tried, please ponder a bit to help me out with this problem.
import java.awt.Image;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import javax.swing.ImageIcon;
public class BubbleMessages {
public static void main(String[] args) throws Exception{
SystemTray tray = SystemTray.getSystemTray();
Image i = new ImageIcon("resources/bulb.gif").getImage();
TrayIcon ti = new TrayIcon(i);
tray.add(ti);
ti.displayMessage("Message", "message", TrayIcon.MessageType.INFO);
}
}
Check the api. The message will automatically disappear with a user click.
If you want to display the message again, you might use Timer
You can modify the code like this
import java.awt.Image;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import javax.swing.ImageIcon;
public class BubbleMessages {
private static TrayIcon ti;
public static void main(String[] args) throws Exception{
SystemTray tray = SystemTray.getSystemTray();
Image i = new ImageIcon("resources/bulb.gif").getImage();
ti = new TrayIcon(i);
tray.add(ti);
MessageDisplayTask mdt = new MessageDisplayTask(ti);
java.util.Timer timer = new java.util.Timer("DM");
timer.schedule(mdt, 0, 10000);//Every three seconds, it shows a message
}
}
class MessageDisplayTask extends java.util.TimerTask {
private TrayIcon ti;
private int displayCount = 0;
public MessageDisplayTask(TrayIcon ti){
this.ti = ti;
}
public void run() {
displayCount++;
if (displayCount <= 10) {
ti.displayMessage("Message", "Message#" + displayCount, TrayIcon.MessageType.INFO);
} else {
//Stop Timer.
this.cancel();
}
}
}
tray.add(ti);
ti.setImageAutoSize(true);
ti.displayMessage("Message", "message", TrayIcon.MessageType.INFO);

What kind of popup "Safe To Remove Hardware" in Windows

i am working on a java project and i want to display a message in popup like the popup of "Safe To Remove Hardware" occurred in the windows when we click on the Eject icon for USB Drives.
I want show my message in the same kind of popup using java code.
Use the SystemTray class.
To create an icon with a tooltip, use something like this:
SystemTray tray = SystemTray.getSystemTray();
TrayIcon icon = new TrayIcon(....);
icon.setToolTip("I have finished my work");
icon.setActionListener(this);
tray.add(trayIcon);
Then in the class that displays the tooltip, implement the ActionListener interface to be informed when the user clicks on the icon and/or the tooltip (that's what the setActionListener() is for)
For more details refer to the Javadocs of SystemTray, TrayIcon and ActionListener
You simply need to use the displayMessage(...) method of the TrayIcon class.
Try your hands on this code, is this what you wanted :
import java.awt.*;
import java.net.URL;
import javax.swing.*;
public class BalloonExample
{
private void createAndDisplayGUI()
{
TrayIcon trayIcon = new TrayIcon(createImage(
"/image/caIcon.png", "tray icon"));
SystemTray tray = SystemTray.getSystemTray();
try
{
tray.add(trayIcon);
}
catch (AWTException e)
{
System.out.println("TrayIcon could not be added.");
return;
}
trayIcon.displayMessage("Balloon", "My First Balloon", TrayIcon.MessageType.INFO);
}
//Obtain the image URL
protected static Image createImage(String path, String description) {
URL imageURL = BalloonExample.class.getResource(path);
if (imageURL == null) {
System.err.println("Resource not found: " + path);
return null;
} else {
return (new ImageIcon(imageURL, description)).getImage();
}
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new BalloonExample().createAndDisplayGUI();
}
});
}
}
Have a look at my question here. Basically that tooltip is a Balloon tip and you can use ShellNotifyIcon to create one.

Windows 7 Seems to break SWT Control.print(GC)

A bug has been filed and fixed (super quickly) in SWT:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=305294
Just to preface this, my goal here is to print the two images into a canvas so that I can animate the canvas sliding across the screen (think iPhone), sliding the controls themselves was too CPU intensive, so this was a good alternative until I tested it on Win7. I'm open to anything that will help me solve my original problem, it doesn't have to be fixing the problem below.
Does anyone know how to get "Control.print(GC)" to work with Windows 7 Aero? I have code that works just fine in Windows XP and in Windows 7, when Aero is disabled, but the command:
control.print(GC) causes a non-top control to be effectively erased from the screen.
GC gc = new GC(image);
try {
// As soon as this code is called, calling "layout" on the controls
// causes them to disappear.
control.print(gc);
} finally {
gc.dispose();
}
I have stacked controls and would like to print the images from the current and next controls such that I can "slide" them off the screen. However, upon printing the non-top control, it is never redrawn again.
Here is some example code. (Interesting code bits are at the top and it will require pointing at SWT in order to work.)
Thanks for any and all help. As a work around, I'm thinking about swapping controls between prints to see if that helps, but I'd rather not.
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
public class SWTImagePrintTest {
private Composite stack;
private StackLayout layout;
private Label lblFlip;
private Label lblFlop;
private boolean flip = true;
private Button buttonFlop;
private Button buttonPrint;
/**
* Prints the control into an image
*
* #param control
*/
protected void print(Control control) {
Image image = new Image(control.getDisplay(), control.getBounds());
GC gc = new GC(image);
try {
// As soon as this code is called, calling "layout" on the controls
// causes them to disappear.
control.print(gc);
} finally {
gc.dispose();
}
}
/**
* Swaps the controls in the stack
*/
private void flipFlop() {
if (flip) {
flip = false;
layout.topControl = lblFlop;
buttonFlop.setText("flop");
stack.layout();
} else {
flip = true;
layout.topControl = lblFlip;
buttonFlop.setText("flip");
stack.layout();
}
}
private void createContents(Shell shell) {
shell.setLayout(new GridLayout(2, true));
stack = new Composite(shell, SWT.NONE);
GridData gdStack = new GridData(GridData.FILL_BOTH);
gdStack.horizontalSpan = 2;
stack.setLayoutData(gdStack);
layout = new StackLayout();
stack.setLayout(layout);
lblFlip = new Label(stack, SWT.BOLD);
lblFlip.setBackground(Display.getCurrent().getSystemColor(
SWT.COLOR_CYAN));
lblFlip.setText("FlIp");
lblFlop = new Label(stack, SWT.NONE);
lblFlop.setBackground(Display.getCurrent().getSystemColor(
SWT.COLOR_BLUE));
lblFlop.setText("fLoP");
layout.topControl = lblFlip;
stack.layout();
buttonFlop = new Button(shell, SWT.FLAT);
buttonFlop.setText("Flip");
GridData gdFlip = new GridData();
gdFlip.horizontalAlignment = SWT.RIGHT;
buttonFlop.setLayoutData(gdFlip);
buttonFlop.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
flipFlop();
}
});
buttonPrint = new Button(shell, SWT.FLAT);
buttonPrint.setText("Print");
GridData gdPrint = new GridData();
gdPrint.horizontalAlignment = SWT.LEFT;
buttonPrint.setLayoutData(gdPrint);
buttonPrint.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
print(lblFlip);
print(lblFlop);
}
});
}
/**
* #param args
*/
public static void main(String[] args) {
Shell shell = new Shell();
shell.setText("Slider Test");
shell.setSize(new Point(800, 600));
shell.setLayout(new GridLayout());
SWTImagePrintTest tt = new SWTImagePrintTest();
tt.createContents(shell);
shell.open();
Display display = Display.getDefault();
while (shell.isDisposed() == false) {
if (display.readAndDispatch() == false) {
display.sleep();
}
}
display.dispose();
}
}
This was the result of a bug:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=305294
It's since been fixed. Hopefully a new packaged version of SWT will come out soon so we can officially use it.

Categories

Resources