diff --git a/source/RobotAPI/gui-plugins/CartesianWaypointControlGui/CMakeLists.txt b/source/RobotAPI/gui-plugins/CartesianWaypointControlGui/CMakeLists.txt
index 1b2caffb7f5f818c18e1ee068b6e9d7e0745eabc..55b06608d60a5a3f09f6805a20039177f0bb8fc3 100644
--- a/source/RobotAPI/gui-plugins/CartesianWaypointControlGui/CMakeLists.txt
+++ b/source/RobotAPI/gui-plugins/CartesianWaypointControlGui/CMakeLists.txt
@@ -1,25 +1,17 @@
 armarx_set_target("CartesianWaypointControlGuiGuiPlugin")
-
 armarx_build_if(ArmarXGui_FOUND "ArmarXGui not available")
 
 set(SOURCES
     CartesianWaypointControlGuiGuiPlugin.cpp
     CartesianWaypointControlGuiWidgetController.cpp
 )
-
 set(HEADERS
     CartesianWaypointControlGuiGuiPlugin.h
     CartesianWaypointControlGuiWidgetController.h
 )
-
 set(GUI_MOC_HDRS ${HEADERS})
-
 set(GUI_UIS CartesianWaypointControlGuiWidget.ui)
-
-set(COMPONENT_LIBS
-    SimpleConfigDialog
-    RobotAPIComponentPlugins
-)
+set(COMPONENT_LIBS NJointControllerGuiPluginUtility)
 
 if(ArmarXGui_FOUND)
     armarx_gui_library(CartesianWaypointControlGuiGuiPlugin "${SOURCES}" "${GUI_MOC_HDRS}" "${GUI_UIS}" "" "${COMPONENT_LIBS}")
diff --git a/source/RobotAPI/gui-plugins/CartesianWaypointControlGui/CartesianWaypointControlGuiWidgetController.cpp b/source/RobotAPI/gui-plugins/CartesianWaypointControlGui/CartesianWaypointControlGuiWidgetController.cpp
index 5348bcaaa944c72d5b05f85afa0cd5253ca5ce9c..20e9273ab1aaa54297af953fce840432dbb32576 100644
--- a/source/RobotAPI/gui-plugins/CartesianWaypointControlGui/CartesianWaypointControlGuiWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/CartesianWaypointControlGui/CartesianWaypointControlGuiWidgetController.cpp
@@ -32,54 +32,34 @@
 
 namespace armarx
 {
-    CartesianWaypointControlGuiWidgetController::CartesianWaypointControlGuiWidgetController()
+    CartesianWaypointControlGuiWidgetController::CartesianWaypointControlGuiWidgetController() :
+        NJointControllerGuiPluginBase("NJointCartesianWaypointController")
     {
+        using T = CartesianWaypointControlGuiWidgetController;
         std::lock_guard g{_allMutex};
         _ui.setupUi(getWidget());
-        connect(_ui.radioButtonWPJson, SIGNAL(clicked()), this, SLOT(triggerParsing()));
-        connect(_ui.radioButton4f, SIGNAL(clicked()), this, SLOT(triggerParsing()));
-        connect(_ui.textEditWPs, SIGNAL(textChanged()), this, SLOT(triggerParsing()));
+        connect(_ui.radioButtonWPJson, &QPushButton::clicked, this, &T::triggerParsing);
+        connect(_ui.radioButton4f,     &QPushButton::clicked, this, &T::triggerParsing);
+        connect(_ui.textEditWPs,       &QTextEdit::textChanged, this, &T::triggerParsing);
 
-        connect(_ui.pushButtonStop,             SIGNAL(clicked()), this, SLOT(on_pushButtonStop_clicked()));
-        connect(_ui.pushButtonExecute,          SIGNAL(clicked()), this, SLOT(on_pushButtonExecute_clicked()));
-        connect(_ui.pushButtonZeroFT,           SIGNAL(clicked()), this, SLOT(on_pushButtonZeroFT_clicked()));
-        connect(_ui.pushButtonSendSettings,     SIGNAL(clicked()), this, SLOT(on_pushButtonSendSettings_clicked()));
-        connect(_ui.pushButtonCreateController, SIGNAL(clicked()), this, SLOT(on_pushButtonCreateController_clicked()));
+        connect(_ui.pushButtonExecute,      &QPushButton::clicked, this, &T::on_pushButtonExecute_clicked);
+        connect(_ui.pushButtonZeroFT,       &QPushButton::clicked, this, &T::on_pushButtonZeroFT_clicked);
+        connect(_ui.pushButtonSendSettings, &QPushButton::clicked, this, &T::on_pushButtonSendSettings_clicked);
 
-        _ui.widgetSpacer->setVisible(false);
-        _timer = startTimer(100);
-    }
-
-    CartesianWaypointControlGuiWidgetController::~CartesianWaypointControlGuiWidgetController()
-    {
-        killTimer(_timer);
-    }
-
-    void CartesianWaypointControlGuiWidgetController::loadSettings(QSettings* settings)
-    {
-        std::lock_guard g{_allMutex};
-        getRobotStateComponentPlugin().setRobotStateComponentName(settings->value("rsc", "Armar6StateComponent").toString().toStdString());
-        getRobotUnitComponentPlugin().setRobotUnitName(settings->value("ru", "Armar6Unit").toString().toStdString());
-    }
-
-    void CartesianWaypointControlGuiWidgetController::saveSettings(QSettings* settings)
-    {
-        std::lock_guard g{_allMutex};
-        settings->setValue("rsc", QString::fromStdString(getRobotStateComponentPlugin().getRobotStateComponentName()));
-        settings->setValue("ru", QString::fromStdString(getRobotUnitComponentPlugin().getRobotUnitName()));
-    }
+        connectCreateAcivateDeactivateDelete(
+            _ui.pushButtonCreateController,
+            nullptr,
+            _ui.pushButtonStop,
+            nullptr
+        );
 
-    void CartesianWaypointControlGuiWidgetController::onInitComponent()
-    {
+        _ui.widgetSpacer->setVisible(false);
     }
 
     void CartesianWaypointControlGuiWidgetController::onConnectComponent()
     {
         std::lock_guard g{_allMutex};
-        //robot
-        {
-            _robot = addRobot("state robot", VirtualRobot::RobotIO::eStructure);
-        }
+        NJointControllerGuiPluginBase::onConnectComponent();
         //fill rns combo box
         {
             bool found = false;
@@ -98,40 +78,12 @@ namespace armarx
             }
         }
     }
-    void CartesianWaypointControlGuiWidgetController::onDisconnectComponent()
-    {
-        std::lock_guard g{_allMutex};
-        deleteOldController();
-    }
-    void CartesianWaypointControlGuiWidgetController::on_pushButtonCreateController_clicked()
+
+    void CartesianWaypointControlGuiWidgetController::createController()
     {
         std::lock_guard g{_allMutex};
-        deleteOldController();
-
-        static const std::string njointControllerClassName = "NJointCartesianWaypointController";
-
-        NJointCartesianWaypointControllerConfigPtr cfg = new NJointCartesianWaypointControllerConfig;
-        cfg->rns = _ui.comboBoxChain->currentText().toStdString();
-        cfg->ftName = _ui.lineEditFTName->text().toStdString();
-        cfg->runCfg = readRunCfg();
-        _supportsFT = !cfg->ftName.empty();
-
-        _controllerName = getName() + "_" + njointControllerClassName +
-                          std::to_string(std::random_device{}());
-        std::replace(_controllerName.begin(), _controllerName.end(), '.', '_');
-        std::replace(_controllerName.begin(), _controllerName.end(), ':', '_');
-
-        _ui.labelCurrentControllerChain->setText(QString::fromStdString(cfg->rns));
-        _ui.labelCurrentControllerFT->setText(QString::fromStdString(cfg->ftName));
-
-        ARMARX_IMPORTANT << "Creating " << njointControllerClassName << " '"
-                         << _controllerName << "'";
-        _controller = NJointCartesianWaypointControllerInterfacePrx::checkedCast(
-                          getRobotUnit()->createNJointController(
-                              njointControllerClassName,
-                              _controllerName,
-                              cfg));
-        ARMARX_CHECK_NOT_NULL(_controller);
+        NJointControllerGuiPluginBase::createController();
+        _supportsFT = !_ui.lineEditFTName->text().toStdString().empty();
     }
 
     void CartesianWaypointControlGuiWidgetController::on_pushButtonSendSettings_clicked()
@@ -166,35 +118,6 @@ namespace armarx
         }
     }
 
-    void CartesianWaypointControlGuiWidgetController::on_pushButtonStop_clicked()
-    {
-        std::lock_guard g{_allMutex};
-        if (_controller)
-        {
-            ARMARX_IMPORTANT << "sending stop command to controller " << _controllerName;
-            _controller->stopMovement();
-        }
-    }
-
-    QPointer<QDialog> CartesianWaypointControlGuiWidgetController::getConfigDialog(QWidget* parent)
-    {
-        std::lock_guard g{_allMutex};
-        if (!_dialog)
-        {
-            _dialog = new SimpleConfigDialog(parent);
-            _dialog->addProxyFinder<RobotUnitInterfacePrx>({"ru", "Robot Unit", "*Unit"});
-            _dialog->addProxyFinder<RobotStateComponentInterfacePrx>({"rsc", "Robot State Component", "*Component"});
-        }
-        return qobject_cast<SimpleConfigDialog*>(_dialog);
-    }
-
-    void CartesianWaypointControlGuiWidgetController::configured()
-    {
-        std::lock_guard g{_allMutex};
-        getRobotStateComponentPlugin().setRobotStateComponentName(_dialog->getProxyName("rsc"));
-        getRobotUnitComponentPlugin().setRobotUnitName(_dialog->getProxyName("ru"));
-    }
-
     void CartesianWaypointControlGuiWidgetController::triggerParsing()
     {
         std::lock_guard g{_allMutex};
@@ -257,21 +180,6 @@ namespace armarx
         return cfg;
     }
 
-    void CartesianWaypointControlGuiWidgetController::deleteOldController()
-    {
-        std::lock_guard g{_allMutex};
-        if (_controller)
-        {
-            ARMARX_IMPORTANT << "deleting old controller '" << _controllerName << "'";
-            try
-            {
-                _controller->deactivateAndDeleteController();
-            }
-            catch (...) {}
-            _controller = nullptr;
-        }
-    }
-
     void CartesianWaypointControlGuiWidgetController::timerEvent(QTimerEvent*)
     {
         std::lock_guard g{_allMutex};
@@ -286,4 +194,13 @@ namespace armarx
             _controller->setVisualizationRobotGlobalPose(_robot->getGlobalPose());
         }
     }
+
+    NJointControllerConfigPtr CartesianWaypointControlGuiWidgetController::readFullCFG() const
+    {
+        NJointCartesianWaypointControllerConfigPtr cfg = new NJointCartesianWaypointControllerConfig;
+        cfg->rns = _ui.comboBoxChain->currentText().toStdString();
+        cfg->ftName = _ui.lineEditFTName->text().toStdString();
+        cfg->runCfg = readRunCfg();
+        return NJointControllerConfigPtr::dynamicCast(cfg);
+    }
 }
diff --git a/source/RobotAPI/gui-plugins/CartesianWaypointControlGui/CartesianWaypointControlGuiWidgetController.h b/source/RobotAPI/gui-plugins/CartesianWaypointControlGui/CartesianWaypointControlGuiWidgetController.h
index fc6b1936d3abe105a02c8fdf2ca72439dcf8d84f..8430e1e167bcbc3b7b39df400e57e89344908d5e 100644
--- a/source/RobotAPI/gui-plugins/CartesianWaypointControlGui/CartesianWaypointControlGuiWidgetController.h
+++ b/source/RobotAPI/gui-plugins/CartesianWaypointControlGui/CartesianWaypointControlGuiWidgetController.h
@@ -21,22 +21,8 @@
  */
 #pragma once
 
-#include <mutex>
-
-#include <VirtualRobot/Robot.h>
-
-#include <ArmarXCore/core/system/ImportExportComponent.h>
-
-#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXGuiPlugin.h>
-#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXComponentWidgetController.h>
-#include <ArmarXGui/libraries/SimpleConfigDialog/SimpleConfigDialog.h>
-
-#include <RobotAPI/interface/core/RobotState.h>
-#include <RobotAPI/interface/units/RobotUnit/RobotUnitInterface.h>
+#include <RobotAPI/libraries/NJointControllerGuiPluginUtility/NJointControllerGuiPluginBase.h>
 #include <RobotAPI/interface/units/RobotUnit/NJointCartesianWaypointController.h>
-#include <RobotAPI/libraries/RobotAPIComponentPlugins/RobotUnitComponentPlugin.h>
-#include <RobotAPI/libraries/RobotAPIComponentPlugins/RobotStateComponentPlugin.h>
-
 #include <RobotAPI/gui-plugins/CartesianWaypointControlGui/ui_CartesianWaypointControlGuiWidget.h>
 
 namespace armarx
@@ -61,22 +47,15 @@ namespace armarx
      */
     class ARMARXCOMPONENT_IMPORT_EXPORT
         CartesianWaypointControlGuiWidgetController:
-        public armarx::ArmarXComponentWidgetControllerTemplate < CartesianWaypointControlGuiWidgetController >,
-        public virtual RobotUnitComponentPluginUser,
-        public virtual RobotStateComponentPluginUser
+        public NJointControllerGuiPluginBase <
+        CartesianWaypointControlGuiWidgetController,
+        NJointCartesianWaypointControllerInterfacePrx
+        >
     {
         Q_OBJECT
-
     public:
         /// Controller Constructor
         explicit CartesianWaypointControlGuiWidgetController();
-        /// Controller destructor
-        virtual ~CartesianWaypointControlGuiWidgetController();
-
-        /// @see ArmarXWidgetController::loadSettings()
-        void loadSettings(QSettings* settings) override;
-        /// @see ArmarXWidgetController::saveSettings()
-        void saveSettings(QSettings* settings) override;
 
         /**
          * Returns the Widget name displayed in the ArmarXGui to create an
@@ -87,36 +66,24 @@ namespace armarx
             return "RobotControl.NJointControllers.CartesianWaypointControlGui";
         }
 
-        void onInitComponent() override;
         void onConnectComponent() override;
-        void onDisconnectComponent() override;
-
-        QPointer<QDialog> getConfigDialog(QWidget* parent) override;
-        void configured() override;
+        NJointControllerConfigPtr readFullCFG() const override;
 
     private slots:
-        void on_pushButtonStop_clicked();
         void on_pushButtonExecute_clicked();
         void on_pushButtonZeroFT_clicked();
         void on_pushButtonSendSettings_clicked();
-        void on_pushButtonCreateController_clicked();
+        void createController() override;
 
         void triggerParsing();
 
     private:
         NJointCartesianWaypointControllerRuntimeConfig readRunCfg() const;
-        void deleteOldController();
         void timerEvent(QTimerEvent*) override;
 
     private:
         Ui::CartesianWaypointControlGuiWidget           _ui;
-        QPointer<SimpleConfigDialog>                    _dialog;
-        NJointCartesianWaypointControllerInterfacePrx   _controller;
-        std::string                                     _controllerName;
-        VirtualRobot::RobotPtr                          _robot;
         std::vector<Eigen::Matrix4f>                    _lastParsedWPs;
         bool                                            _supportsFT{false};
-        mutable std::recursive_mutex                    _allMutex;
-        int                                             _timer;
     };
 }