Well I'm writing an IRC client in Java and I was wondering if there was a way to make my app's icon bounce in the dock when a nickalert is triggered (or any other relevant notification).
If Windows also has some sort of notification system I'd like to know about it as well.
Under the MacOS, try using something like Application#requestUserAttention(boolean)
import com.apple.eawt.Application;
...
Application application = Application.getApplication();
application.requestUserAttention(false);
nb- I've not tried this my self - sorry.
Updated with example
From the JavaDocs
Requests user attention to this application (usually through bouncing
the Dock icon). Critical requests will continue to bounce the Dock
icon until the app is activated. An already active application
requesting attention does nothing.
That means, that if the application has focus, then the method will do nothing.
Test on Mac OSX 10.7.5, Java 1.7.0_07
import com.apple.eawt.Application;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestMacIcon {
public static void main(String[] args) {
new TestMacIcon();
}
public TestMacIcon() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
final Application application = Application.getApplication();
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
try {
System.out.println("clicked");
application.requestUserAttention(true);
application.setDockIconImage(ImageIO.read(getClass().getResource("/Java.png")));
application.setDockIconBadge("Blah");
application.requestUserAttention(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
Timer time = new Timer(2000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (!SwingUtilities.getWindowAncestor(TestPane.this).hasFocus()) {
((Timer)e.getSource()).stop();
System.out.println("Pay attention!!");
application.requestUserAttention(true);
}
}
});
time.setRepeats(true);
time.setCoalesce(true);
time.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
Ps make sure that you do-focus application ;)
Related
I have a full screen window that plays a simple animation, and I want to make it so that when I press any key, the full screen is restored and the program stops.
The key listener class looks like this:
import java.awt.event.*;
public class key implements KeyListener {
private framerun animation=new framerun();
public void keyPressed(KeyEvent e){}
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e){
animation.x=false;
}
}
The animation runs in a method, run, with a while loop which looks like this:
public void run(DisplayMode dm){
Screen s=new Screen();
s.setFullScreen(dm, this);
while(true){
try{
System.out.println(x);
Thread.sleep(300);
}catch(Exception e){}
if(!x)
s.RestoreScreen();
repaint();
}
}
PS: x is a boolean with initial value true, initiated in the constructor.
This is the main method:
public static void main(String args []){
DisplayMode dm=new DisplayMode(800, 600, 16,DisplayMode.REFRESH_RATE_UNKNOWN);
framerun f=new framerun();
key k=new key();
f.addKeyListener(k);
f.run(dm);
}
Now this works perfectly if there is no while loop. The full screen closes and the program stop. But with the while loop there is no response when I press a key. The value of x doesn't change to false as expected.
Ideas?
I can't get the DisplayMode switching to work, but it shouldn't make a difference.
Basically, KeyListener is fiddly. It requires the component that it is attached to is focusable and has focus.
The following example basically uses a combination of requestFocusInWindow and setFocusable on a JPanel to try and force focus to the JPanel, so that when a key is typed, the JPanel can respond to it...
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.EventQueue;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
private DisplayMode defaultMode;
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
defaultMode = gd.getDisplayMode();
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
// DisplayMode dm = new DisplayMode(800, 600, 16, DisplayMode.BIT_DEPTH_MULTI);
// gd.setDisplayMode(dm);
gd.setFullScreenWindow(frame);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setFocusable(true);
setLayout(new GridBagLayout());
add(new JLabel("Test"));
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
requestFocusInWindow();
}
});
addKeyListener(new KeyAdapter() {
#Override
public void keyTyped(KeyEvent e) {
try {
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
// gd.setDisplayMode(defaultMode);
gd.setFullScreenWindow(null);
} catch (Throwable exp) {
exp.printStackTrace();
}
SwingUtilities.windowForComponent(TestPane.this).dispose();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
Personlly, I'd recommend using the key bindings API, How to Use Key Bindings, but this focuses on binding a single key to a given action, but overcomes the focus issues related to KeyListener
How to Disable/Enable JFrame components when JInternalFrame isVisible inside JFrame/JDesktopPane? For example, make every JInternalFrame1 visible on the JDesktopPane (desktop pane set on the JFrame) all frame components like JMenuBar/JButton/etc. set disabled.
Have a solution?
If you have a reference to all your components, the best shot is to write a simple method that would disable everything (more or less like a state machine).
If you don't have a reference to all of them (like a GUI that uses reflection) you will need to get a root panel and iterate over it finding every component and disabling it.
Take a look at the Jemmy tool that is used to test Netbeans, they have a GUIBrowser that can give you an idea.
That makes use of JXLayer and JHLabs filters, basically, it creates a custom frame that wraps the JRootPane in a JXLayer, which allows you to "disable" the entire frame...
import com.jhlabs.image.BlurFilter;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JRootPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.jdesktop.jxlayer.JXLayer;
import org.jdesktop.jxlayer.plaf.effect.BufferedImageOpEffect;
import org.jdesktop.jxlayer.plaf.ext.LockableUI;
public class EnabledFrame {
public static void main(String[] args) {
new EnabledFrame();
}
public EnabledFrame() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
final LayeredFrame frame = new LayeredFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
JMenuBar mb = new JMenuBar();
JMenu mFile = new JMenu("File");
mFile.add("Exit");
frame.setJMenuBar(mb);
mb.add(mFile);
JButton btn = new JButton("Click me");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
frame.setEnabled(false);
}
});
frame.add(btn);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class LayeredFrame extends JFrame {
private BlurableLockedUI lockUI;
private JXLayer<JRootPane> rootLayer;
public LayeredFrame(String title) throws HeadlessException {
super(title);
}
#Override
protected void setRootPane(JRootPane root) {
if (rootLayer != null) {
remove(rootLayer);
}
super.setRootPane(root);
JRootPane rootPane = getRootPane();
rootLayer = new JXLayer<>(root);
rootLayer.setUI(getLockUI());
add(rootLayer, BorderLayout.CENTER);
}
protected BlurableLockedUI getLockUI() {
if (lockUI == null) {
lockUI = new BlurableLockedUI();
}
return lockUI;
}
#Override
public void setEnabled(boolean b) {
getLockUI().setLocked(!b);
super.setEnabled(b);
}
}
public class BlurableLockedUI extends LockableUI {
public BlurableLockedUI() {
super(new BufferedImageOpEffect(new BlurFilter()));
}
public void repaint() {
setDirty(true);
}
public void invalidate() {
setDirty(true);
}
public void revalidate() {
setDirty(true);
}
}
}
I am making a java application that includes a JWindow. I want to be able to track the mouse without the user having to click the window after going to another window.
Your question is little vague on why you want to continue processing the mouse once it's left the JWindow...but
You have two (basic) choices when it comes to mointoring the mouse outside of your application, you can use a JNI/JNA solution or you can poll MouseInfo.
The following demonstrates the latter, using MouseInfo and a javax.swing.Timer to update a label...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.MouseInfo;
import java.awt.PointerInfo;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MouseWindow {
public static void main(String[] args) {
new MouseWindow();
}
public MouseWindow() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel label;
public TestPane() {
setLayout(new BorderLayout());
label = new JLabel();
label.setFont(label.getFont().deriveFont(48f));
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalAlignment(JLabel.CENTER);
add(label);
updateMouseInfo();
Timer timer = new Timer(250, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
updateMouseInfo();
}
});
timer.start();
}
protected void updateMouseInfo() {
PointerInfo pi = MouseInfo.getPointerInfo();
label.setText(pi.getLocation().x + "x" + pi.getLocation().y);
}
}
}
Updated
You may also find Window#setAlwaysOnTop of help to keep the window ontop of the others, if support for the platform
Is possible to capture event when user tries to close floating toolbar window in swing?
Thanks in advance.
There's probably some really awesomely simple solution, but why would you use that?
The best I could come up with (without extending out my own tool bar) was to add an AncestorListener to the toolbar and monitor it's events.
The problem I have this approach, though, is you need to know the main frame you were originally attached to, which may not be convenient.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
public class TestFloatingToolBar {
public static void main(String[] args) {
new TestFloatingToolBar();
}
public TestFloatingToolBar() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
final JFrame frame = new JFrame("Test");
final JToolBar tb = new JToolBar();
tb.add(new JButton("Pop"));
tb.setFloatable(true);
tb.addAncestorListener(new AncestorListener() {
#Override
public void ancestorAdded(AncestorEvent event) {
tell();
if (SwingUtilities.getWindowAncestor(tb).equals(frame)) {
System.out.println("...In Main Frame");
} else {
System.out.println("...Maybe floating");
}
}
#Override
public void ancestorRemoved(AncestorEvent event) {
tell();
if (SwingUtilities.getWindowAncestor(tb).equals(frame)) {
System.out.println("...In Main Frame");
} else {
System.out.println("...Maybe floating");
}
}
#Override
public void ancestorMoved(AncestorEvent event) {
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(tb, BorderLayout.NORTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public void tell() {
Exception exp = new Exception();
StackTraceElement[] stackTrace = exp.getStackTrace();
System.out.println(stackTrace[1].getMethodName());
}
}
Well I'm writing an IRC client in Java and I was wondering if there was a way to make my app's icon bounce in the dock when a nickalert is triggered (or any other relevant notification).
If Windows also has some sort of notification system I'd like to know about it as well.
Under the MacOS, try using something like Application#requestUserAttention(boolean)
import com.apple.eawt.Application;
...
Application application = Application.getApplication();
application.requestUserAttention(false);
nb- I've not tried this my self - sorry.
Updated with example
From the JavaDocs
Requests user attention to this application (usually through bouncing
the Dock icon). Critical requests will continue to bounce the Dock
icon until the app is activated. An already active application
requesting attention does nothing.
That means, that if the application has focus, then the method will do nothing.
Test on Mac OSX 10.7.5, Java 1.7.0_07
import com.apple.eawt.Application;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestMacIcon {
public static void main(String[] args) {
new TestMacIcon();
}
public TestMacIcon() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
final Application application = Application.getApplication();
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
try {
System.out.println("clicked");
application.requestUserAttention(true);
application.setDockIconImage(ImageIO.read(getClass().getResource("/Java.png")));
application.setDockIconBadge("Blah");
application.requestUserAttention(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
Timer time = new Timer(2000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (!SwingUtilities.getWindowAncestor(TestPane.this).hasFocus()) {
((Timer)e.getSource()).stop();
System.out.println("Pay attention!!");
application.requestUserAttention(true);
}
}
});
time.setRepeats(true);
time.setCoalesce(true);
time.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
Ps make sure that you do-focus application ;)