diff --git a/ch.psi.imagej.zeromq/pom.xml b/ch.psi.imagej.zeromq/pom.xml
index a766865..0647484 100644
--- a/ch.psi.imagej.zeromq/pom.xml
+++ b/ch.psi.imagej.zeromq/pom.xml
@@ -3,7 +3,7 @@
4.0.0
ch.psi
ch.psi.imagej.zeromq
- 0.0.1-SNAPSHOT
+ 0.0.3-SNAPSHOT
diff --git a/ch.psi.imagej.zeromq/src/main/java/ch/psi/imagej/zeromq/ZeroMQViewer.java b/ch.psi.imagej.zeromq/src/main/java/ch/psi/imagej/zeromq/ZeroMQViewer.java
index e069bb1..652953a 100644
--- a/ch.psi.imagej.zeromq/src/main/java/ch/psi/imagej/zeromq/ZeroMQViewer.java
+++ b/ch.psi.imagej.zeromq/src/main/java/ch/psi/imagej/zeromq/ZeroMQViewer.java
@@ -1,4 +1,5 @@
package ch.psi.imagej.zeromq;
+
// EPICS_AD_Viewer.java
// Original authors
// Tim Madden, APS
@@ -11,12 +12,12 @@ import ij.plugin.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.awt.event.*;
+import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.Timer;
-import javax.swing.border.*;
import org.jeromq.ZMQ;
@@ -34,48 +35,92 @@ public class ZeroMQViewer implements PlugIn {
private int numImageUpdates;
private JFrame frame;
- private JTextField fpsText;
+ // private JLabel fpsText;
- private boolean isPluginRunning;
+ private volatile boolean isPluginRunning;
+ private volatile boolean collect;
private Timer timer;
private ZMQ.Context context;
private ZMQ.Socket socket;
+ private JPanel panel_1;
+ private JLabel lblNewLabel;
+ private JLabel labelFrameRate;
+ private JTextField textHostname;
+ private JLabel lblHostname;
+ private JLabel lblPort;
+ private JTextField textPort;
+ private JButton btnStart;
+
+ private Semaphore semaphore = new Semaphore(1);
+ private JLabel lblMethod;
+ private JComboBox comboBoxMethod;
+
public void run(String arg) {
IJ.showStatus("Running ZeroMQ Viewer");
try {
isPluginRunning = true;
-
+
prevTime = System.currentTimeMillis();
numImageUpdates = 0;
-
+ semaphore.acquire(); // block semaphore
+
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
- context = ZMQ.context(1);
- socket = context.socket(ZMQ.PULL);
- socket.bind("tcp://*:8080");
-
+
while (isPluginRunning) {
- byte[] message = socket.recv();
- byte[] content = null;
- if (socket.hasReceiveMore()) {
- content = socket.recv();
+ semaphore.acquire();
+ collect=true;
+ try{
+ if(img!=null){
+ img.close();
+ img=null;
+ }
+ String hostname = textHostname.getText();
+ int port = Integer.parseInt(textPort.getText());
+ String method = (String) comboBoxMethod.getSelectedItem();
+
+
+ context = ZMQ.context(1);
+ if(method.equals("PULL")){
+ socket = context.socket(ZMQ.PULL);
+ }
+ else if(method.equals("SUB")){
+ socket = context.socket(ZMQ.SUB);
+ }
+ else{
+ logger.severe("Method not supported");
+ collect=false;
+ }
+ socket.connect("tcp://"+hostname+":"+port);
+
+ while(collect){
+ byte[] message = socket.recv();
+ byte[] content = null;
+ if (socket.hasReceiveMore()) {
+ content = socket.recv();
+ }
+ logger.info(new String(message));
+ updateImage(content);
+ }
+
+ socket.close();
+ context.term();
+ }
+ catch(Exception e){
+ logger.log(Level.SEVERE, "",e);
+ btnStart.setText("Start");
}
- logger.info(new String(message));
- updateImage(content);
}
timer.stop();
- socket.close();
- context.term();
-
img.close();
frame.setVisible(false);
@@ -89,14 +134,14 @@ public class ZeroMQViewer implements PlugIn {
public void updateImage(byte[] content) {
try {
- if(img==null){
+ if (img == null) {
// TODO eventually use ByteProcessor or BinaryProcessor
// BinaryProcessor p = new ij.process.BinaryProcessor(new
// ByteProcessor(imageSizeX, imageSizeY));
img = new ImagePlus("", new ShortProcessor(imageSizeX, imageSizeY));
img.show();
}
-
+
// TODO Check whether this is needed
short[] shorts = new short[content.length / 2];
ByteBuffer.wrap(content).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
@@ -112,46 +157,133 @@ public class ZeroMQViewer implements PlugIn {
/**
* Create the GUI and show it. For thread safety, this method should be
* invoked from the event-dispatching thread.
+ *
+ * @wbp.parser.entryPoint
*/
public void createAndShowGUI() {
- fpsText = new JTextField(6);
- fpsText.setEditable(false);
- fpsText.setHorizontalAlignment(JTextField.CENTER);
frame = new JFrame("ZeroMQ_Viewer Plugin");
- JPanel panel = new JPanel(new BorderLayout());
- panel.setLayout(new GridBagLayout());
- panel.setBorder(new EmptyBorder(new Insets(5, 5, 5, 5)));
- frame.getContentPane().add(BorderLayout.CENTER, panel);
- GridBagConstraints c = new GridBagConstraints();
- // Add extra space around each component to avoid clutter
- c.insets = new Insets(2, 2, 2, 2);
+ panel_1 = new JPanel();
+ GridBagConstraints gbc_panel_1 = new GridBagConstraints();
+ gbc_panel_1.fill = GridBagConstraints.BOTH;
+ gbc_panel_1.gridx = 0;
+ gbc_panel_1.gridy = 1;
+ frame.getContentPane().add(panel_1, BorderLayout.CENTER);
+ GridBagLayout gbl_panel_1 = new GridBagLayout();
+ gbl_panel_1.columnWidths = new int[] { 0, 0, 0 };
+ gbl_panel_1.rowHeights = new int[] { 0, 0, 0, 0, 0, 0 };
+ gbl_panel_1.columnWeights = new double[] { 0.0, 1.0, Double.MIN_VALUE };
+ gbl_panel_1.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE };
+ panel_1.setLayout(gbl_panel_1);
- // Top row
- // Anchor all components CENTER
- c.anchor = GridBagConstraints.CENTER;
- c.gridx = 0;
- c.gridy = 0;
- panel.add(new JLabel("Frames/s"), c);
+ lblHostname = new JLabel("Hostname");
+ GridBagConstraints gbc_lblHostname = new GridBagConstraints();
+ gbc_lblHostname.insets = new Insets(0, 0, 5, 5);
+ gbc_lblHostname.anchor = GridBagConstraints.EAST;
+ gbc_lblHostname.gridx = 0;
+ gbc_lblHostname.gridy = 0;
+ panel_1.add(lblHostname, gbc_lblHostname);
- // Middle row
- // These widgets should be centered
- c.anchor = GridBagConstraints.CENTER;
- c.gridy = 1;
- c.gridx = 0;
- panel.add(fpsText, c);
+ textHostname = new JTextField();
+ GridBagConstraints gbc_textHostname = new GridBagConstraints();
+ gbc_textHostname.insets = new Insets(0, 0, 5, 0);
+ gbc_textHostname.fill = GridBagConstraints.HORIZONTAL;
+ gbc_textHostname.gridx = 1;
+ gbc_textHostname.gridy = 0;
+ panel_1.add(textHostname, gbc_textHostname);
+ textHostname.setColumns(10);
+
+ lblPort = new JLabel("Port");
+ GridBagConstraints gbc_lblPort = new GridBagConstraints();
+ gbc_lblPort.anchor = GridBagConstraints.EAST;
+ gbc_lblPort.insets = new Insets(0, 0, 5, 5);
+ gbc_lblPort.gridx = 0;
+ gbc_lblPort.gridy = 1;
+ panel_1.add(lblPort, gbc_lblPort);
+
+ textPort = new JTextField();
+ GridBagConstraints gbc_textPort = new GridBagConstraints();
+ gbc_textPort.insets = new Insets(0, 0, 5, 0);
+ gbc_textPort.fill = GridBagConstraints.HORIZONTAL;
+ gbc_textPort.gridx = 1;
+ gbc_textPort.gridy = 1;
+ panel_1.add(textPort, gbc_textPort);
+ textPort.setColumns(10);
+
+ lblMethod = new JLabel("Method");
+ GridBagConstraints gbc_lblMethod = new GridBagConstraints();
+ gbc_lblMethod.anchor = GridBagConstraints.EAST;
+ gbc_lblMethod.insets = new Insets(0, 0, 5, 5);
+ gbc_lblMethod.gridx = 0;
+ gbc_lblMethod.gridy = 2;
+ panel_1.add(lblMethod, gbc_lblMethod);
+
+ comboBoxMethod = new JComboBox();
+ comboBoxMethod.setModel(new DefaultComboBoxModel(new String[] {"PULL", "SUB"}));
+ comboBoxMethod.setSelectedIndex(0);
+ GridBagConstraints gbc_comboBoxMethod = new GridBagConstraints();
+ gbc_comboBoxMethod.insets = new Insets(0, 0, 5, 0);
+ gbc_comboBoxMethod.fill = GridBagConstraints.HORIZONTAL;
+ gbc_comboBoxMethod.gridx = 1;
+ gbc_comboBoxMethod.gridy = 2;
+ panel_1.add(comboBoxMethod, gbc_comboBoxMethod);
+
+ lblNewLabel = new JLabel("Frame/s");
+ GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
+ gbc_lblNewLabel.anchor = GridBagConstraints.EAST;
+ gbc_lblNewLabel.insets = new Insets(0, 0, 5, 5);
+ gbc_lblNewLabel.gridx = 0;
+ gbc_lblNewLabel.gridy = 3;
+ panel_1.add(lblNewLabel, gbc_lblNewLabel);
+
+ labelFrameRate = new JLabel("0.0");
+ GridBagConstraints gbc_labelFrameRate = new GridBagConstraints();
+ gbc_labelFrameRate.anchor = GridBagConstraints.EAST;
+ gbc_labelFrameRate.insets = new Insets(0, 0, 5, 0);
+ gbc_labelFrameRate.gridx = 1;
+ gbc_labelFrameRate.gridy = 3;
+ panel_1.add(labelFrameRate, gbc_labelFrameRate);
+
+ btnStart = new JButton("Start");
+ btnStart.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if(btnStart.getText().equals("Start")){
+ // Start data acquisition
+ semaphore.release();
+ btnStart.setText("Stop");
+ }
+ else{
+ // Stop data acquisition
+ collect = false;
+ try{
+ socket.notifyAll();
+ }
+ catch(Exception ex){
+ // This exception can savely be ignored (somewhat most of the time an exception is expected)
+ }
+ btnStart.setText("Start");
+ }
+ }
+ });
+ GridBagConstraints gbc_btnStart = new GridBagConstraints();
+ gbc_btnStart.anchor = GridBagConstraints.WEST;
+ gbc_btnStart.gridx = 1;
+ gbc_btnStart.gridy = 4;
+ panel_1.add(btnStart, gbc_btnStart);
// Display the window.
frame.pack();
frame.addWindowListener(new FrameExitListener());
frame.setVisible(true);
+
+ // Update frame rate
int timerDelay = 2000; // 2 seconds
timer = new Timer(timerDelay, new ActionListener() {
public void actionPerformed(ActionEvent event) {
long time = System.currentTimeMillis();
double fps = 1000. * numImageUpdates / (double) (time - prevTime);
- fpsText.setText(String.format("%.1f", fps));
+ labelFrameRate.setText(String.format("%.1f", fps));
prevTime = time;
numImageUpdates = 0;
}