Martin Kunz 4 years ago
commit
5bb2f75551

+ 189 - 0
.gitignore

@@ -0,0 +1,189 @@
+
+# Created by https://www.gitignore.io/api/osx,java,linux,windows,intellij,maven
+# Edit at https://www.gitignore.io/?templates=osx,java,linux,windows,intellij,maven
+
+### Intellij ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn.  Uncomment if using
+# auto-import.
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### Intellij Patch ###
+# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
+
+# *.iml
+# modules.xml
+# .idea/misc.xml
+# *.ipr
+
+# Sonarlint plugin
+.idea/sonarlint
+
+### Java ###
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+### Linux ###
+*~
+
+# temporary files which can be created if a process still has a handle open of a deleted file
+.fuse_hidden*
+
+# KDE directory preferences
+.directory
+
+# Linux trash folder which might appear on any partition or disk
+.Trash-*
+
+# .nfs files are created when an open file is removed but is still being accessed
+.nfs*
+
+### Maven ###
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+
+### OSX ###
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+### Windows ###
+# Windows thumbnail cache files
+Thumbs.db
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# End of https://www.gitignore.io/api/osx,java,linux,windows,intellij,maven

+ 308 - 0
pom.xml

@@ -0,0 +1,308 @@
+<?xml version="1.0"?>
+<project
+	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+	<modelVersion>4.0.0</modelVersion>
+
+	<groupId>cdp</groupId>
+	<artifactId>urgrip</artifactId>
+	<version>1.0-SNAPSHOT</version>
+	<name>urgrip</name>
+	<packaging>bundle</packaging>
+
+	<properties>
+
+		<!--********************************************************************-->
+		<!--   Note: Update this section with relevant meta data                -->
+		<!--         that comes along with your URCap                           -->
+		<!--********************************************************************-->
+		<!--******************* BEGINNING OF URCAP META DATA *******************-->
+		<urcap.symbolicname>cdp.urgrip</urcap.symbolicname>
+		<urcap.vendor>CDP</urcap.vendor>
+		<urcap.contactAddress>Seestadtstraße 27</urcap.contactAddress>
+		<urcap.copyright>Copyright notice (C)</urcap.copyright>
+		<urcap.description>This is a description of the URCap</urcap.description>
+		<urcap.licenseType>License type</urcap.licenseType>
+		<!--********************** END OF URCAP META DATA **********************-->
+		<!--********************************************************************-->
+
+		<!-- Host, username and password of the robot to be used when running "mvn install -Premote" -->
+		<urcap.install.host>localhost:2222</urcap.install.host>
+		<urcap.install.username>root</urcap.install.username>
+		<urcap.install.password>easybot</urcap.install.password>
+
+		<!--Install path for the UR Sim-->
+		<ursim.home></ursim.home>
+
+		<!--Host and standard user/password for UR Sim running in a VM-->
+		<ursimvm.install.host></ursimvm.install.host>
+		<ursimvm.install.username>ur</ursimvm.install.username>
+		<ursimvm.install.password>easybot</ursimvm.install.password>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.8.1</version>
+				<configuration>
+					<source>1.8</source>
+					<target>1.8</target>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-install-plugin</artifactId>
+				<version>2.5.2</version>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<version>2.22.1</version>
+				<configuration>
+					<runOrder>alphabetical</runOrder>
+					<useSystemClassLoader>false</useSystemClassLoader>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-jar-plugin</artifactId>
+				<version>3.1.2</version>
+				<configuration>
+					<archive>
+						<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+					</archive>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-resources-plugin</artifactId>
+				<version>3.1.0</version>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-bundle-plugin</artifactId>
+				<version>4.2.1</version>
+				<extensions>true</extensions>
+				<executions>
+					<execution>
+						<id>bundle-manifest</id>
+						<phase>process-classes</phase>
+							<goals>
+								<goal>manifest</goal>
+							</goals>
+					</execution>
+				</executions>
+				<configuration>
+					<instructions>
+						<!--********** DO NOT MODIFY THE ENTRIES OF THIS SECTION **********-->
+						<Bundle-Category>URCap</Bundle-Category>
+						<Bundle-Activator>uraxis.Activator</Bundle-Activator>
+						<Bundle-Vendor>${urcap.vendor}</Bundle-Vendor>
+						<Bundle-ContactAddress>${urcap.contactAddress}</Bundle-ContactAddress>
+						<Bundle-Copyright>${urcap.copyright}</Bundle-Copyright>
+						<Bundle-LicenseType>${urcap.licenseType}</Bundle-LicenseType>
+						<Bundle-Description>${urcap.description}</Bundle-Description>
+						<!--***************************************************************-->
+						<Import-Package>
+							com.ur.urcap.api*;version="[1.7.0,2.0.0)",
+							*
+						</Import-Package>
+					</instructions>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>exec-maven-plugin</artifactId>
+				<version>1.6.0</version>
+				<executions>
+					<!-- generate URCap package after compiling -->
+					<execution>
+						<id>package-urcap</id>
+						<phase>package</phase>
+						<goals>
+							<goal>exec</goal>
+						</goals>
+						<configuration>
+							<executable>copy</executable>
+								<commandlineArgs>target\\${project.build.finalName}.jar target\\${project.build.finalName}.urcap</commandlineArgs>
+							<workingDirectory>.</workingDirectory>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.core</artifactId>
+			<version>4.3.0</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.ur.urcap</groupId>
+			<artifactId>api</artifactId>
+			<version>1.7.0</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.xmlrpc</groupId>
+			<artifactId>xmlrpc-client</artifactId>
+			<version>3.1.3.0</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.xmlrpc</groupId>
+			<artifactId>xmlrpc-common</artifactId>
+			<version>3.1.3.0</version>
+			<exclusions>
+				<exclusion>
+					<groupId>org.antlr</groupId>
+					<artifactId>stringtemplate</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.antlr</groupId>
+					<artifactId>antlr-runtime</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.ws.commons.util</groupId>
+			<artifactId>ws-commons-util</artifactId>
+			<version>1.0.2.0</version>
+			<exclusions>
+				<exclusion>
+					<artifactId>xml-apis</artifactId>
+					<groupId>xml-apis</groupId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<!-- test dependencies -->
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.12</version>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+	<profiles>
+		<profile>
+			<id>remote</id>
+			<build>
+				<plugins>
+					<plugin>
+						<groupId>org.codehaus.mojo</groupId>
+						<artifactId>exec-maven-plugin</artifactId>
+						<version>1.1</version>
+						<executions>
+							<execution>
+								<id>remote-install-urcap</id>
+								<phase>install</phase>
+								<goals>
+									<goal>exec</goal>
+								</goals>
+								<configuration>
+									<executable>sshpass</executable>
+									<commandlineArgs>-p ${urcap.install.password} scp -o StrictHostKeyChecking=no target/${project.build.finalName}.jar ${urcap.install.username}@${urcap.install.host}:/root/.urcaps/${urcap.symbolicname}.jar</commandlineArgs>
+									<workingDirectory>.</workingDirectory>
+								</configuration>
+							</execution>
+							<execution>
+								<id>remote-restart-ui</id>
+								<phase>install</phase>
+								<goals>
+									<goal>exec</goal>
+								</goals>
+								<configuration>
+									<executable>sshpass</executable>
+									<commandlineArgs>-p ${urcap.install.password} ssh ${urcap.install.username}@${urcap.install.host} pkill java</commandlineArgs>
+									<workingDirectory>.</workingDirectory>
+								</configuration>
+							</execution>
+						</executions>
+					</plugin>
+				</plugins>
+			</build>
+		</profile>
+		<profile>
+			<id>local</id>
+			<build>
+				<plugins>
+					<plugin>
+						<groupId>org.codehaus.mojo</groupId>
+						<artifactId>exec-maven-plugin</artifactId>
+						<version>1.1</version>
+						<executions>
+							<execution>
+								<id>local-install-urcap</id>
+								<phase>install</phase>
+								<goals>
+									<goal>exec</goal>
+								</goals>
+								<configuration>
+									<executable>cp</executable>
+									<commandlineArgs>target/${project.build.finalName}.jar ${user.home}/.urcaps/${urcap.symbolicname}.jar</commandlineArgs>
+									<workingDirectory>.</workingDirectory>
+								</configuration>
+							</execution>
+						</executions>
+					</plugin>
+				</plugins>
+			</build>
+		</profile>
+		<profile>
+			<id>ursim</id>
+			<build>
+				<plugins>
+					<plugin>
+						<groupId>org.codehaus.mojo</groupId>
+						<artifactId>exec-maven-plugin</artifactId>
+						<version>1.1</version>
+						<executions>
+							<execution>
+								<id>ursim-install-urcap</id>
+								<phase>install</phase>
+								<goals>
+									<goal>exec</goal>
+								</goals>
+								<configuration>
+									<executable>cp</executable>
+									<commandlineArgs>target/${project.build.finalName}.jar ${ursim.home}/.urcaps/${urcap.symbolicname}.jar</commandlineArgs>
+									<workingDirectory>.</workingDirectory>
+								</configuration>
+							</execution>
+						</executions>
+					</plugin>
+				</plugins>
+			</build>
+		</profile>
+		<profile>
+			<id>ursimvm</id>
+			<build>
+				<plugins>
+					<plugin>
+						<groupId>org.codehaus.mojo</groupId>
+						<artifactId>exec-maven-plugin</artifactId>
+						<version>1.1</version>
+						<executions>
+							<execution>
+								<id>ursimvm-install-urcap</id>
+								<phase>install</phase>
+								<goals>
+									<goal>exec</goal>
+								</goals>
+								<configuration>
+									<executable>sshpass</executable>
+									<commandlineArgs>-p ${ursimvm.install.password} scp -o StrictHostKeyChecking=no target/${project.build.finalName}.jar ${ursimvm.install.username}@${ursimvm.install.host}:/home/ur/ursim-current/.urcaps/${urcap.symbolicname}.jar</commandlineArgs>
+									<workingDirectory>.</workingDirectory>
+								</configuration>
+							</execution>
+						</executions>
+					</plugin>
+				</plugins>
+			</build>
+		</profile>
+	</profiles>
+</project>

+ 25 - 0
src/main/java/uraxis/Activator.java

@@ -0,0 +1,25 @@
+package uraxis;
+
+import com.ur.urcap.api.contribution.program.swing.SwingProgramNodeService;
+import com.ur.urcap.api.contribution.toolbar.swing.SwingToolbarService;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import uraxis.programnodes.GripperNodeService;
+import uraxis.toolbar.MyToolbarService;
+
+public class Activator implements BundleActivator {
+
+	@Override
+	public void start(BundleContext context) throws Exception {
+		System.out.println("Gripper Activator says Hello World!");
+
+		context.registerService(SwingToolbarService.class, new MyToolbarService(), null);
+		context.registerService(SwingProgramNodeService.class, new GripperNodeService(), null);
+	}
+
+	@Override
+	public void stop(BundleContext bundleContext) throws Exception {
+		System.out.println("Activator says Goodbye World!");
+	}
+}
+

+ 93 - 0
src/main/java/uraxis/programnodes/GripperNodeContribution.java

@@ -0,0 +1,93 @@
+package uraxis.programnodes;
+
+import com.ur.urcap.api.contribution.ProgramNodeContribution;
+import com.ur.urcap.api.contribution.program.ProgramAPIProvider;
+import com.ur.urcap.api.domain.ProgramAPI;
+import com.ur.urcap.api.domain.data.DataModel;
+import com.ur.urcap.api.domain.script.ScriptWriter;
+import com.ur.urcap.api.domain.undoredo.UndoRedoManager;
+import com.ur.urcap.api.domain.userinteraction.keyboard.KeyboardInputCallback;
+import com.ur.urcap.api.domain.userinteraction.keyboard.KeyboardInputFactory;
+import com.ur.urcap.api.domain.userinteraction.keyboard.KeyboardNumberInput;
+
+public class GripperNodeContribution implements ProgramNodeContribution {
+    private final String POSITION="POSITION";
+    private final String SPEED="SPEED";
+
+    private final ProgramAPI programAPI;
+    private final UndoRedoManager undoRedoManager;
+    private final KeyboardInputFactory keyboardFactory;
+
+    private final GripperNodeView view;
+    private final DataModel model;
+
+
+    public GripperNodeContribution(ProgramAPIProvider apiProvider, GripperNodeView view, DataModel model) {
+        this.programAPI = apiProvider.getProgramAPI();
+        this.undoRedoManager = apiProvider.getProgramAPI().getUndoRedoManager();
+        this.keyboardFactory = apiProvider.getUserInterfaceAPI().getUserInteraction().getKeyboardInputFactory();
+
+        this.view = view;
+        this.model = model;
+    }
+
+    @Override
+    public void openView() {
+        view.setPosition(model.get(POSITION, 0));
+        view.setSpeed(model.get(SPEED, 20));
+    }
+
+    @Override
+    public void closeView() {
+        model.set(POSITION, view.getPosition());
+        model.set(SPEED, view.getSpeed());
+    }
+
+    @Override
+    public String getTitle() {
+        return "Gripper ";
+    }
+
+    @Override
+    public void generateScript(ScriptWriter writer) {
+        writer.appendLine("write_output_integer_register(3," + 3 + ")");
+        writer.writeChildren();
+    }
+
+    public KeyboardNumberInput getKeyboardForPositionField() {
+        KeyboardNumberInput<Integer> keyboardInput = keyboardFactory.createIntegerKeypadInput();
+        keyboardInput.setInitialValue(model.get(POSITION, 0));
+        return keyboardInput;
+    }
+
+    public KeyboardInputCallback<Integer> getCallbackForPositionField() {
+        return new KeyboardInputCallback<Integer>() {
+            @Override
+            public void onOk(Integer value) {
+                model.set(POSITION, value);
+                view.setPosition(value);
+            }
+        };
+    }
+
+    public KeyboardNumberInput getKeyboardForSpeedField() {
+        KeyboardNumberInput<Integer> keyboardInput = keyboardFactory.createIntegerKeypadInput();
+        keyboardInput.setInitialValue(model.get(SPEED, 0));
+        return keyboardInput;
+    }
+
+    public KeyboardInputCallback<Integer> getCallbackForSpeedField() {
+        return new KeyboardInputCallback<Integer>() {
+            @Override
+            public void onOk(Integer value) {
+                model.set(SPEED, value);
+                view.setSpeed(value);
+            }
+        };
+    }
+
+    @Override
+    public boolean isDefined() {
+        return true;
+    }
+}

+ 50 - 0
src/main/java/uraxis/programnodes/GripperNodeService.java

@@ -0,0 +1,50 @@
+package uraxis.programnodes;
+
+import com.ur.urcap.api.contribution.ViewAPIProvider;
+import com.ur.urcap.api.contribution.program.ContributionConfiguration;
+import com.ur.urcap.api.contribution.program.CreationContext;
+import com.ur.urcap.api.contribution.program.ProgramAPIProvider;
+import com.ur.urcap.api.contribution.program.swing.SwingProgramNodeService;
+import com.ur.urcap.api.domain.SystemAPI;
+import com.ur.urcap.api.domain.data.DataModel;
+
+import java.util.Locale;
+
+public class GripperNodeService implements SwingProgramNodeService<GripperNodeContribution, GripperNodeView> {
+
+
+    @Override
+    public String getId() {
+        return "FestoABS";
+    }
+
+    @Override
+    public void configureContribution(ContributionConfiguration configuration) {
+        configuration.setChildrenAllowed(false);
+    }
+
+    @Override
+    public String getTitle(Locale locale) {
+        return "FestoABS";
+    }
+
+    @Override
+    public GripperNodeView createView(ViewAPIProvider apiProvider) {
+        SystemAPI systemAPI = apiProvider.getSystemAPI();
+        Style style =  new V5Style();
+        return new GripperNodeView(style);
+    }
+
+    @Override
+    public GripperNodeContribution createNode(
+            ProgramAPIProvider apiProvider,
+            GripperNodeView view,
+            DataModel model,
+            CreationContext context) {
+        return new GripperNodeContribution(apiProvider, view, model);
+    }
+
+    public GripperNodeService() {
+
+    }
+}

+ 102 - 0
src/main/java/uraxis/programnodes/GripperNodeView.java

@@ -0,0 +1,102 @@
+package uraxis.programnodes;
+
+import com.ur.urcap.api.contribution.ContributionProvider;
+import com.ur.urcap.api.contribution.program.swing.SwingProgramNodeView;
+import com.ur.urcap.api.domain.userinteraction.keyboard.KeyboardNumberInput;
+
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+public class GripperNodeView implements SwingProgramNodeView<GripperNodeContribution>{
+
+    private final Style style;
+    private JTextField jtfPosition, jtfSpeed;
+
+    public GripperNodeView(Style style) {
+        this.style = style;
+    }
+
+    @Override
+    public void buildUI(JPanel jPanel, final ContributionProvider<GripperNodeContribution> provider) {
+        jPanel.setLayout(new BoxLayout(jPanel, BoxLayout.Y_AXIS));
+        jPanel.add(createVerticalSpacing(style.getVerticalSpacing()));
+        jPanel.add(createInputPosition(provider));
+        jPanel.add(createInputSpeed(provider));
+        jPanel.add(createVerticalSpacing(style.getExtraLargeVerticalSpacing()));
+    }
+
+    private Box createInputPosition(final ContributionProvider<GripperNodeContribution> provider) {
+        Box inputBox = Box.createHorizontalBox();
+        inputBox.setAlignmentX(Component.LEFT_ALIGNMENT);
+        inputBox.add(new JLabel("Move by:"));
+        inputBox.add(createHorizontalSpacing());
+
+        jtfPosition = new JTextField();
+        jtfPosition.setFocusable(false);
+        jtfPosition.setPreferredSize(style.getInputfieldSize());
+        jtfPosition.setMaximumSize(jtfPosition.getPreferredSize());
+        jtfPosition.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mousePressed(MouseEvent e) {
+                KeyboardNumberInput keyboardInput = provider.get().getKeyboardForPositionField();
+                keyboardInput.show(jtfPosition, provider.get().getCallbackForPositionField());
+            }
+        });
+        inputBox.add(jtfPosition);
+
+        return inputBox;
+    }
+
+    private Box createInputSpeed(final ContributionProvider<GripperNodeContribution> provider) {
+        Box inputBox = Box.createHorizontalBox();
+        inputBox.setAlignmentX(Component.LEFT_ALIGNMENT);
+        inputBox.add(new JLabel("Speed %:"));
+        inputBox.add(createHorizontalSpacing());
+
+        jtfSpeed = new JTextField();
+        jtfSpeed.setFocusable(false);
+        jtfSpeed.setPreferredSize(style.getInputfieldSize());
+        jtfSpeed.setMaximumSize(jtfSpeed.getPreferredSize());
+        jtfSpeed.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mousePressed(MouseEvent e) {
+                KeyboardNumberInput keyboardInput = provider.get().getKeyboardForSpeedField();
+                keyboardInput.show(jtfSpeed, provider.get().getCallbackForSpeedField());
+            }
+        });
+        inputBox.add(jtfSpeed);
+        return inputBox;
+    }
+
+        private Component createVerticalSpacing(int height) {
+        return Box.createRigidArea(new Dimension(0, height));
+    }
+
+    private Component createHorizontalSpacing() {
+        return Box.createRigidArea(new Dimension(style.getHorizontalSpacing(), 0));
+    }
+
+    public void setPosition(Integer value) {
+        jtfPosition.setText(value.toString());
+    }
+
+    public void setSpeed(Integer value) {
+        jtfSpeed.setText(value.toString());
+    }
+
+    public Integer getPosition() {
+        return Integer.parseInt(jtfPosition.getText());
+    }
+    public Integer getSpeed() {
+        return Integer.parseInt(jtfSpeed.getText());
+    }
+
+
+}

+ 33 - 0
src/main/java/uraxis/programnodes/Style.java

@@ -0,0 +1,33 @@
+package uraxis.programnodes;
+
+import java.awt.*;
+
+public abstract class Style {
+    private static final int HORIZONTAL_SPACING = 10;
+    private static final int VERTICAL_SPACING = 10;
+    private static final int LARGE_VERTICAL_SPACING = 25;
+    private static final int XLARGE_VERTICAL_SPACING = 50;
+    private static final int SMALL_HEADER_FONT_SIZE = 16;
+
+    public int getHorizontalSpacing() {
+        return HORIZONTAL_SPACING;
+    }
+
+    public int getVerticalSpacing() {
+        return VERTICAL_SPACING;
+    }
+
+    public int getExtraLargeVerticalSpacing() {
+        return XLARGE_VERTICAL_SPACING;
+    }
+
+    public int getLargeVerticalSpacing() {
+        return LARGE_VERTICAL_SPACING;
+    }
+
+    public int getSmallHeaderFontSize() {
+        return SMALL_HEADER_FONT_SIZE;
+    }
+
+    public abstract Dimension getInputfieldSize();
+}

+ 12 - 0
src/main/java/uraxis/programnodes/V5Style.java

@@ -0,0 +1,12 @@
+package uraxis.programnodes;
+
+import java.awt.*;
+
+public class V5Style extends Style {
+	private static final Dimension INPUTFIELD_SIZE = new Dimension(200, 30);
+
+	@Override
+	public Dimension getInputfieldSize() {
+		return INPUTFIELD_SIZE;
+	}
+}

+ 88 - 0
src/main/java/uraxis/toolbar/IOHandler.java

@@ -0,0 +1,88 @@
+package uraxis.toolbar;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import com.ur.urcap.api.domain.io.AnalogIO;
+import com.ur.urcap.api.domain.io.DigitalIO;
+import com.ur.urcap.api.domain.io.IOModel;
+
+public class IOHandler {
+
+    private final IOModel ioModel;
+
+    public IOHandler(IOModel ioModel) {
+        this.ioModel = ioModel;
+    }
+
+
+    /*Returns a DigitalIO object found by its default name
+     * Default names are:
+     * 	digital_in[0]
+     *  digital_in[1]
+     *  ...
+     *  digital_in[7]
+     *  digital_out[0]
+     *  digital_out[1]
+     *  ...
+     *  digital_out[7]
+     *  tool_in[0]
+     *  tool_in[1]
+     *  tool_out[0]
+     *  tool_out[1]
+     *  config_in[0]
+     *  config_in[1]
+     *  ...
+     *  config_in[7]
+     *  config_out[0]
+     *  config_out[1]
+     *  ...
+     *  config_out[7]
+     *
+     */
+    public DigitalIO getDigitalIO(String defaultName){
+        Collection<DigitalIO> IOcollection = ioModel.getIOs(DigitalIO.class);
+        int IO_count = IOcollection.size();
+        if(IO_count > 0){
+            Iterator<DigitalIO> IO_itr = IOcollection.iterator();
+            while(IO_itr.hasNext()){
+                DigitalIO thisIO = IO_itr.next();
+                String thisDefaultName = thisIO.getDefaultName();
+//				System.out.println("Found an IO named "+thisDefaultName);
+                if(thisDefaultName.equals(defaultName)){
+                    return thisIO;
+                }
+            }
+        }
+        return null;
+    }
+
+    /*Returns an AnalogIO object found by its default name
+     * Default names are:
+     *  analog_in[0]
+     *  analog_in[1]
+     *  analog_in[2] 	(Tool analog in 0)
+     *  analog_in[3]	(Tool analog in 1)
+     *  analog_out[0]
+     *  analog_out[1]
+     *
+     */
+    public AnalogIO getAnalogIO(String defaultName){
+        Collection<AnalogIO> IOcollection = ioModel.getIOs(AnalogIO.class);
+        int IO_count = IOcollection.size();
+        if(IO_count > 0){
+            Iterator<AnalogIO> IO_itr = IOcollection.iterator();
+            while(IO_itr.hasNext()){
+                AnalogIO thisIO = IO_itr.next();
+                String thisDefaultName = thisIO.getDefaultName();
+//				System.out.println("Found an IO named "+thisDefaultName);
+                if(thisDefaultName.equals(defaultName)){
+                    return thisIO;
+                }
+            }
+        }
+        return null;
+    }
+
+
+}

+ 94 - 0
src/main/java/uraxis/toolbar/MyToolbarContribution.java

@@ -0,0 +1,94 @@
+package uraxis.toolbar;
+
+import com.ur.urcap.api.contribution.toolbar.ToolbarAPIProvider;
+import com.ur.urcap.api.contribution.toolbar.ToolbarContext;
+import com.ur.urcap.api.contribution.toolbar.swing.SwingToolbarContribution;
+import com.ur.urcap.api.domain.io.DigitalIO;
+import com.ur.urcap.api.domain.io.IO;
+import com.ur.urcap.api.domain.io.IOModel;
+import uraxis.Activator;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.util.*;
+import java.util.Timer;
+
+class MyToolbarContribution implements SwingToolbarContribution {
+    private static final int VERTICAL_SPACE = 10;
+    private static final int HEADER_FONT_SIZE = 24;
+
+    private final ToolbarContext context;
+    private final ToolbarAPIProvider apiProvider;
+    private final IOHandler ioHandler;
+    private JLabel demoToolStatus;
+    private HashMap<String, JCheckBox> boxes=new HashMap<>();
+    private DigitalIO out0,out1, in0, in1;
+
+
+    MyToolbarContribution(ToolbarContext context) {
+        this.context = context;
+        this.apiProvider = context.getAPIProvider();
+        this.ioHandler = new IOHandler(this.apiProvider.getApplicationAPI().getIOModel());
+    }
+
+    @Override
+    public void openView() {
+        IOModel ioModel = apiProvider.getApplicationAPI().getIOModel();
+        Collection<IO> ios = ioModel.getIOs();
+    }
+
+    private void InitializeIO() {
+        out0 = 	ioHandler.getDigitalIO("tool_out[0]");
+        out1 = 	ioHandler.getDigitalIO("tool_out[1]");
+        in0 = 	ioHandler.getDigitalIO("tool_in[0]");
+        in1 = 	ioHandler.getDigitalIO("tool_in[1]");
+    }
+
+    @Override
+    public void closeView() {
+    }
+
+    public void buildUI(JPanel jPanel) {
+        jPanel.setLayout(new BoxLayout(jPanel, BoxLayout.Y_AXIS));
+        jPanel.add(createHeader());
+        jPanel.add(createVerticalSpace());
+        jPanel.add(createButtons());
+        jPanel.add(createInfo());
+    }
+
+    private Box createHeader() {
+        Box headerBox = Box.createHorizontalBox();
+        headerBox.setAlignmentX(Component.CENTER_ALIGNMENT);
+
+        JLabel header = new JLabel("Festo Axis Control");
+        header.setFont(header.getFont().deriveFont(Font.BOLD, HEADER_FONT_SIZE));
+        headerBox.add(header);
+        return headerBox;
+    }
+
+    private Box createButtons() {
+        Box box = Box.createHorizontalBox();
+        return box;
+    }
+
+    private Box createInfo() {
+        Box infoBox = Box.createVerticalBox();
+        infoBox.setAlignmentX(Component.CENTER_ALIGNMENT);
+        demoToolStatus = new JLabel();
+        demoToolStatus.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+
+        infoBox.add(demoToolStatus);
+        return infoBox;
+    }
+
+    private Component createVerticalSpace() {
+        return Box.createRigidArea(new Dimension(0, VERTICAL_SPACE));
+    }
+
+    private void updateText(String text) {
+        SwingUtilities.invokeLater(() -> demoToolStatus.setText("<HTML>" + text +"</HTML>"));
+    }
+
+
+}

+ 27 - 0
src/main/java/uraxis/toolbar/MyToolbarService.java

@@ -0,0 +1,27 @@
+package uraxis.toolbar;
+
+import com.ur.urcap.api.contribution.toolbar.ToolbarConfiguration;
+import com.ur.urcap.api.contribution.toolbar.ToolbarContext;
+import com.ur.urcap.api.contribution.toolbar.swing.SwingToolbarContribution;
+import com.ur.urcap.api.contribution.toolbar.swing.SwingToolbarService;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+
+public class MyToolbarService implements SwingToolbarService {
+
+    @Override
+    public Icon getIcon() {
+        return new ImageIcon(getClass().getResource("/icons/logo.png"));
+    }
+
+    @Override
+    public void configureContribution(ToolbarConfiguration configuration) {
+        configuration.setToolbarHeight(370);
+    }
+
+    @Override
+    public SwingToolbarContribution createToolbar(ToolbarContext context) {
+        return new MyToolbarContribution(context);
+    }
+}

BIN
src/main/resources/icons/logo.png


+ 39 - 0
src/main/resources/uraxis/installation.html

@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>Fexto Axis</title>
+		<style>
+			label {
+				display: inline-block;
+				width: 100px;
+				height: 28px;
+			}
+			input {
+				display: inline-block;
+				width: 200px;
+				height: 28px;
+			}
+		</style>
+	</head>
+	<body>
+		<h1>Festo Axis</h1>
+		<form>
+			<p>Fest Achse Config</p>
+			<br />
+
+			<label for="textIP">Daemon IP</label>
+			<input id="textIP" type="text" style="font-size: 18px;" /><br/>
+			<label for="textIP">Daemon Port</label>
+			<input id="textPort" type="text" style="font-size: 18px;" /><br/>
+            <input id="btnReady" type="button" style="font-size: 18px;" />
+
+            <input id="btnEnableDaemon" type="button" style="font-size: 18px;" />
+			<input id="btnDisableDaemon" type="button" style="font-size: 18px;" />
+			<br>
+			<label  id="lblStatus" style="width: 400px;height: 200px;vertical-align: top"></label>
+			<label id="lblDaemonStatus" style="width: 200px">Status of daemon</label>
+			<br>
+
+		</form>
+	</body>
+</html>

+ 38 - 0
src/test/java/uraxis/AppTest.java

@@ -0,0 +1,38 @@
+package uraxis;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest 
+	extends TestCase
+{
+	/**
+	 * Create the test case
+	 *
+	 * @param testName name of the test case
+	 */
+	public AppTest( String testName )
+	{
+		super( testName );
+	}
+
+	/**
+	 * @return the suite of tests being tested
+	 */
+	public static Test suite()
+	{
+		return new TestSuite( AppTest.class );
+	}
+
+	/**
+	 * Rigourous Test :-)
+	 */
+	public void testApp()
+	{
+		assertTrue( true );
+	}
+}