cleaned up the code

changed GUI layout to respect current desktop layout for SDI capture
added temperature offset controls
This commit is contained in:
Lucas Pleß 2014-11-21 03:50:27 +01:00
parent 9c0c7a0fdc
commit ac890076b4
18 changed files with 383 additions and 348 deletions

View File

@ -131,6 +131,9 @@
<item class="de.psychose.ActorDisplay" icon="" removable="true" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="0" />
</item>
<item class="de.psychose.TemperatureControl" icon="" removable="true" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="0" />
</item>
</group>
</component>
</project>

View File

@ -1,5 +1,10 @@
you need jdk 1.7 or newer and maven2 installed
compile with
mvn clean compile ideauidesigner:javac2 assembly:single
run with
java -jar psychose-X.X-jar-with-dependencies.jar

View File

@ -6,34 +6,63 @@ package de.psychose;
*/
public class ActorData {
private String actor = "";
private String caption = "";
private PulseData pulseData = new PulseData();
private int airflow;
private int ekg;
private int emg;
private float temperature;
private double temperature;
private double temperatureOffset;
private boolean tommyHeartbeat;
private long timestampPulse = 0;
private long timestampTommyPulse = 0;
private long timestampHeartbeat = 0;
private long timestampOxygen = 0;
private long timestampTommyHeartbeat = 0;
private long timestampEkg = 0;
private long timestampEmg = 0;
private long timestampTemperature = 0;
private long timestampBreath = 0;
// TODO: hier die timestamps setzen wann letztes mal geändert,
// dann kann ich in ActorDisplay im Timer einfach prüfen ob differenz > timeout, dann rot setzen
public void setTimestampPulse() {
this.timestampPulse = System.currentTimeMillis();
}
public PulseData getPulseData() {
return pulseData;
public ActorData(String actor, String caption) {
this.actor = actor;
this.caption = caption;
}
public void setPulseData(PulseData pulseData) {
this.pulseData = pulseData;
this.timestampPulse = System.currentTimeMillis();
public String getActor() {
return actor;
}
public String getCaption() {
return caption;
}
public int getOxygen() {
return pulseData.getOxygen();
}
public void setOxygen(int oxygen) {
timestampOxygen = System.currentTimeMillis();
pulseData.setOxygen(oxygen);
}
public boolean getHeartbeat() {
return pulseData.getHeartbeat();
}
public void setHeartbeat(boolean heartbeat) {
timestampHeartbeat = System.currentTimeMillis();
pulseData.setHeartbeat(heartbeat);
}
public int getPulse() {
return pulseData.getPulse();
}
public void setPulse(int pulse) {
timestampPulse = System.currentTimeMillis();
pulseData.setPulse(pulse);
}
public int getAirflow() {
@ -63,11 +92,11 @@ public class ActorData {
this.timestampEmg = System.currentTimeMillis();
}
public float getTemperature() {
public double getTemperature() {
return temperature;
}
public void setTemperature(float temperature) {
public void setTemperature(double temperature) {
this.temperature = temperature;
this.timestampTemperature = System.currentTimeMillis();
}
@ -78,7 +107,15 @@ public class ActorData {
public void setTommyHeartbeat(boolean tommyHeartbeat) {
this.tommyHeartbeat = tommyHeartbeat;
this.timestampTommyPulse = System.currentTimeMillis();
this.timestampTommyHeartbeat = System.currentTimeMillis();
}
public double getTemperatureOffset() {
return temperatureOffset;
}
public void setTemperatureOffset(double temperatureOffset) {
this.temperatureOffset = temperatureOffset;
}
public long getTimestampPulse() {
@ -100,4 +137,26 @@ public class ActorData {
public long getTimestampBreath() {
return timestampBreath;
}
@Override
public String toString() {
return "ActorData{" +
"actor='" + actor + '\'' +
", caption='" + caption + '\'' +
", airflow=" + airflow +
", ekg=" + ekg +
", emg=" + emg +
", temperature=" + temperature +
", temperatureOffset=" + temperatureOffset +
", tommyHeartbeat=" + tommyHeartbeat +
", timestampPulse=" + timestampPulse +
", timestampHeartbeat=" + timestampHeartbeat +
", timestampOxygen=" + timestampOxygen +
", timestampTommyHeartbeat=" + timestampTommyHeartbeat +
", timestampEkg=" + timestampEkg +
", timestampEmg=" + timestampEmg +
", timestampTemperature=" + timestampTemperature +
", timestampBreath=" + timestampBreath +
'}';
}
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="de.psychose.ActorDisplay">
<grid id="27dc6" binding="actorPanel" layout-manager="GridLayoutManager" row-count="9" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="9" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="4" left="6" bottom="4" right="6"/>
<constraints>
<xy x="20" y="20" width="316" height="302"/>

View File

@ -2,7 +2,6 @@ package de.psychose;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.text.DecimalFormat;
/**
@ -10,11 +9,7 @@ import java.text.DecimalFormat;
* @date: 14.04.14 21:44
*/
public class ActorDisplay {
private final Timer timer;
private final static Color onColor = Color.WHITE;
private final static Color offColor = Color.RED;
private final static String offText = "no data";
private static final long TIMEOUT_MILLISECONDS = 2000;
private JLabel lblCaption;
private JLabel lblHeartbeat;
private JLabel lblPulse;
@ -23,98 +18,49 @@ public class ActorDisplay {
private JLabel lblEmg;
private JLabel lblTemperature;
private JLabel lblBreath;
private JPanel actorPanel;
private JPanel mainPanel;
private ActorData actorData;
private boolean showErrors = false;
private DecimalFormat df = new DecimalFormat("#.0");
//TODO: die einzelnen Setter wegmachen, dafür eine setData() bauen die die daten en bloc nimmt
// die darin enthaltenen timestamps dann für rotfärbung nehmen
public void setActorData(ActorData actorData) {
this.actorData = actorData;
}
public void setCaption(String caption) {
lblCaption.setText(caption);
}
public void update() {
if (actorData == null) {
return;
}
lblBreath.setText(String.valueOf(actorData.getAirflow()));
lblTemperature.setText(df.format(actorData.getTemperature()));
lblTemperature.setText(df.format(actorData.getTemperature() + actorData.getTemperatureOffset()));
lblEkg.setText(String.valueOf(actorData.getEkg()));
lblPulse.setText(actorData.getPulseData().getHeartbeat() == 0 ? "systole" : "diastole");
lblPulse.setText(actorData.getHeartbeat() ? "systole" : "diastole");
lblEmg.setText(String.valueOf(actorData.getEmg()));
lblOxy.setText(String.valueOf(actorData.getPulseData().getOxygen()));
lblHeartbeat.setText(String.valueOf(actorData.getPulseData().getPulse()));
lblOxy.setText(String.valueOf(actorData.getOxygen()));
lblHeartbeat.setText(String.valueOf(actorData.getPulse()));
if (showErrors) {
checkTimeout(lblTemperature, actorData.getTimestampTemperature());
checkTimeout(lblPulse, actorData.getTimestampPulse());
checkTimeout(lblOxy, actorData.getTimestampPulse());
checkTimeout(lblHeartbeat, actorData.getTimestampPulse());
checkTimeout(lblEkg, actorData.getTimestampEkg());
checkTimeout(lblEmg, actorData.getTimestampEmg());
checkTimeout(lblBreath, actorData.getTimestampBreath());
}
}
public ActorDisplay() {
this.timer = new Timer(100, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if (actorData == null)
return;
update();
if (showErrors) {
long timeout = System.currentTimeMillis() - 1000;
if (actorData.getTimestampTemperature() < timeout) {
lblTemperature.setForeground(offColor);
lblTemperature.setText(offText);
} else {
lblTemperature.setForeground(onColor);
}
if (actorData.getTimestampPulse() < timeout) {
lblPulse.setForeground(offColor);
lblPulse.setText(offText);
lblOxy.setForeground(offColor);
lblOxy.setText(offText);
lblHeartbeat.setForeground(offColor);
lblHeartbeat.setText(offText);
} else {
lblPulse.setForeground(onColor);
lblOxy.setForeground(onColor);
lblHeartbeat.setForeground(onColor);
}
if (actorData.getTimestampEkg() < timeout) {
lblEkg.setForeground(offColor);
lblEkg.setText(offText);
} else {
lblEkg.setForeground(onColor);
}
if (actorData.getTimestampEmg() < timeout) {
lblEmg.setForeground(offColor);
lblEmg.setText(offText);
} else {
lblEmg.setForeground(onColor);
}
if (actorData.getTimestampBreath() < timeout) {
lblBreath.setForeground(offColor);
lblBreath.setText(offText);
} else {
lblBreath.setForeground(onColor);
}
}
}
});
timer.setRepeats(true);
timer.start();
}
public void setShowErrors(boolean showErrors) {
public void init(ActorData actorData, final boolean showErrors) {
this.actorData = actorData;
lblCaption.setText(actorData.getCaption());
this.showErrors = showErrors;
}
private void checkTimeout(final JLabel label, final long time) {
if (time < System.currentTimeMillis() - TIMEOUT_MILLISECONDS) {
label.setText("no data");
label.setForeground(Color.red);
} else {
label.setForeground(Color.white);
}
}
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="de.psychose.ActorHeart">
<grid id="27dc6" binding="heartPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
<grid id="27dc6" binding="mainPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
<xy x="20" y="20" width="789" height="299"/>
</constraints>

View File

@ -3,7 +3,6 @@ package de.psychose;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
@ -12,33 +11,21 @@ import java.io.IOException;
* @date: 15.11.14 21:36
*/
public class ActorHeart {
private JPanel heartPanel;
private ActorData actorData1;
private ActorData actorData2;
private ActorData actorData3;
private JPanel mainPanel;
private ActorData[] actorDatas;
private ImagePanel imagePanel;
private Timer timer;
public ActorHeart() {
imagePanel = new ImagePanel("/de/psychose/heart1_klein_inv.jpg", "/de/psychose/heart2_klein_inv.jpg");
heartPanel.add(imagePanel);
timer = new Timer(100, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if(actorData1 != null && actorData2 != null && actorData3 != null) {
imagePanel.repaint();
}
}
});
timer.setRepeats(true);
timer.start();
mainPanel.add(imagePanel);
}
public void setActorData(final ActorData actorData1, final ActorData actorData2, final ActorData actorData3) {
this.actorData1 = actorData1;
this.actorData2 = actorData2;
this.actorData3 = actorData3;
public void update() {
imagePanel.repaint();
}
public void setActorDatas(final ActorData[] actorDatas) {
this.actorDatas = actorDatas;
}
private class ImagePanel extends JPanel {
@ -57,10 +44,13 @@ public class ActorHeart {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if(actorData1 != null && actorData2 != null && actorData3 != null) {
g.drawImage(ActorHeart.this.actorData1.getTommyHeartbeat() ? image1 : image2, 0, 0, null, null);
g.drawImage(ActorHeart.this.actorData2.getTommyHeartbeat() ? image1 : image2, 263, 0, null, null);
g.drawImage(ActorHeart.this.actorData3.getTommyHeartbeat() ? image1 : image2, 526, 0, null, null);
if (actorDatas != null) {
for (int i = 0; i < actorDatas.length; i++) {
if (actorDatas[i] != null) {
g.drawImage(actorDatas[i].getTommyHeartbeat() ? image1 : image2, 263 * i, 0, null, null);
}
}
}
}
}

View File

@ -45,21 +45,21 @@ public class ChaOSCclient {
return changeChaoscSubscription(true);
}
public void sendPulse(String actor, int heartbeat, int pulse, int oxygen) {
public void sendMessage(final String address, Object... args) {
try {
OSCMessage subscribeMessage = new OSCMessage("/" + actor + "/heartbeat");
subscribeMessage.addArgument(heartbeat);
subscribeMessage.addArgument(pulse);
subscribeMessage.addArgument(oxygen);
OSCMessage subscribeMessage = new OSCMessage(address);
for(Object param: args) {
subscribeMessage.addArgument(param);
}
portOut.send(subscribeMessage);
} catch (IOException e) {
System.out.println("could not send pulse OSC Message");
e.printStackTrace();
}
}
}
private boolean changeChaoscSubscription(boolean subscribe) {
try {

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="de.psychose.ControlForm">
<grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="rootPanel" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="10" bottom="10" right="10"/>
<constraints>
<xy x="20" y="20" width="704" height="400"/>
@ -25,15 +25,30 @@
</nested-form>
<nested-form id="c060f" form-file="de/psychose/ActorDisplay.form" binding="actor1">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
<nested-form id="abfde" form-file="de/psychose/ActorDisplay.form" binding="actor2">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
<nested-form id="97d21" form-file="de/psychose/ActorDisplay.form" binding="actor3">
<constraints>
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
<nested-form id="f7ec5" form-file="de/psychose/TemperatureControl.form" binding="temp1">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
<nested-form id="bcc93" form-file="de/psychose/TemperatureControl.form" binding="temp2">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
<nested-form id="3726f" form-file="de/psychose/TemperatureControl.form" binding="temp3">
<constraints>
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>

View File

@ -8,47 +8,61 @@ import java.util.Observer;
* @author: lucas
* @date: 15.11.14 22:23
*/
public class ControlForm {
public class ControlForm extends JFrame {
private PulseControl pulse1;
private PulseControl pulse2;
private PulseControl pulse3;
private JPanel mainPanel;
private JPanel rootPanel;
private ActorDisplay actor1;
private ActorDisplay actor2;
private ActorDisplay actor3;
private TemperatureControl temp1;
private TemperatureControl temp2;
private TemperatureControl temp3;
private final ChaOSCclient osCclient;
public JPanel getMainPanel() {
return mainPanel;
}
public ControlForm(ChaOSCclient chaOSCclient, final ActorData actorData1, final ActorData actorData2, final ActorData actorData3) {
public ControlForm(ChaOSCclient chaOSCclient, final ActorData[] actorData) {
super("HD Control");
this.osCclient = chaOSCclient;
addActor("merle", pulse1, actor1, actorData1);
addActor("uwe", pulse2, actor2, actorData2);
addActor("bjoern", pulse3, actor3, actorData3);
setContentPane(rootPanel);
setResizable(false);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
actor1.setShowErrors(true);
actor2.setShowErrors(true);
actor3.setShowErrors(true);
addActor(pulse1, actor1, temp1, actorData[0]);
addActor(pulse2, actor2, temp2, actorData[1]);
addActor(pulse3, actor3, temp3, actorData[2]);
pack();
setVisible(true);
}
private void addActor(final String actor, PulseControl pulse, ActorDisplay display, ActorData actorData) {
private void addActor(final PulseControl pulse, final ActorDisplay display, final TemperatureControl temp, final ActorData actorData) {
pulse.addObserver(new Observer() {
@Override
public void update(Observable o, Object arg) {
if(arg instanceof PulseData) {
final PulseData data = (PulseData)arg;
osCclient.sendPulse(actor, data.getHeartbeat(), data.getPulse(), data.getOxygen());
if (arg instanceof PulseData) {
final PulseData data = (PulseData) arg;
osCclient.sendMessage("/" + actorData.getActor().toLowerCase() + "/heartbeat", data.getHeartbeat(),
data.getPulse(), data.getOxygen());
// TODO: delete this line, bc tommy will send the real events
osCclient.sendMessage("/" + actorData.getActor().toLowerCase() + "/tommyheartbeat");
}
}
});
display.setCaption(actor);
display.setActorData(actorData);
temp.addObserver(new Observer() {
@Override
public void update(Observable o, Object arg) {
if (arg instanceof Double) {
actorData.setTemperatureOffset((double)arg);
}
}
});
display.init(actorData, true);
}
}

View File

@ -4,8 +4,6 @@ import com.illposed.osc.OSCListener;
import com.illposed.osc.OSCMessage;
import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Date;
@ -15,26 +13,17 @@ import java.util.Date;
* @date: 25.04.14 00:23
*/
public class Main {
private ChaOSCclient chaOSCclient;
private ControlForm controlForm;
private MainForm mainForm;
private int totalMessageCount = 0;
private int messagesTempCounter = 0;
private long totalTraffic = 0;
private long lastTraffic = 0;
private final ActorData actorData1 = new ActorData();
private final ActorData actorData2 = new ActorData();
private final ActorData actorData3 = new ActorData();
public static void main(String[] args) {
new Main();
}
public Main() {
final ActorData[] actorDatas = new ActorData[3];
actorDatas[0] = new ActorData("merle", "Körper 1");
actorDatas[1] = new ActorData("uwe", "Körper 2");
actorDatas[2] = new ActorData("bjoern", "Körper 3");
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
} catch (Exception e) {
@ -42,151 +31,99 @@ public class Main {
}
try {
this.chaOSCclient = new ChaOSCclient("chaosc", 7110);
this.controlForm = new ControlForm(chaOSCclient, actorData1, actorData2, actorData3);
final ChaOSCclient chaOSCclient = new ChaOSCclient("chaosc", 7110);
final JFrame cframe = new JFrame("HD Control");
cframe.setContentPane(controlForm.getMainPanel());
cframe.setResizable(false);
cframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
cframe.pack();
this.mainForm = new MainForm(actorData1, actorData2, actorData3);
final JFrame frame = new JFrame("HD Main");
frame.setContentPane(mainForm.getMainPanel());
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setUndecorated(true);
frame.pack();
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
chaOSCclient.stopReceiver();
// snmp.stopRunning();
super.windowClosing(e);
}
});
addActor("merle", actorData1);
addActor("uwe", actorData2);
addActor("bjoern", actorData3);
cframe.setVisible(true);
frame.setVisible(true);
for(int i = 0; i < actorDatas.length; i++) {
addActorOSCListeners(chaOSCclient, actorDatas[i]);
}
chaOSCclient.startReceiver();
new ControlForm(chaOSCclient, actorDatas);
new MainForm(actorDatas);
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
chaOSCclient.stopReceiver();
}
}));
} catch (UnknownHostException | SocketException e) {
e.printStackTrace();
}
}
private void addActor(final String actor, final ActorData actorData) {
private static void addActorOSCListeners(final ChaOSCclient chaOSCclient, final ActorData actorData) {
chaOSCclient.addListener("/" + actor.toLowerCase() + "/heartbeat", new OSCListener() {
chaOSCclient.addListener("/" + actorData.getActor().toLowerCase() + "/heartbeat", new OSCListener() {
@Override
public void acceptMessage(Date time, OSCMessage message) {
if (message.getArguments().length == 3) {
totalMessageCount++;
// set the beat ( 0 or 1 )
if (message.getArguments()[0] instanceof Integer) {
actorData.setHeartbeat( (int)(message.getArguments()[0]) == 1);
}
// set the heartrate
if (message.getArguments()[1] instanceof Integer) {
int pulse = (int) (message.getArguments()[1]);
if (pulse > 60) { // try to skip the invalid pulserate from device
// set the heartrate
actorData.getPulseData().setPulse((int) (message.getArguments()[1]));
// set the beat ( 0 or 1 )
if (message.getArguments()[0] instanceof Integer) {
actorData.getPulseData().setHeartbeat((int) (message.getArguments()[0]));
}
//TODO: remove this, its for testing without tommy only
actorData.setTommyHeartbeat(((int) message.getArguments()[0]) == 1);
// set the oxy level
if (message.getArguments()[2] instanceof Integer) {
actorData.getPulseData().setOxygen((int) (message.getArguments()[2]));
}
actorData.setTimestampPulse();
final int pulse = (int) (message.getArguments()[1]);
if (pulse > 60) { // try to skip the invalid pulse rate from device
actorData.setPulse(pulse);
}
}
}
}
});
chaOSCclient.addListener("/" + actor.toLowerCase() + "/ekg", new OSCListener() {
@Override
public void acceptMessage(Date time, OSCMessage message) {
if (message.getArguments().length == 1) {
totalMessageCount++;
if (message.getArguments()[0] instanceof Integer) {
actorData.setEkg((int) (message.getArguments()[0]));
// set the oxy level
if (message.getArguments()[2] instanceof Integer) {
actorData.setOxygen((int) (message.getArguments()[2]));
}
}
}
});
chaOSCclient.addListener("/" + actor.toLowerCase() + "/emg", new OSCListener() {
chaOSCclient.addListener("/" + actorData.getActor().toLowerCase() + "/ekg", new OSCListener() {
@Override
public void acceptMessage(Date time, OSCMessage message) {
if (message.getArguments().length == 1) {
totalMessageCount++;
if (message.getArguments()[0] instanceof Integer) {
actorData.setEmg((int) (message.getArguments()[0]));
}
if (message.getArguments().length == 1 && message.getArguments()[0] instanceof Integer) {
actorData.setEkg((int) (message.getArguments()[0]));
}
}
});
chaOSCclient.addListener("/" + actor.toLowerCase() + "/temperature", new OSCListener() {
chaOSCclient.addListener("/" + actorData.getActor().toLowerCase() + "/emg", new OSCListener() {
@Override
public void acceptMessage(Date time, OSCMessage message) {
if (message.getArguments().length == 1) {
totalMessageCount++;
if (message.getArguments()[0] instanceof Float) {
actorData.setTemperature((float) (message.getArguments()[0]));
}
if (message.getArguments().length == 1 && message.getArguments()[0] instanceof Integer) {
actorData.setEmg((int) (message.getArguments()[0]));
}
}
});
chaOSCclient.addListener("/" + actor.toLowerCase() + "/airFlow", new OSCListener() {
chaOSCclient.addListener("/" + actorData.getActor().toLowerCase() + "/temperature", new OSCListener() {
@Override
public void acceptMessage(Date time, OSCMessage message) {
if (message.getArguments().length == 1) {
totalMessageCount++;
if (message.getArguments()[0] instanceof Integer) {
actorData.setAirflow((int) (message.getArguments()[0]));
}
if (message.getArguments().length == 1 && message.getArguments()[0] instanceof Float) {
actorData.setTemperature((float) (message.getArguments()[0]));
}
}
});
chaOSCclient.addListener("/" + actor.toLowerCase() + "/tommypuls", new OSCListener() {
chaOSCclient.addListener("/" + actorData.getActor().toLowerCase() + "/airFlow", new OSCListener() {
@Override
public void acceptMessage(Date time, OSCMessage message) {
if (message.getArguments().length == 1) {
totalMessageCount++;
if (message.getArguments()[0] instanceof Integer) {
actorData.setTommyHeartbeat((boolean) (message.getArguments()[0]));
}
//TODO: evtl muss das oben hier noch anders
if (message.getArguments().length == 1 && message.getArguments()[0] instanceof Integer) {
actorData.setAirflow((int) (message.getArguments()[0]));
}
}
});
//TODO: evtl muss das oben hier noch anders
chaOSCclient.addListener("/" + actorData.getActor().toLowerCase() + "/tommyheartbeat", new OSCListener() {
@Override
public void acceptMessage(Date time, OSCMessage message) {
actorData.setTommyHeartbeat(!actorData.getTommyHeartbeat());
}
});
}
}

View File

@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="de.psychose.MainForm">
<grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="2" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="0" y="0" width="810" height="670"/>
<xy x="0" y="0" width="930" height="560"/>
</constraints>
<properties>
<background color="-16777216"/>
<foreground color="-1"/>
<maximumSize width="1000" height="1000"/>
<minimumSize width="810" height="670"/>
<preferredSize width="810" height="670"/>
<minimumSize width="930" height="560"/>
<preferredSize width="950" height="570"/>
</properties>
<border type="none"/>
<children>
@ -19,9 +19,9 @@
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
<nested-form id="e6dc4" form-file="de/psychose/ActorHeart.form" binding="heart1">
<nested-form id="e6dc4" form-file="de/psychose/ActorHeart.form" binding="heart">
<constraints>
<grid row="1" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
<grid row="1" column="0" row-span="1" col-span="4" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
<nested-form id="18353" form-file="de/psychose/ActorDisplay.form" binding="actor2">
@ -36,17 +36,22 @@
</nested-form>
<component id="fe39c" class="javax.swing.JLabel" binding="breath">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
<grid row="0" column="3" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<enabled value="true"/>
<font name="Serif" size="72"/>
<font size="70"/>
<foreground color="-1"/>
<horizontalAlignment value="0"/>
<horizontalTextPosition value="0"/>
<text value="123"/>
<text value="999"/>
</properties>
</component>
<hspacer id="10ad8">
<constraints>
<grid row="1" column="4" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
</form>

View File

@ -2,44 +2,48 @@ package de.psychose;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.text.DecimalFormat;
/**
* @author: lucas
* @date: 14.04.14 21:43
*/
public class MainForm {
public class MainForm extends JFrame {
private JPanel mainPanel;
private ActorHeart heart1;
private ActorHeart heart;
private ActorDisplay actor1;
private ActorDisplay actor2;
private ActorDisplay actor3;
private JLabel breath;
private final DecimalFormat df = new DecimalFormat("#.0");
public JPanel getMainPanel() {
return mainPanel;
}
public MainForm(final ActorData[] actorDatas) {
super("HD Main");
setContentPane(mainPanel);
setResizable(false);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setUndecorated(true);
public MainForm(final ActorData actorData1, final ActorData actorData2, final ActorData actorData3) {
actor1.init(actorDatas[0], false);
actor2.init(actorDatas[1], false);
actor3.init(actorDatas[2], false);
heart.setActorDatas(actorDatas);
actor1.setCaption("Körper 1");
actor2.setCaption("Körper 2");
actor3.setCaption("Körper 3");
actor1.setActorData(actorData1);
actor2.setActorData(actorData2);
actor3.setActorData(actorData3);
heart1.setActorData(actorData1, actorData2, actorData3);
final Timer timer = new Timer(100, new AbstractAction() {
// this is now our main timer to update all and everything gui related
final Timer timer = new Timer(50, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
breath.setText(String.valueOf(actorData1.getAirflow()));
// update the breath display
breath.setText(String.valueOf(actorDatas[0].getAirflow()));
actor1.update();
actor2.update();
actor3.update();
heart.update();
}
});
timer.setRepeats(true);
timer.start();
pack();
setVisible(true);
}

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="de.psychose.PulseControl">
<grid id="27dc6" binding="pulsePanel" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="261" height="38"/>
<xy x="20" y="20" width="179" height="30"/>
</constraints>
<properties>
<foreground color="-1"/>
@ -12,29 +12,34 @@
<children>
<component id="a9565" class="javax.swing.JCheckBox" binding="enableCheckBox" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<focusable value="false"/>
<selected value="false"/>
<text value="Enable"/>
</properties>
</component>
<component id="dadb" class="javax.swing.JSpinner" binding="spinner1" default-binding="true">
<component id="dadb" class="javax.swing.JSpinner" binding="spinner">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
<minimum-size width="50" height="-1"/>
<preferred-size width="50" height="-1"/>
</grid>
</constraints>
<properties>
<background color="-16711423"/>
<focusable value="false"/>
</properties>
</component>
<hspacer id="dec01">
<component id="b9118" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<properties>
<text value="Pulse"/>
</properties>
</component>
</children>
</grid>
</form>

View File

@ -14,58 +14,41 @@ import java.util.Random;
public class PulseControl extends Observable {
private final int PULSE_WOBBLE_WIDTH = 10;
private JCheckBox enableCheckBox;
private JSpinner spinner1;
private JPanel pulsePanel;
private Timer timer;
private Random random = new Random();
private int heartbeat = 0;
private JSpinner spinner;
private JPanel mainPanel;
private final Timer timer;
private final Random random = new Random();
private boolean heartbeat = false;
public PulseControl() {
enableCheckBox.setFocusable(false);
spinner1.setFocusable(false);
spinner1.setValue(110);
spinner.setValue(110);
timer = new Timer(100, new AbstractAction() {
timer = new Timer(500, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
heartbeat = (heartbeat+1) % 2;
heartbeat = !heartbeat;
final int pulseWobbleCenter = (int)spinner1.getValue();
int pulse = pulseWobbleCenter - PULSE_WOBBLE_WIDTH / 2 + random.nextInt(PULSE_WOBBLE_WIDTH);
int pulse = (int) spinner.getValue() - PULSE_WOBBLE_WIDTH / 2 + random.nextInt(PULSE_WOBBLE_WIDTH);
if(pulse < 60) pulse = 60;
if(pulse > 230) pulse = 230;
final PulseData data = new PulseData(heartbeat, pulse, 95 + random.nextInt(4));
setChanged();
notifyObservers(data);
notifyObservers(new PulseData(heartbeat, pulse, 95 + random.nextInt(4)));
final int delay = 60000 / pulse;
timer.setDelay(delay);
timer.setDelay(60000 / pulse);
}
});
timer.setRepeats(true);
enableCheckBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
JCheckBox checkBox = (JCheckBox)e.getSource();
if(checkBox.isSelected()) {
if(!timer.isRunning()) {
System.out.println("starting pulsecontrol " + this);
timer.start();
}
} else {
if(timer.isRunning()) {
System.out.println("stopping pulsecontrol " + this);
timer.stop();
}
if (enableCheckBox.isSelected() && !timer.isRunning()) {
timer.start();
} else if (timer.isRunning()) {
timer.stop();
}
}
});
}
}

View File

@ -6,7 +6,7 @@ package de.psychose;
*/
public class PulseData {
private int heartbeat;
private boolean heartbeat;
private int pulse;
private int oxygen;
@ -14,17 +14,17 @@ public class PulseData {
}
public PulseData(int heartbeat, int pulse, int oxygen) {
public PulseData(boolean heartbeat, int pulse, int oxygen) {
this.heartbeat = heartbeat;
this.pulse = pulse;
this.oxygen = oxygen;
}
public int getHeartbeat() {
public boolean getHeartbeat() {
return heartbeat;
}
public void setHeartbeat(int heartbeat) {
public void setHeartbeat(boolean heartbeat) {
this.heartbeat = heartbeat;
}

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="de.psychose.TemperatureControl">
<grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="211" height="30"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="c685e" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Temp"/>
</properties>
</component>
<component id="f12ee" class="javax.swing.JCheckBox" binding="enableCheckBox" default-binding="true">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Enable"/>
</properties>
</component>
<component id="27ee3" class="javax.swing.JSpinner" binding="spinner1" default-binding="true">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
</children>
</grid>
</form>

View File

@ -0,0 +1,34 @@
package de.psychose;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.util.Observable;
/**
* @author: lucas
* @date: 20.11.14 23:11
*/
public class TemperatureControl extends Observable {
private static final double MIN_OFFSET = -20;
private static final double MAX_OFFSET = 20;
private static final double INCREMENT = 0.1;
private JCheckBox enableCheckBox;
private JSpinner spinner1;
private JPanel mainPanel;
public TemperatureControl() {
spinner1.setModel(new SpinnerNumberModel(0, MIN_OFFSET, MAX_OFFSET, INCREMENT));
final ChangeListener changeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
setChanged();
notifyObservers(enableCheckBox.isSelected() ? spinner1.getValue() : 0.0);
}
};
spinner1.addChangeListener(changeListener);
enableCheckBox.addChangeListener(changeListener);
}
}