Improve Growl exception handling, remove System.out and a few fixes from audit
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1048 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
437837e21c
commit
a7c218857b
|
@ -37,175 +37,144 @@ import javax.imageio.ImageIO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Growl notification implementation. This uses JNI to send messages to Growl.
|
* Growl notification implementation. This uses JNI to send messages to Growl.
|
||||||
*
|
*
|
||||||
* @author Michael Stringer
|
* @author Michael Stringer
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
*/
|
*/
|
||||||
class GrowlNative implements Growl {
|
class GrowlNative implements Growl {
|
||||||
private String appName;
|
private final String appName;
|
||||||
private List<NotificationType> notifications;
|
private final List<NotificationType> notifications;
|
||||||
private List<GrowlCallbackListener> callbackListeners;
|
private final List<GrowlCallbackListener> callbackListeners;
|
||||||
private byte[] imageData;
|
private byte[] imageData;
|
||||||
|
|
||||||
private native void sendNotification(String appName, String name,
|
private native void sendNotification(String appName, String name,
|
||||||
String title, String message, String callbackContext, byte[] icon);
|
String title, String message, String callbackContext, byte[] icon);
|
||||||
|
|
||||||
private native void registerApp(String appName, byte[] image,
|
private native void registerApp(String appName, byte[] image,
|
||||||
List<NotificationType> notifications);
|
List<NotificationType> notifications);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new <code>GrowlNative</code> instance for the specified
|
* Creates a new <code>GrowlNative</code> instance for the specified
|
||||||
* application name.
|
* application name.
|
||||||
*
|
*
|
||||||
* @param appName
|
* @param appName The name of the application sending notifications.
|
||||||
* The name of the application sending notifications.
|
|
||||||
*/
|
*/
|
||||||
GrowlNative(String appName) {
|
GrowlNative(String appName) {
|
||||||
notifications = new ArrayList<NotificationType>();
|
notifications = new ArrayList<NotificationType>();
|
||||||
callbackListeners = new ArrayList<GrowlCallbackListener>();
|
callbackListeners = new ArrayList<GrowlCallbackListener>();
|
||||||
this.appName = appName;
|
this.appName = appName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"UnusedDeclaration"})
|
||||||
void fireCallbacks(String callbackContext) {
|
void fireCallbacks(String callbackContext) {
|
||||||
for (GrowlCallbackListener listener : callbackListeners) {
|
for (GrowlCallbackListener listener : callbackListeners) {
|
||||||
listener.notificationWasClicked(callbackContext);
|
listener.notificationWasClicked(callbackContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public void register() throws GrowlException {
|
public void register() throws GrowlException {
|
||||||
registerApp(appName, imageData, notifications);
|
registerApp(appName, imageData, notifications);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public void addNotification(String name, boolean enabledByDefault) {
|
public void addNotification(String name, boolean enabledByDefault) {
|
||||||
notifications.add(new NotificationType(name, enabledByDefault));
|
notifications.add(new NotificationType(name, enabledByDefault));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public void addCallbackListener(GrowlCallbackListener listener) {
|
public void addCallbackListener(GrowlCallbackListener listener) {
|
||||||
callbackListeners.add(listener);
|
callbackListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public void setIcon(RenderedImage icon) throws GrowlException {
|
public void setIcon(RenderedImage icon) throws GrowlException {
|
||||||
try {
|
imageData = convertImage(icon);
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
}
|
||||||
ImageIO.write(icon, "png", baos);
|
|
||||||
|
|
||||||
imageData = baos.toByteArray();
|
protected byte[] convertImage(RenderedImage icon) throws GrowlException {
|
||||||
} catch (IOException e) {
|
if (icon == null) {
|
||||||
// TODO Auto-generated catch block
|
return null;
|
||||||
e.printStackTrace();
|
}
|
||||||
}
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
try {
|
||||||
|
ImageIO.write(icon, "png", baos);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
throw new GrowlException("Failed to convert Image", ioe);
|
||||||
|
}
|
||||||
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public void sendNotification(String name, String title, String body)
|
public void sendNotification(String name, String title, String body)
|
||||||
throws GrowlException {
|
throws GrowlException {
|
||||||
if (!notifications.contains(new NotificationType(name, false))) {
|
sendNotification(name, title, body, null, null);
|
||||||
System.out.println("contains: " + notifications);
|
|
||||||
throw new GrowlException("Unregistered notification name [" + name
|
|
||||||
+ "]");
|
|
||||||
}
|
|
||||||
sendNotification(appName, name, title, body, null, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public void sendNotification(String name, String title, String body,
|
public void sendNotification(String name, String title, String body, RenderedImage icon) throws GrowlException {
|
||||||
RenderedImage icon) throws GrowlException {
|
sendNotification(name, title, body, null, icon);
|
||||||
if (!notifications.contains(new NotificationType(name, false))) {
|
|
||||||
System.out.println("contains: " + notifications);
|
|
||||||
throw new GrowlException("Unregistered notification name [" + name
|
|
||||||
+ "]");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
ImageIO.write(icon, "png", baos);
|
|
||||||
|
|
||||||
byte[] image = baos.toByteArray();
|
|
||||||
|
|
||||||
sendNotification(appName, name, title, body, null, image);
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
throw new GrowlException("Failed to convert Image", ioe);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public void sendNotification(String name, String title, String body,
|
public void sendNotification(String name, String title, String body, String callbackContext) throws GrowlException {
|
||||||
String callbackContext) throws GrowlException {
|
sendNotification(name, title, body, callbackContext, null);
|
||||||
if (!notifications.contains(new NotificationType(name, false))) {
|
|
||||||
System.out.println("contains: " + notifications);
|
|
||||||
throw new GrowlException("Unregistered notification name [" + name
|
|
||||||
+ "]");
|
|
||||||
}
|
|
||||||
|
|
||||||
sendNotification(appName, name, title, body, callbackContext, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public void sendNotification(String name, String title, String body,
|
public void sendNotification(String name, String title, String body, String callbackContext, RenderedImage icon)
|
||||||
String callbackContext, RenderedImage icon) throws GrowlException {
|
throws GrowlException {
|
||||||
if (!notifications.contains(new NotificationType(name, false))) {
|
if (!notifications.contains(new NotificationType(name, false))) {
|
||||||
System.out.println("contains: " + notifications);
|
throw new GrowlException("Unregistered notification name [" + name + ']');
|
||||||
throw new GrowlException("Unregistered notification name [" + name
|
}
|
||||||
+ "]");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
sendNotification(appName, name, title, body, callbackContext, convertImage(icon));
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
ImageIO.write(icon, "png", baos);
|
|
||||||
|
|
||||||
byte[] image = baos.toByteArray();
|
|
||||||
|
|
||||||
sendNotification(appName, name, title, body, callbackContext, image);
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
throw new GrowlException("Failed to convert Image", ioe);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NotificationType {
|
private class NotificationType {
|
||||||
private String name;
|
private final String name;
|
||||||
private boolean enabledByDefault;
|
private final boolean enabledByDefault;
|
||||||
|
|
||||||
public NotificationType(String name, boolean enabledByDefault) {
|
private NotificationType(String name, boolean enabledByDefault) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.enabledByDefault = enabledByDefault;
|
this.enabledByDefault = enabledByDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
@SuppressWarnings({"UnusedDeclaration"})
|
||||||
return name;
|
public String getName() {
|
||||||
}
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEnabledByDefault() {
|
@SuppressWarnings({"UnusedDeclaration"})
|
||||||
return enabledByDefault;
|
public boolean isEnabledByDefault() {
|
||||||
}
|
return enabledByDefault;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean equals(Object other) {
|
@Override
|
||||||
if (!(other instanceof NotificationType)) {
|
public boolean equals(Object other) {
|
||||||
return false;
|
return (other instanceof NotificationType) &&
|
||||||
}
|
name.equals(((NotificationType) other).name);
|
||||||
|
}
|
||||||
|
|
||||||
NotificationType otherType = (NotificationType) other;
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
return name.equals(otherType.name);
|
return name.hashCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,65 +32,65 @@ import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class for sending notifications using Growl.
|
* Utility class for sending notifications using Growl.
|
||||||
*
|
*
|
||||||
* @author Michael Stringer
|
* @author Michael Stringer
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
*/
|
*/
|
||||||
public final class GrowlUtils {
|
public final class GrowlUtils {
|
||||||
private static final boolean GROWL_LOADED;
|
private static final boolean GROWL_LOADED;
|
||||||
private static Map<String, Growl> instances = new HashMap<String, Growl>();
|
private static final Map<String, Growl> instances = new HashMap<String, Growl>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
boolean loaded = false;
|
boolean loaded = false;
|
||||||
try {
|
try {
|
||||||
System.loadLibrary("growl");
|
System.loadLibrary("growl");
|
||||||
loaded = true;
|
loaded = true;
|
||||||
} catch (UnsatisfiedLinkError ule) {
|
} catch (UnsatisfiedLinkError ule) {
|
||||||
System.out.println("Failed to load Growl library");
|
// ignore: growl not available
|
||||||
}
|
}
|
||||||
|
|
||||||
GROWL_LOADED = loaded;
|
GROWL_LOADED = loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method - should not be instantiated.
|
* Utility method - should not be instantiated.
|
||||||
*/
|
*/
|
||||||
private GrowlUtils() {
|
private GrowlUtils() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a <code>Growl</code> instance to use for the specified application
|
* Gets a <code>Growl</code> instance to use for the specified application
|
||||||
* name. Multiple calls to this method will return the same instance.
|
* name. Multiple calls to this method will return the same instance.
|
||||||
*
|
*
|
||||||
* @param appName
|
* @param appName The name of the application.
|
||||||
* The name of the application.
|
|
||||||
* @return The <code>Growl</code> instance to use.
|
* @return The <code>Growl</code> instance to use.
|
||||||
*/
|
*/
|
||||||
public static Growl getGrowlInstance(String appName) {
|
public static Growl getGrowlInstance(String appName) {
|
||||||
Growl instance = instances.get(appName);
|
synchronized (instances) {
|
||||||
|
Growl instance = instances.get(appName);
|
||||||
|
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
if (GROWL_LOADED) {
|
if (GROWL_LOADED) {
|
||||||
instance = new GrowlNative(appName);
|
instance = new GrowlNative(appName);
|
||||||
} else {
|
} else {
|
||||||
instance = new DummyGrowl();
|
instance = new DummyGrowl();
|
||||||
}
|
}
|
||||||
|
|
||||||
instances.put(appName, instance);
|
instances.put(appName, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets whether messages can be sent to Growl. If this returns
|
* Gets whether messages can be sent to Growl. If this returns
|
||||||
* <code>false</code> then {@link #getGrowlInstance(String)} will return a
|
* <code>false</code> then {@link #getGrowlInstance(String)} will return a
|
||||||
* dummy object.
|
* dummy object.
|
||||||
*
|
*
|
||||||
* @return <code>true</code> if messages can be sent to Growl.
|
* @return <code>true</code> if messages can be sent to Growl.
|
||||||
*/
|
*/
|
||||||
public static boolean isGrowlLoaded() {
|
public static boolean isGrowlLoaded() {
|
||||||
return GROWL_LOADED;
|
return GROWL_LOADED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple test class for Growl.
|
* Simple test class for Growl.
|
||||||
*
|
*
|
||||||
* @author Michael Stringer
|
* @author Michael Stringer
|
||||||
* @version 0.1
|
* @version 0.1
|
||||||
*/
|
*/
|
||||||
|
@ -55,132 +55,138 @@ public class TestGrowl extends JFrame {
|
||||||
private static final String APP_NAME = "Test Java App";
|
private static final String APP_NAME = "Test Java App";
|
||||||
private static final String NOTIF_3_CALLBACK = "Notif3";
|
private static final String NOTIF_3_CALLBACK = "Notif3";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Growl.
|
||||||
|
*/
|
||||||
public TestGrowl() {
|
public TestGrowl() {
|
||||||
super("Growl for Java");
|
super("Growl for Java");
|
||||||
setSize(320, 290);
|
setSize(320, 290);
|
||||||
|
|
||||||
buildComponents();
|
buildComponents();
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildComponents() {
|
private void buildComponents() {
|
||||||
getContentPane().setLayout(new GridLayout(6, 1));
|
getContentPane().setLayout(new GridLayout(6, 1));
|
||||||
|
|
||||||
Action action = new AbstractAction("Register") {
|
Action action = new AbstractAction("Register") {
|
||||||
public void actionPerformed(ActionEvent ae) {
|
public void actionPerformed(ActionEvent ae) {
|
||||||
try {
|
try {
|
||||||
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
|
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
|
||||||
|
|
||||||
growl.addNotification("Test Notification 1", true);
|
growl.addNotification("Test Notification 1", true);
|
||||||
growl.addNotification("Test Notification 2", false);
|
growl.addNotification("Test Notification 2", false);
|
||||||
growl.addNotification("Test Notification 3", true);
|
growl.addNotification("Test Notification 3", true);
|
||||||
|
|
||||||
GrowlCallbackListener listener = new GrowlCallbackListener() {
|
GrowlCallbackListener listener = new GrowlCallbackListener() {
|
||||||
public void notificationWasClicked(
|
public void notificationWasClicked(
|
||||||
final String clickContext) {
|
final String clickContext) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (NOTIF_3_CALLBACK.equals(clickContext)) {
|
if (NOTIF_3_CALLBACK.equals(clickContext)) {
|
||||||
JOptionPane
|
JOptionPane
|
||||||
.showMessageDialog(
|
.showMessageDialog(
|
||||||
TestGrowl.this,
|
TestGrowl.this,
|
||||||
"User clicked on 'Test Notification 3'");
|
"User clicked on 'Test Notification 3'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
growl.addCallbackListener(listener);
|
growl.addCallbackListener(listener);
|
||||||
growl.register();
|
growl.register();
|
||||||
} catch (GrowlException ge) {
|
} catch (GrowlException ge) {
|
||||||
ge.printStackTrace();
|
ge.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
getContentPane().add(new JButton(action));
|
getContentPane().add(new JButton(action));
|
||||||
|
|
||||||
action = new AbstractAction("Send 'Test Notification 1'") {
|
action = new AbstractAction("Send 'Test Notification 1'") {
|
||||||
public void actionPerformed(ActionEvent ae) {
|
public void actionPerformed(ActionEvent ae) {
|
||||||
try {
|
try {
|
||||||
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
|
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
|
||||||
|
|
||||||
growl.sendNotification("Test Notification 1",
|
growl.sendNotification("Test Notification 1",
|
||||||
"Test Notif 1", "This is a test");
|
"Test Notif 1", "This is a test");
|
||||||
} catch (GrowlException ge) {
|
} catch (GrowlException ge) {
|
||||||
ge.printStackTrace();
|
ge.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
getContentPane().add(new JButton(action));
|
getContentPane().add(new JButton(action));
|
||||||
|
|
||||||
action = new AbstractAction("Send 'Test Notification 2'") {
|
action = new AbstractAction("Send 'Test Notification 2'") {
|
||||||
public void actionPerformed(ActionEvent ae) {
|
public void actionPerformed(ActionEvent ae) {
|
||||||
try {
|
try {
|
||||||
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
|
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
|
||||||
BufferedImage image = ImageIO.read(TestGrowl.class
|
BufferedImage image = ImageIO.read(TestGrowl.class
|
||||||
.getResource("/images/duke.gif"));
|
.getResource("/images/duke.gif"));
|
||||||
growl.sendNotification("Test Notification 2",
|
growl.sendNotification("Test Notification 2",
|
||||||
"Test Notif 2", "This is another test", image);
|
"Test Notif 2", "This is another test", image);
|
||||||
} catch (GrowlException ge) {
|
} catch (GrowlException ge) {
|
||||||
ge.printStackTrace();
|
ge.printStackTrace();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// TODO Auto-generated catch block
|
e.printStackTrace();
|
||||||
e.printStackTrace();
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
getContentPane().add(new JButton(action));
|
||||||
getContentPane().add(new JButton(action));
|
|
||||||
|
|
||||||
action = new AbstractAction("Test Callback 'Notification 3'") {
|
action = new AbstractAction("Test Callback 'Notification 3'") {
|
||||||
public void actionPerformed(ActionEvent ae) {
|
public void actionPerformed(ActionEvent ae) {
|
||||||
try {
|
try {
|
||||||
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
|
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
|
||||||
|
|
||||||
growl.sendNotification("Test Notification 3",
|
growl.sendNotification("Test Notification 3",
|
||||||
"Callback Test", "Click me - I dares you!", NOTIF_3_CALLBACK);
|
"Callback Test", "Click me - I dares you!", NOTIF_3_CALLBACK);
|
||||||
} catch (GrowlException ge) {
|
} catch (GrowlException ge) {
|
||||||
ge.printStackTrace();
|
ge.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
getContentPane().add(new JButton(action));
|
getContentPane().add(new JButton(action));
|
||||||
|
|
||||||
action = new AbstractAction("Reg & Test App 2") {
|
action = new AbstractAction("Reg & Test App 2") {
|
||||||
public void actionPerformed(ActionEvent ae) {
|
public void actionPerformed(ActionEvent ae) {
|
||||||
try {
|
try {
|
||||||
Growl growl = GrowlUtils.getGrowlInstance("Other App");
|
Growl growl = GrowlUtils.getGrowlInstance("Other App");
|
||||||
|
|
||||||
growl.addNotification("A Notification", true);
|
growl.addNotification("A Notification", true);
|
||||||
|
|
||||||
BufferedImage image = ImageIO.read(TestGrowl.class
|
BufferedImage image = ImageIO.read(TestGrowl.class
|
||||||
.getResource("/images/duke.gif"));
|
.getResource("/images/duke.gif"));
|
||||||
growl.setIcon(image);
|
growl.setIcon(image);
|
||||||
|
|
||||||
growl.register();
|
growl.register();
|
||||||
growl.sendNotification("A Notification", "Testin",
|
growl.sendNotification("A Notification", "Testin",
|
||||||
"Blah de blah blah");
|
"Blah de blah blah");
|
||||||
} catch (GrowlException ge) {
|
} catch (GrowlException ge) {
|
||||||
ge.printStackTrace();
|
ge.printStackTrace();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// TODO Auto-generated catch block
|
e.printStackTrace();
|
||||||
e.printStackTrace();
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
getContentPane().add(new JButton(action));
|
||||||
getContentPane().add(new JButton(action));
|
|
||||||
|
|
||||||
action = new AbstractAction("Exit") {
|
action = new AbstractAction("Exit") {
|
||||||
public void actionPerformed(ActionEvent ae) {
|
public void actionPerformed(ActionEvent ae) {
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
getContentPane().add(new JButton(action));
|
getContentPane().add(new JButton(action));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final void main(String[] args) {
|
/**
|
||||||
new TestGrowl();
|
* Test growl.
|
||||||
|
* @param args args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
//noinspection ResultOfObjectAllocationIgnored
|
||||||
|
new TestGrowl();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue