swt-base notifier application; update java api

This commit is contained in:
Evgeny Gryaznov 2011-02-20 23:05:47 +01:00
parent de5717e2f2
commit a58c7774a0
13 changed files with 226 additions and 191 deletions

4
.gitignore vendored
View File

@ -1,3 +1,5 @@
bin
src/messenger/.idea/workspace.xml
src/.idea/workspace.xml
src/mibewjava/.idea/workspace.xml
src/mibewjava/org.mibew.notifier/resources/
mibew.ini

View File

@ -3,6 +3,9 @@
<component name="DependencyValidationManager">
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</component>
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="JavadocGenerationManager">
<option name="OUTPUT_DIRECTORY" />
<option name="OPTION_SCOPE" value="protected" />

View File

@ -11,7 +11,13 @@
<option name="PASS_PARENT_ENVS" value="true" />
<module name="org.mibew.notifier" />
<envs />
<RunnerSettings RunnerId="Debug">
<option name="DEBUG_PORT" value="50388" />
<option name="TRANSPORT" value="0" />
<option name="LOCAL" value="true" />
</RunnerSettings>
<RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Debug" />
<ConfigurationWrapper RunnerId="Run" />
<method />
</configuration>

View File

@ -43,7 +43,7 @@ public class MibewAgentOptions {
private static String getProperty(Properties p, String name, String defaultValue) throws IOException {
String result = p.getProperty(name);
if(result == null || result.trim().length() == 0) {
if(result == null) {
if(defaultValue != null) {
return defaultValue;
}

View File

@ -1,6 +1,5 @@
package org.mibew.api;
import java.text.MessageFormat;
/**
* @author inspirer
@ -120,7 +119,6 @@ public class MibewThread implements Comparable<MibewThread> {
fWaitingTime = value;
}
@Override
public int compareTo(MibewThread o) {
int res = index(this).compareTo(index(o));
if(res != 0) {

View File

@ -43,7 +43,7 @@ public class MibewTracker {
private void handleResponse(MibewResponse response, UpdateHandler handler) throws IOException {
if (handler.getResponse() == UpdateHandler.UPD_ERROR) {
throw new IOException("Update error: " + handler.getMessage());
} else if (handler.getResponse() == UpdateHandler.UPD_THREADS) {
} else if (handler.getResponse() == UpdateHandler.UPD_SUCCESS) {
fSince = handler.getRevision();
fLastUpdate = handler.getTime();
List<MibewThread> threads = handler.getThreads();

View File

@ -26,6 +26,4 @@ public class Utils {
}
return sb.toString();
}
}

View File

@ -15,7 +15,9 @@ import org.xml.sax.helpers.DefaultHandler;
public class UpdateHandler extends DefaultHandler {
public static final int UPD_ERROR = 1;
public static final int UPD_THREADS = 2;
public static final int UPD_SUCCESS = 2;
private static final int STATE_READING_THREADS = 1;
private int fResponse = 0;
private String fMessage = "";
@ -23,6 +25,8 @@ public class UpdateHandler extends DefaultHandler {
private long fTime;
private List<MibewThread> fUpdated;
private int state = 0;
private Stack<String> fPath = new Stack<String>();
private MibewThread fCurrentThread;
@ -33,27 +37,34 @@ public class UpdateHandler extends DefaultHandler {
if (fPath.size() == 0) {
if (name.equals("error")) {
fResponse = UPD_ERROR;
} else if (name.equals("threads")) {
fResponse = UPD_THREADS;
fTime = Long.parseLong(attributes.getValue("time"));
fRevision = Long.parseLong(attributes.getValue("revision"));
} else if (name.equals("update")) {
fResponse = UPD_SUCCESS;
} else {
throw new SAXException("unknown root element: " + name);
}
}
if (fResponse == UPD_THREADS && fPath.size() == 1
&& name.equals("thread")) {
long id = Long.parseLong(attributes.getValue("id"));
String stateid = attributes.getValue("stateid");
fCurrentThread = new MibewThread(id, stateid);
if(!stateid.equals("closed")) {
fCurrentThread.setStateText(attributes.getValue("state"));
fCurrentThread.setCanOpen(booleanAttribute(attributes.getValue("canopen")));
fCurrentThread.setCanView(booleanAttribute(attributes.getValue("canview")));
fCurrentThread.setCanBan(booleanAttribute(attributes.getValue("canban")));
} else if(fResponse == UPD_SUCCESS) {
if(fPath.size() == 1) {
if (name.equals("threads")) {
fTime = Long.parseLong(attributes.getValue("time"));
fRevision = Long.parseLong(attributes.getValue("revision"));
fUpdated = new ArrayList<MibewThread>();
state = STATE_READING_THREADS;
}
/* ignore others for compatibility reasons */
}
if (fPath.size() == 2 && state == STATE_READING_THREADS && name.equals("thread")) {
long id = Long.parseLong(attributes.getValue("id"));
String stateid = attributes.getValue("stateid");
fCurrentThread = new MibewThread(id, stateid);
if(!stateid.equals("closed")) {
fCurrentThread.setStateText(attributes.getValue("state"));
fCurrentThread.setCanOpen(booleanAttribute(attributes.getValue("canopen")));
fCurrentThread.setCanView(booleanAttribute(attributes.getValue("canview")));
fCurrentThread.setCanBan(booleanAttribute(attributes.getValue("canban")));
}
}
}
} catch (NumberFormatException ex) {
throw new SAXException(ex.getMessage());
@ -80,13 +91,11 @@ public class UpdateHandler extends DefaultHandler {
public void endElement(String uri, String localName, String name)
throws SAXException {
fPath.pop();
if (fResponse == UPD_THREADS && fPath.size() == 1
&& name.equals("thread")) {
if(fUpdated == null) {
fUpdated = new ArrayList<MibewThread>();
}
if (fResponse == UPD_SUCCESS && fPath.size() == 2 && state == STATE_READING_THREADS && name.equals("thread")) {
fUpdated.add(fCurrentThread);
fCurrentThread = null;
} else if(fPath.size() == 1 && state == STATE_READING_THREADS) {
state = 0;
}
}
@ -99,8 +108,8 @@ public class UpdateHandler extends DefaultHandler {
throw new SAXException("unexpected characters");
}
fMessage += new String(ch, start, length);
} else if (fResponse == UPD_THREADS) {
if(fCurrentThread == null || fPath.size() != 3) {
} else if (fResponse == UPD_SUCCESS && fCurrentThread != null) {
if(fCurrentThread == null || fPath.size() != 4) {
throw new SAXException("unknown characters");
}

View File

@ -2,4 +2,4 @@
mibew.host=http://localhost:8080/webim/
mibew.login=admin
mibew.password=1
mibew.password=

View File

@ -0,0 +1,140 @@
package org.mibew.notifier;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.mibew.api.MibewAgent;
import org.mibew.api.MibewAgentListener;
import org.mibew.api.MibewThread;
import java.awt.*;
import java.io.IOException;
public class MibewTray extends MibewAgentListener {
private volatile boolean isStopped = false;
private Image fImageOn;
private Image fImageOff;
private TrayItem fItem;
private Menu fMenu;
private MibewAgent fAgent;
void initTray(Display display, Shell shell, MibewAgent agent) {
fAgent = agent;
fImageOn = new Image(display, getClass().getClassLoader().getResourceAsStream("org/mibew/notifier/tray_on.png"));
fImageOff = new Image(display, getClass().getClassLoader().getResourceAsStream("org/mibew/notifier/tray_off.png"));
final Tray tray = display.getSystemTray();
if (tray == null) {
System.out.println("The system tray is not available");
} else {
fItem = new TrayItem(tray, SWT.NONE);
fItem.setToolTipText("SWT TrayItem");
fItem.addListener(SWT.Show, new Listener() {
public void handleEvent(Event event) {
System.out.println("show");
}
});
fItem.addListener(SWT.Hide, new Listener() {
public void handleEvent(Event event) {
System.out.println("hide");
}
});
fMenu = new Menu(shell, SWT.POP_UP);
for (int i = 0; i < 8; i++) {
MenuItem mi = new MenuItem(fMenu, SWT.PUSH);
mi.setText("Item" + i);
mi.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
System.out.println("selection " + event.widget);
}
});
}
Listener listener = new Listener() {
public void handleEvent(Event event) {
fMenu.setVisible(true);
}
};
fItem.addListener(SWT.MenuDetect, listener);
fItem.addListener(SWT.Selection, listener);
fItem.setImage(fImageOff);
}
shell.setBounds(50, 50, 300, 200);
//shell.open();
}
@Override
protected synchronized void onlineStateChanged(final boolean isOnline) {
if(isStopped)
return;
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if(isStopped)
return;
fItem.setImage(isOnline ? fImageOn : fImageOff);
}
});
}
@Override
protected synchronized void updated(final MibewThread[] all, final MibewThread[] created) {
if(isStopped)
return;
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if(isStopped)
return;
for (MenuItem menuItem : fMenu.getItems()) {
menuItem.dispose();
}
for(MibewThread m : all) {
MenuItem mi = new MenuItem(fMenu, SWT.PUSH);
mi.setText(m.getClientName());
mi.addListener(SWT.Selection, new LinkActionListener(null, fAgent.getOptions().getUrl() + "operator/agent.php?thread=" + m.getId()));
}
if(created.length == 1) {
fItem.setToolTipText(created[0].getClientName() + "\n" + created[0].getFirstMessage());
} else if(created.length > 1) {
fItem.setToolTipText("New " + created.length + " visitors");
}
}
});
}
synchronized void dispose() {
isStopped = true;
fItem.dispose();
fImageOn.dispose();
fImageOff.dispose();
}
private static class LinkActionListener implements Listener {
private final Shell shell;
private final String link;
public LinkActionListener(Shell shell, String link) {
this.shell = shell;
this.link = link;
}
public void handleEvent(Event event) {
try {
BrowserUtil.openURL(link);
} catch (IOException e1) {
MessageBox messageBox = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR);
messageBox.setText("Browser error"); //$NON-NLS-1$
messageBox.setMessage(e1.getMessage());
messageBox.open();
}
}
}}

View File

@ -1,22 +1,34 @@
package org.mibew.notifier;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.mibew.api.MibewAgent;
import org.mibew.notifier.Options.JOptions;
public class NotifyApp {
public static void main(String[] args) {
Options options = new JOptions(args);
if(!options.load()) {
Display display = new Display();
Shell shell = new Shell(display);
Options options = new JOptions(shell, args);
if (!options.load()) {
return;
}
TrayNotifier tn = new TrayNotifier();
tn.init();
MibewAgent agent = new MibewAgent(options.getAgentOptions(), tn);
MibewTray tray = new MibewTray();
MibewAgent agent = new MibewAgent(options.getAgentOptions(), tray);
agent.launch();
tn.setAgent(agent);
tray.initTray(display, shell, agent);
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
tray.dispose();
agent.stop();
display.dispose();
System.exit(0);
}
}

View File

@ -1,13 +1,14 @@
package org.mibew.notifier;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.mibew.api.MibewAgentOptions;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import javax.swing.JOptionPane;
import org.mibew.api.MibewAgentOptions;
public class Options {
private MibewAgentOptions agentOptions;
@ -43,13 +44,19 @@ public class Options {
public static class JOptions extends Options {
public JOptions(String[] args) {
private final Shell fShell;
public JOptions(Shell shell, String[] args) {
super(args);
}
fShell = shell;
}
@Override
protected void handleError(String message) {
JOptionPane.showMessageDialog(null, message);
protected void handleError(final String message) {
MessageBox messageBox = new MessageBox(fShell, SWT.OK | SWT.ICON_ERROR);
messageBox.setText("Options error"); //$NON-NLS-1$
messageBox.setMessage(message);
messageBox.open();
}
}
}

View File

@ -1,140 +0,0 @@
package org.mibew.notifier;
import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.MenuShortcut;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.TrayIcon.MessageType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import javax.swing.JOptionPane;
import org.mibew.api.MibewAgent;
import org.mibew.api.MibewAgentListener;
import org.mibew.api.MibewThread;
public class TrayNotifier extends MibewAgentListener {
private TrayIcon trayIcon;
private MibewAgent agent;
private Image online;
private Image offline;
private ActionListener fExit;
public TrayNotifier() {
}
public void init() {
if (SystemTray.isSupported()) {
SystemTray tray = SystemTray.getSystemTray();
online = Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("tray_on.png"));
offline = Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("tray_off.png"));
fExit = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(agent != null) {
agent.stop();
}
System.exit(0);
}
};
PopupMenu pm = new PopupMenu();
MenuItem exitItem = new MenuItem("Exit", new MenuShortcut(KeyEvent.VK_X));
exitItem.addActionListener(fExit);
pm.add(exitItem);
trayIcon = new TrayIcon(offline, "Mibew Notifier", pm);
trayIcon.setImageAutoSize(true);
try {
tray.add(trayIcon);
} catch (AWTException e) {
System.err.println("TrayIcon could not be added.");
System.exit(1);
}
} else {
System.err.println("TrayIcon could not be added.");
System.exit(1);
}
}
@Override
protected void onlineStateChanged(boolean isOnline) {
trayIcon.setImage(isOnline ? online : offline);
}
@Override
protected void updated(MibewThread[] all, final MibewThread[] created) {
Arrays.sort(all);
final PopupMenu pm = new PopupMenu();
boolean beforeChat = false;
for(MibewThread mt : all) {
boolean isChat = "chat".equals(mt.getState());
if(beforeChat && isChat) {
pm.addSeparator();
}
MenuItem mi = new MenuItem(mt.toString());
mi.addActionListener(new LinkActionListener(agent.getOptions().getUrl() + "operator/agent.php?thread=" + mt.getId()));
pm.add(mi);
beforeChat = !isChat;
}
if(all.length > 0) {
pm.addSeparator();
}
MenuItem exitItem = new MenuItem("Exit", new MenuShortcut(KeyEvent.VK_X));
exitItem.addActionListener(fExit);
pm.add(exitItem);
try {
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
trayIcon.setPopupMenu(pm);
if(created.length == 1) {
trayIcon.displayMessage("New visitor", created[0].getClientName() + "\n" + created[0].getFirstMessage(), MessageType.INFO);
} else if(created.length > 1) {
trayIcon.displayMessage("New visitors", "New " + created.length + " visitors", MessageType.INFO);
}
}
});
} catch (InterruptedException e) {
/* skip cycle */
} catch (InvocationTargetException e) {
/* hmm */
}
}
public void setAgent(MibewAgent agent) {
this.agent = agent;
}
private static class LinkActionListener implements ActionListener {
String link;
public LinkActionListener(String link) {
this.link = link;
}
@Override
public void actionPerformed(ActionEvent e) {
try {
BrowserUtil.openURL(link);
} catch (IOException e1) {
JOptionPane.showMessageDialog(null, e1.getMessage());
}
}
}
}