User Interface Controls

NeuroKernel offers high performance user interface controls to developers for rapid prototyping and best user experience. All controls are based on elements available via Document Object Model supplied by the web browser. They are easy to style and does need any external style sheet file. Programming with NeuroKernel UI controls is similar to Swing and SWT but much more easier and accessible to the developer. The default theme is called Karia, and it is designed to give a vintage and modern look together.

1. Containers

Container is an abstract class which can contain other components in its layout. The default layout manager is a 1×1 grid layout.

1.1 Window

NWindow is the super class for frame, dialog and tool windows. Except the top level main application window, each window must have a parent. Top level windows are created only by the system. It is possible to directly extend this class which will produce a window with no decorations. Window class has advanced controls for defining custom decorations.

1.1.1 Framed Window

Normal windows are created by the application main window being the top of the window hierarchy of an application. It is possible to use a normal window as the parent of any other window.

import com.neurokernel.client.*;
import com.neurokernel.client.annotation.LoadResources;
import com.neurokernel.client.annotation.Source;
 
@LoadResources(
    resources = {
         @Source(value = "resources/banner.png", name = "banner")
    }
)
public class MyApplication extends NApplication {
    @Override
    public void main(int argc, String[] argv) {
       NFrame mainFrame=getMainFrame();
       mainFrame.setTitle("Frame Example");
       mainFrame.setBounds(20,20,300,300);
       mainFrame.setVisible(true);
 
       NFrame splashWindow = new NFrame(mainFrame);
       splashWindow.setDecorations(NWindow.DECOR_NONE);
       new NImageView(splashWindow, (NImage)getResource("banner"));
       splashWindow.setSize(250, 250);
       splashWindow.centerWindow()
       splashWindow.setVisible(true);
    }
}

1.1.2 Dialog Window

Dialog windows blocks event processing on their immediate parent. A dialog window can spawn another dialog window when necessary. Unlike other web applications, dialog windows in NeuroKernel are real dialogs that behaves like their desktop counterparts blocking only their parent window instead of entire web page. Dialog windows can nor child a tool window.

   import com.neurokernel.client.*;
   import com.neurokernel.client.adapter.NActionListener;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
          final NFrame mainFrame=getMainFrame();
 
          NButton button=new NButton(mainFrame,"Open Dialog");
          button.addActionListener(new NActionListener() {
              @Override
              public void onAction(NEvent e) {
                 NDialog dlg=new NDialog(mainFrame, "Dialog");
                 dlg.setSize(150,150);
                 dlg.setVisible(true);
              }
          });
 
          mainFrame.setTitle("Dialog Example");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
   }
 

1.1.2.1 Command Dialog

Dialog with a command layout. OK button is the command button and can also be activated by pressing the enter key. The default close operation is set to NORMAL_CLOSE. In order to get to the work area of the command dialog always use getContentPane method.The default close operation set for the dialog is hide-on-close.

import com.neurokernel.client.*;
import com.neurokernel.adapter.NActionListener;
 
public class DialogExample extends NApplication {
      NFrame mainFrame;
      AskQuestion question;
 
      @Override
      public void main(int argc, String[] argv) {
          mainFrame=getMainFrame();
          question=new AskQuestion(mainFrame);
 
          new NButton(mainFrame,"Hello!").addActionListener(new NActionListener() {
              @Override
              public void onAction(NEvent e) {
                  question.setVisible(true);
              }
          });
 
         question.addDialogListener(new NDialogListener() {
                @Override
                public void onOK(NEvent event) {
					NMessageDialog.showInfo(mainFrame,question.getUserName());
                }
          });
 
          mainFrame.setTitle("Hello There");
          mainFrame.show(20,20);
      }
 
      /**
       * Command Dialog Example
       */
      static class AskQuestion extends NCommandDialog {
          NTextField name;
 
          public AskQuestion(NWindow parent) {
              super(parent, "Enter Name", false);
              getContentPane().getLayout().setPadding(5, 0, 5, 0);
              name = new NTextField(content);
              name.setPromptText("Enter Your Name");
              getOKButton().getForm().addField(name);
              setSize(300, 80);
          }
 
          public String getUserName() {
          	return name.getText();
          }
      }
}

1.1.2.2 Font Dialog

Font chooser panel. Font choose is by default extends a panel container so that custom additions to a font choose dialog can be made more easily. In order to have a plain font choose dialog create the instance using the constructor that accepts a window for parent. Selected font can be retrieved using getFont method. If internal command dialog is used the dialog can be accessed using getDialog method. The current font can be set with setFont or setValue method. It is also possible to set and get various other aspects of the desired font using the supplied methods.

   import com.neurokernel.client.*;
   import com.neurokernel.client.adapter.*;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
           NFrame mainFrame=getMainFrame();
           final NFontDialog fontChooser=new NFontDialog(mainFrame);
           final NButton button=new NButton(mainFrame,"Font");
 
           button.addActionListener(new NActionListener() {
               @Override
               public void onAction(NEvent e) {
                  fontChooser.getDialog().setVisible(true);
               }
           });
 
           fontChooser.addDialogListener(new NDialogListener() {
               @Override
               public void onOK(NEvent e) {
                  button.setFont(fontChooser.getFont());
               }
            });
 
           mainFrame.setTitle("Font Chooser Demo");
           mainFrame.setBounds(20,20,200,200);
           mainFrame.setVisible(true);
       }
   }
 

1.1.2.3 File Dialog

Allows selecting user files via provided controls from a dialog window. It also lets user to download or upload files from host computer to user's file system account or vice versa; plus, it lets user to manipulate and remove files and directories. It is possible to add multiple file systems.

1.1.2.4 Color Dialog

Color picker implementation. Color picker is by default extends a panel container so that custom additions to a color picker dialog can be made more easily. In order to have a plain color picker dialog create the instance using the constructor that accepts a window for parent. Selected color can be retrieved using getColor method. If internal command dialog is used the dialog can be accessed using getDialog method. The current color can be set with setColor or setValue method; otherwise the the default color will be set as white. Transparency controls can be added using showOpacity method.

   import com.neurokernel.client.*;
   import com.neurokernel.client.adapter.*;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
           NFrame mainFrame=getMainFrame();
           final NColorDialog colorPicker=new NColorDialog(mainFrame);
           final NButton button=new NButton(mainFrame,"Color");
 
           button.addActionListener(new NActionListener() {
               @Override
               public void onAction(NEvent e) {
                  colorPicker.getDialog().setVisible(true);
               }
           });
 
           colorPicker.addDialogListener(new NDialogListener() {
               @Override
               public void onOK(NEvent e) {
                  button.setBackground(colorPicker.getColor());
               }
            });
 
           mainFrame.setTitle("Color Picker Demo");
           mainFrame.setBounds(20,20,200,200);
           mainFrame.setVisible(true);
       }
   }
 

1.1.2.5 Message Dialog

A Message dialog can be set as ERROR, WARNING, INFO or HELP. Dialogs created can be reused for new messages. A system dialog does not suspend the execution of the application. It is possible to add event listeners to the buttons of the message dialogs to process the actions in detail.

   import com.neurokernel.client.*;
   import com.neurokernel.client.adapter.NActionListener;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
           final NFrame mainFrame=getMainFrame();
           NButton button=new NButton(mainFrame,"Click Here");
 
           button.addActionListener(new NActionListener() {
               @Override
               public void onAction(NEvent e) {
                   NMessageDialog.showInfo(mainFrame,"Hello World");
               }
           });
 
           mainFrame.setTitle("Message Dialog Demo");
           mainFrame.setBounds(20,20,200,200);
           mainFrame.setVisible(true);
       }
   }
 

1.1.2.6 Confirm Dialog

ConfirmType dialog factory. Dialogs created can be reused for new messages. A system dialog does not suspend the execution of the application. It is possible to add event listeners to the buttons of the message and confirm dialogs to process the actions.

   import com.neurokernel.client.*;
   import com.neurokernel.client.adapter.*;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
           final NFrame mainFrame=getMainFrame();
           final NButton button=new NButton(mainFrame,"Click Here");
 
           button.addActionListener(new NActionListener() {
               @Override
               public void onAction(NEvent e) {
                   NConfirmDialog.showWarning(mainFrame,"Make button blue?", new NDialogListener() {
                      @Override
                      public void onOK(NEvent e) {
                          button.setColor(NColor.BLUE);
                      }
                  });
               }
           });
 
           mainFrame.setTitle("Confirm Dialog Demo");
           mainFrame.setBounds(20,20,200,200);
           mainFrame.setVisible(true);
       }
   }
 

1.1.3 Tool Window

Tool windows are special windows that always remains on top of their immediate parent. Only main windows and normal windows can spawn tool windows. Tools windows can also be orginized in themselves and can be made sticky to their parent. Sticky tool windows will retain position relative to their parent.

import com.neurokernel.client.*;
 
public class MyApplication extends NApplication {
    @Override
    public void main(int argc, String[] argv) {
       NFrame mainFrame=getMainFrame();
       mainFrame.setTitle("Tool Frame Example");
       mainFrame.setBounds(20,20,300,300);
       mainFrame.setVisible(true);
 
       NToolFrame toolA = new NToolFrame(mainFrame, "Sticky");
       toolA.setWindowSticky(true);
       toolA.setBounds(30, 30, 250, 250);
       toolA.setVisible(true);
 
       NToolFrame toolB = new NToolFrame(mainFrame, "Always on Top");
       toolB.setAlwaysOnTop(true);
       toolB.setBounds(50, 50, 200, 200);
       toolB.setVisible(true);
    }
}

1.1.4 Tooltip Window

A tool tip window shows a tip on the desired side of the window which may be useful for getting the user to the right interface for the next action.

1.2 Panel Window

Panel windows are federated window contexts that live in the layout of their parent container. It has its own control hierarchy, keyboard handling and scrolling. They may be useful when there are too many controls on a window that may slow down the event processing such as tables or lists. NScrollPane directly inherits NPanelWindow, and used as a scrollable tree view in the example below.

import com.neurokernel.client.*;
 
public class ScrollPane extends NApplication {
    @Override
    public void main(int argc, String[] argv) {
        NFrame mainFrame=getMainFrame();
 
        //ScrollPane contains a Panel Window
        NTreeView tree = new NTreeView(new NScrollPane(mainFrame));
        NTreeCell t1 = new NTreeCell(null, "Node 1");
        t1.setChecked(false);
        NTreeCell t2 = new NTreeCell(null, "Node 2");
        NTreeCell t3 = new NTreeCell(t2, "Node 3");
        t3.setChecked(false);
        NTreeCell t4 = new NTreeCell(t1, "Node 4");
        NTreeCell t5 = new NTreeCell(t4, "Node 5");
        tree.addRows(new NCell[] { t2, t3, new NTreeCell(t3, "Node 6"));
        tree.addRows(new NTreeCell[] { t1, new NTreeCell(t1, "Node 7"), t4,
                                     new NTreeCell(t4, "Node 8"), t5,
                                     new NTreeCell(t5, "Node 9"), });
 
       mainFrame.setTitle("ScrollPane Example");
       mainFrame.setBounds(20,20,300,300);
       mainFrame.setVisible(true);
    }
}

A popup window can be painted independently from its parent window, but requires its parent window to be visible on the screen. Popup windows can be nested. A popup window can be invoked by any control by using its setInvoker method, including cells. It also can be mapped to an arbitrary coordinate inside its invoker component as well.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
          NFrame mainFrame=getMainFrame();
 
          NPopupWindow menu = new NPopupWindow(mainFrame);
          new NButton(menu,"Hello");
 
          new NMenuButton(mainFrame,menu);
 
          mainFrame.setTitle("Popup Window Example");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
   }
 

Popup menu is styled version of the popup window. It puts a border and padding to the pop up window.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
          NFrame mainFrame=getMainFrame();
 
          NPopupMenu menu = new NPopupMenu(mainFrame);
          new NButton(menu,"Hello");
 
          new NMenuButton(mainFrame,menu);
 
          mainFrame.setTitle("Popup Menu Example");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
   }
 

Menu contains a column of menu cells and extends popup window. The menu can be automatically resized to the maximum width of the menu cells.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
          NFrame mainFrame=getMainFrame();
          mainFrame.setFrameLayout(NFrameLayout.MENUBAR);
          NMenuBar menubar = new NMenuBar(mainFrame);
 
          NMenu menu = new NMenu(mainFrame);
          new NMenuCell(menu, "Options").setChecked(true);
          new NMenuCell(menu, "Settings", true);
 
          menubar.addMenu("File", menu);
 
          mainFrame.setTitle("Menu Cell Example");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
   }
 

1.3.3 Tooltip Menu

A tool tip pop up menu is used to show a tip towards the invoker control or on a desired side of the menu. It may be used to show the user where menu has been activated from.

1.4 Document Window

Document window can only be created when in rootless mode. Rootless mode is a special mode where NeuroKernel can be embedded in a normal web page. The desktop window is not made visible on this mode to make the web page operational. In this mode, desktop window can spawn any kind of window, and it can also embed windows inside DIV elements using document window object. The size of the window is automatically updated when the size of the parent DIV element changes. This makes creative mashups with NeuroKernel possible. The code segment below shows an example use of document window in a desktop manager implementation.

final NFrame rootlessTest=new NFrame(getMainFrame());
new NButton(rootlessTest,"test").addListener(new IEventListener() {
    boolean pinned;
    @Override
    public void onEvent(NEvent e) {
        pinned=!pinned;
        rootlessTest.pinToDocument(pinned);
        NDocumentWindow doc=getRootDocument();
        doc.setBackground(NColor.BLUE);
        doc.scrollTo(2000, 0, NAnimation.Easing.EXPONENTIAL_IN);
    }
}, NEventTypes.ACTION);
 
rootlessTest.setSize(200, 150);
rootlessTest.setVisible(true);
 
NWindow window=getRootDocument().createWindow(htmlRenderer.getElement("staticpanel"));
new NComboBox(window,"test").getColumn().importData("Hello","World");
window.setSize(200, 200);
window.setVisible(true);

In the second part of the code, after making the rootlessTest frame visible, a window is created inside a DIV element called staticpanel.

1.5 Panel

NPanel is the basic container for all components.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
         NGridLayout layout=mainFrame.getLayout();
         layout.setSize(2,1).setGaps(5,5);
 
         NPanel panel=new NPanel(mainFrame);
         layout=panel.getLayout();
         layout.setSize(1,2);
 
         new NButton(panel,"Hello");
         new NButton(panel,"World");
 
         new NLabel(mainFrame).setHTML("<b>Panel</b>");
 
         mainFrame.setTitle("Panel Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

1.6 Column

The core cell container which can hold any type of NCell component. It allows keyboard navigation over cells as well as easy manipulation and update of a collection of cells using high performance methods. Accelerated property setting can be achieved with special methods rather than applying the property to each cell. Accessing large number cells is very efficient by design and without need of data model. NColumn is used with lists, tables, trees and menus.

1.6.1 Table Column

Table column is the default column container that is used by the table view. It uses table cell by default which is the simplest cell control available in API.

1.6.2 Tree Table Column

Tree table column is used by the tree table view as the tree column that controls the rows. It accepts tree cells by default in its structure.

1.6.3 Row Header Column

Row header column can be used with table view to resize the rows vertically. It accepts row header cell control by default.

1.7 Column Panel

Instead of column, a custom panel can be added to the panel table using this class.

1.8 Scroll View

Scroll view container is the main scroll viewer implementation. It can also attach native scrolling capable containers or components to its view. If the client is mobile the scrollbar will not be shown.

 import com.neurokernel.client.*;
 
 public class ScrollViewExample extends NApplication {
     NListView list;
 
     @Override
     public void main(int argc, String[] argv) {
         final NFrame mainFrame = getMainFrame();
         mainFrame.getLayout().setPadding(5);
 
         NScrollView scrollView=new NScrollView(mainFrame);
         list = new NListView(scrollView);
         list.importData("List Cell 1","List Cell 2","List Cell 3","List Cell 4",
                         "List Cell 5","List Cell 6","List Cell 7","List Cell 8");
         list.attachClientEvent(ClientEvent.POINTER_DOUBLE_CLICK);
 
         list.addListener(new IEventListener() {
              @Override
              public void onEvent(NEvent event) {
                 if (event.getEventType() == NEventTypes.POINTER_DOUBLE_CLICK) {
                       NListCell cell = list.getSelectedCell();
                       NMessageDialog.showInfo(mainFrame, cell.getValue());
                 }
              }
         });
 
         mainFrame.setTitle("Scroll View Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
     }
 }
 

1.9 Static View

Lighter viewport for views that does not require scrolling. This view port will not scroll. Best suited for list and combo box with fixed number of visible cells.

1.10 Table

Table container which can have single or multiple columns.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
 
         NTable table = new NTable(mainFrame, "Parameters", "Values");
         table.setFitWidth(true);
         table.setGridVisible(true);
         table.addRow(new NTableCell[] {new NTableCell("Width"), new NTableCell("100")});
         table.addRow(new NTableCell[] {new NTableCell("Height"), new NTableCell("100")});
 
         mainFrame.setTitle("Table Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

1.11 Tree Table

NTreeTable synchronizes a tree column with other non-tree table columns. It was designed to function with the tree rules. All the methods of super class table is functional. An NTreeTableColumn must be added using insertTreeColumn method to the table.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
 
         NTreeTable treetable = new NTreeTable(mainFrame, "Parameter","Value");
         treetable.setFitWidth(true);
         treetable.setGridVisible(true);
         treetable.setRowHeight(30);
 
         NTreeCell size = new NTreeCell(null, "Size");
 
         treetable.addRow(new NCell[] { size, new NTableCell("") });
         treetable.addRow(new NCell[] { new NTreeCell(size, "width"),
                                        new NTableCell("100") });
         treetable.addRow(new NCell[] { new NTreeCell(size, "height"),
                                        new NTableCell("200") });
 
         mainFrame.setTitle("Tree Table Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

1.12 Panel Table

Table container which can have single or multiple panel columns. Panel columns used are not cell holder columns, but plain panel containers that can have any component or container. This table type can be used to create custom table views.

1.13 Tab Pane

Container and manager of all tab panels. It has a tab pane area to stack the tabs on top of each other. Tab headers can only be displayed at the top or bottom. It also offers two different tab header layout managers. Aside from the default tab header layout, a horizontally scrollable layout can also be used. NTabPane lets its tab panel to be shared when used with shared tabs.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
          NFrame mainFrame=getMainFrame();
 
          NTabPane tabPane=new NTabPane(mainFrame);
          tabPane.setMargin(5);
          new NButton(new NTab(tabPane,"Tab A"),"Button A");
          new NButton(new NTab(tabPane,"Tab B"),"Button B");
 
          mainFrame.setTitle("Combo Box Example");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
   }
 

1.14 Tab

Basic building block of the {@code NTabPane} container. It adds a tab header and a tab panel to the parentContainer tab pane. Unlike shared tab header, each tab component has its own panel.

1.15 SharedTab

A tab component which can share a tab panel with other shared tabs. {@code NSharedTab} is useful when there is only one panel with data but the data needs to change for each tab header. this saves resources when needed.

1.16 Page Pane

Paged pane for easy printing which accepts only page as sub component. Each page has a page break in between them. The layout manager of this panel can not be changed. Sub panels are placed relative to each other.

   import com.neurokernel.client.*;
   import com.neurokernel.client.adapter.NActionListener;
 
   public class PagePanelExample extends NApplication {
      NScrollPane pane;
      NPagePane pagePane;
 
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
         NGridLayout gridLayout=(NGridLayout)mainFrame.getLayout();
         gridLayout.setLength(2, 1);
         gridLayout.addSubGrid(0, 0, 1, 2);
         gridLayout.setRowHeight(0, 24);
 
         NButton but=new NButton(mainFrame,"Remove");
         NButton but2=new NButton(mainFrame,"Print");
 
         pane=new NScrollPane(mainFrame);
         pane.setScrollArea(300, 600);
 
         NPagePane pagePane=new NPagePane(pane);
         pagePane.setLength(300,600);
 
         new NLabel(new NPage(pagePane,100),"Page 1");
         new NLabel(new NPage(pagePane,100),"Page 2");
         new NLabel(new NPage(pagePane,100),"Page 3");
 
         but.addActionListener(new NActionListener() {
             @Override
             public void onAction(NEvent e) {
                pagePane.remove(pagePane.getPage(1));
             }
         });
 
         but2.addActionListener(new NActionListener() {
             @Override
             public void onAction(NEvent e) {
                pane.printContent();
             }
         });
 
         mainFrame.setTitle("Paged Panel Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

1.17 Page

Page container to be used by the page pane. Each page container is printed in a single page. Please see the example above.

1.18 List View

A column container that uses NListCell as its basic building block but it may also use other cell controls. List extends NColumn and inherently not scrollable. In order to make a list scrollable, its parent should be a viewport such as NScrollView. It is possible to make the list fit inside the view horizontally eliminating the horizontal scrolling by calling setFitWidth.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
          NFrame mainFrame=getMainFrame();
 
          NListView list=new NListView(new NScrollView(mainFrame),
                                       "Hello","World");
 
          mainFrame.setTitle("List Example");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
   }
 

1.19 Tree View

A column container that displays a set of hierarchical data in tree form.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
          NFrame mainFrame=getMainFrame();
 
          NTreeView tree=new NTreeView(new NScrollView(mainFrame));
          NTreeCell treeCellA = new NTreeCell("Tree A");
          NTreeCell treeCellB = new NTreeCell("Tree B");
          NTreeCell treeCellC = new NTreeCell(treeCellB, "Branch B");
          NTreeCell treeCellD = new NTreeCell(treeCellA, "Branch A");
          NTreeCell treeCellE = new NTreeCell(treeCellD, "Leaf A");
 
          tree.addRows(treeCellA, treeCellD, treeCellE, treeCellB, treeCellC);
 
          mainFrame.setTitle("Canvas Example");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
   }
 

This container class Lays out menu headers and menus associated with them. It is also possible to add other components in the menu bar if needed.

  import com.neurokernel.client.;
 
  public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
 
         NMenuBar menubar = new NMenuBar(mainFrame);
 
         NMenu menu = new NMenu(mainFrame);
         new NMenuCell(menu, "Options").setChecked(true);
         new NMenuCell(menu, "Settings", true);
 
         menubar.addMenu("File", menu);
 
         NMenu menu2 = new NMenu(mainFrame);
         NMenuCell subMenu = new NMenuCell(menu2, "Edit");
         new NMenuCell(menu2, "Update", true);
 
         NMenu menu3 = new NMenu(subMenu);
         new NMenuCell(menu3, "Copy");
         new NMenuCell(menu3, "Paste", true);
 
         menubar.addMenu("Edit", menu2);
 
         mainFrame.setTitle("Menu Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }

1.21 Split Pane

Creates two resizeable panels managed by a splitting bar. Its orientation can be vertical or horizontal. By default, split pane creates two panels for the first and second pane, but they can be changed. The divider bar can be moved to resize the panels. When bar moved to the edge, pane next to the edge will be hidden. Splitted panes can be reached using the {@code getFirstComponent} method.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
 
         NSplitPane split=new NSplitPane(mainFrame);
         new NButton(split,"Left");
         new NButton(split,"Right");
 
         mainFrame.setTitle("Split Pane Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

1.22 Terminal Pane

Terminal pane behaves like the terminal application offered by the platform. It has some build in commands that is handled automatically.

1.23 Console Pane

It is a console message pane which can be used for constant text feeds such logs. It has a text buffer that can be controlled.

1.24 Desktop Pane

NDesktopPane is the container that holds the internal frames. It is possible to manage the internal frames differently by extending the super class of NDesktopPane which is NDesktopView. Internal frames functions similar to normal windows.

import com.neurokernel.client.*;
 
public class MDIExample extends NApplication {
    @Override
    public void main(int argc, String[] argv) {
        NFrame mainFrame=getMainFrame();
 
        NDesktopPane pane=new NDesktopPane(mainFrame);
 
        NInternalFrame frameA=new NInternalFrame(pane);
        new NButton(frameA,"Hello");
        frameA.setBounds(5,5,200,200);
 
        NInternalFrame frameB=new NInternalFrame(pane);
        new NButton(frameB,"World");
        frameB.setBounds(15,15,200,200);
 
        mainFrame.setTitle("MDI Example");
        mainFrame.setBounds(20,20,400,400);
        mainFrame.setVisible(true);
    }
}

1.24.1 Internal Frame

Internal windows are add to the API when in very large screens an MDI type user interface may help consolidate the concentration on the application itself. It may be hard to control all the spawn windows on a large screen. There are other use cases where they can be very useful as well. They basically decorated and managed as normal windows but live in their desktop panel. It is possible to change the default decorations programmatically like normal windows.

2. Components

NComponent is the abstract super class of all UI components. When extended, it acts as the NCanvas component to be painted on. This behavior is similar to that of the Java Abstract Window Toolkit(AWT). The events are directly dispatched to the components by the task container. NComponent does not hold all of its properties in class and it has only setters for the properties. This is also the case for NControl which is extended by NComponent.

The display server of NeuroKernel directly implements a set of components which are available to use from the API. The new components can be added to the display server using NXComponent class. NComponent has a very rich structure, if implemented for a component, it can render HTML as well as SVG. The components can be set as printable or not printable. They can can handle new event types provided by the display server, and tie property setters to other components via these events. Components can animate their properties and bounds.

The event listeners and observers are two ways to keep track of changes to a component. Listeners are for handling new events that happens on the component, and observers are for tracking value changes.Drag and drop is supported with a simple yet powerful schema. The API is designed for easily accessing all system and application interfaces from the NComponent. All interface access points are either provided by the component or its parent container. Graphics processing is the one of the best features of the component's architecture. The paint method can be overridden to draw/redraw graphics if the NComponent class is directly extended by a third party class. The graphics context (2D or 3D) can be selected using createGraphicsContext method.

   import com.neurokernel.client.*;
   import com.neurokernel.client.graphics.*;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
 
         NComponent canvas = new NComponent(mainFrame) {
             IDisplayList mygraphics;
 
              @Override
              public void paint(IGraphics graphics) {
                  IGraphics2D context = (IGraphics2D) graphics;
                  if(mygraphics==null) {
                      mygraphics=context.newList();
                      context.setStrokeStyle(new NColor(128, 128, 255));
                      context.setFillStyle(new NColor(0, 0, 255));
                      context.setLineWidth(5);
                      double pi = 2 Math.PI;
                      context.beginPath();
                      context.arc(50, 50, 100, 0, pi, false);
                      context.closePath();
                      context.fill();
 
                      context.beginPath();
                      context.arc(50, 50, 100, 0, pi, false);
                      context.closePath();
                      context.stroke();
                      context.endList();
                  }
                  context.translate(100, 100);
                  context.callList(mygraphics);
              }
          };
 
          mainFrame.setTitle("My Application");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
   }
 

2.1 Label

Label component can be used to display a text or an image. It has no interactive features by default but can be interactive by attaching new client events. Label is the only component that has an advanced HTML renderer which is available solely to containers.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
         NGridLayout layout=mainFrame.getLayout();
         layout.setSize(2,1).setGaps(5,5);
 
         new NLabel(mainFrame,"Hello");
         new NLabel(mainFrame).setHTML("<b>World</b>");
 
         mainFrame.setTitle("Label Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

2.2 Buttons

There number of button components in NeuroKernel API that can be used for various ways. The most commonly used button is NButton component. Below you will find a list a button componnets.

2.2.1 Button

Button component is used to start an action or setting a state when pressed. The state of the button is handled automatically by the rendering engine. Button pressing and releasing always generates an NEventTypes.ACTION. In addition, when tab key navigation is activated, or the button is focused, pressing space key will also generate an NEventTypes.ACTION.

   import com.neurokernel.client.*;
   import com.neurokernel.client.adapter.NActionListener;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
           final NFrame mainFrame=getMainFrame();
           NButton button=new NButton(mainFrame,"Hello");
 
           button.addActionListener(new NActionListener() {
               {@literal @}Override
               public void onAction(NEvent e) {
                   NMessageDialog.showInfo(mainFrame,"Hello World");
               }
           });
 
           mainFrame.setTitle("Button Demo");
           mainFrame.setBounds(20,20,200,200);
           mainFrame.setVisible(true);
       }
   }
 

A button component which invokes a popup menu

    import com.neurokernel.client.;
 
    public class MyApplication extends NApplication {
        @Override
        public void main(int argc, String[] argv) {
           NFrame mainFrame=getMainFrame();
 
           NMenu menu = new NMenu(mainFrame);
           new NMenuCell(menu, "Options").setChecked(true);
           new NMenuCell(menu, "Settings", true);
 
           new NMenuButton(mainFrame,menu);
 
           mainFrame.setTitle("Menu Button Example");
           mainFrame.setBounds(20,20,200,200);
           mainFrame.setVisible(true);
        }
    }
 

2.2.3 File Button

Available only if HTML5 file API is supported by the client. After reading a file, this component receives FILE_LOAD_SUCCESS or FILE_LOAD_FAILED event, depending on the result of the uploading process.Meta data about the selected file(s) are sent via CHANGE event which could be used to auto read the file(s). If the reading process is done in chunks UPDATE event must be observed.

    import com.neurokernel.client.*;
    import com.neurokernel.client.adapter.*;
 
    public class MyApplication extends NApplication {
       NFileButton loader;
       @Override
       public void main(int argc, String[] argv) {
          NFrame mainFrame=getMainFrame();
          NFileButton loader = new NFileButton(mainFrame, "Upload File");
          loader.addActionListener(new NActionListener() {
                @Override
                public void onAction(NEvent e) {
                   loader.write(new NFile("/"), false, 
                           new NDataListener() {
                               @Override
                               public void onSuccess(IResponse connection) {
                                    NMessageDialog.showInfo(getMainFrame(), "Upload Success");
                               }
                           });
                    }
          });
          mainFrame.setTitle("Toggle Button Example");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
   }
 

2.2.4 Toggle Button

Toggle button is the base class for all button controls that show state. Toggle button by its own can be a stand alone switch or can be part of a one-of-many group that will only allow selecting one toggle button.

    import com.neurokernel.client.*;
 
    public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
          NFrame mainFrame=getMainFrame();
          NGridLayout layout=mainFrame.getLayout();
          layout.setSize(3,1);
 
          NToggleGroup toggleGrp=new NToggleGroup(mainFrame);
          new NToggleButton(toggleGrp, "Toggle Button A").setSelected(true);
          new NToggleButton(toggleGrp, "Toggle Button B");
          new NToggleButton(toggleGrp, "Toggle Button C");
 
          mainFrame.setTitle("Toggle Button Example");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
   }
 

2.2.4.1 Radio Button

Radio button is switch that requires a one-of-many relationship. It should be a part of a NToggleGroup. Selecting a radio button from a group of related ones will switch off the one already selected in the same group.

   import com.neurokernel.client.;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
         NGridLayout layout=mainFrame.getLayout();
         layout.setSize(3,1);
 
         NToggleGroup toggleGrp=new NToggleGroup(mainFrame);
         new NRadioButton(toggleGrp, "Radio Button A").setSelected(true);
         new NRadioButton(toggleGrp, "Radio Button B");
         new NRadioButton(toggleGrp, "Radio Button C");
 
         mainFrame.setTitle("Radio Button Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

2.3 Textfield

Text field lets user enter data by typing in a single line of text.

    import com.neurokernel.client.;
 
    public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
          NFrame mainFrame=getMainFrame();
          NGridLayout layout=mainFrame.getLayout();
          layout.setSize(2,1).setGaps(5,5);
 
          new NTextField(mainFrame,"Hello");
          new NTextField(mainFrame,"World");
 
          mainFrame.setTitle("Text Field Example");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
   }
 

2.4 Password Field

Password text field.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
         NGridLayout layout=mainFrame.getLayout();
         layout.setSize(2,1).setGaps(5,5);
 
         new NTextField(mainFrame).setPromptText("User Id");
         new NPasswordField(mainFrame).setPromptText("Password");
 
         mainFrame.setTitle("Password Field Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

2.5 Spinner

A text field with two spinner buttons. NEventTypes.SPIN_UP is sent when button on the top is pressed, and SPIN_DOWN is sent when button on the bottom is pressed.

   import com.neurokernel.client.*;
    import com.neurokernel.client.constants.Order;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
         NGridLayout layout=mainFrame.getLayout();
         layout.setSize(2,1).setGaps(5,5);
 
         new NSpinner(mainFrame,"0");
         new NSpinner(mainFrame,"0");
 
         mainFrame.setTitle("Spinner Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

2.6 Check Box

Check box is a switch control which can show either selected or not selected state. A check box does not require a ToggleGroup and is used for single option that stands alone. Check boxes can be grouped together but will not have a one-of-many relationship like other toggle buttons such as radio button.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
         NGridLayout layout=mainFrame.getLayout();
         layout.setSize(3,1);
 
         new NCheckBox(mainFrame, "Check Box A").setSelected(true);
         new NCheckBox(mainFrame, "Check Box B");
         new NCheckBox(mainFrame, "Check Box C");
 
         mainFrame.setTitle("Check Box Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

2.7 Combo Box

A Combination of a button or editable field component with a pop-up menu and list box. Selection is made from the list and visible content of the combo box changes with the new selection. The visible content area of the combo box can be set with HTML as well. NComboBox has an option to have an editable content area. Items in the list can be selected by the up and down keys when the focus is on combo box without popping up the list pop-up menu. Space key will pop-up the list by firing NEventTypes.ACTION. On editable combo box, arrow down key will fire the same event. Selections with keyboard will fire NEventTypes.CHANGE on the combo box.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
         mainFrame.setLayout(null);
 
         new NComboBox(mainFrame, new String[]{"Hello", "World"}).
             setBounds(10,10,150,22);
 
         mainFrame.setTitle("Combo Box Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

2.8 Calendar

Constructs a calendar in a widely known wall format. It allows keyboard navigation and fires NEventTypes.ACTION when the selection is made via either left mouse button click or space key. It will fire NEventTypes.POINTER_DOUBLE_CLICK if left mouse button is double clicked. During navigating with keyboard NEventTypes.CHANGE is fired. The selected date can be received using {@code getYear, getMonth and getDay} methods.

   import com.neurokernel.client.*;
   import com.neurokernel.client.adapter.NActionListener;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
           NFrame mainFrame=getMainFrame();
           final NCalendar calendar=new NCalendar(mainFrame);
 
           calendar.addActionListener(new NActionListener() {
               @Override
               public void onAction(NEvent e) {
                   getConsole().println(calendar.getText());
               }
           });
 
           mainFrame.setTitle("Calendar Demo");
           mainFrame.setBounds(20,20,300,300);
           mainFrame.setVisible(true);
       }
   }
 

2.9 Canvas

Canvas component is implemented to offer browser based graphics drawing features to NeuroKernel applications. The paint method can be overridden for advanced drawing control.

   import com.neurokernel.client.*;
   import com.neurokernel.client.graphics.*;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
          NFrame mainFrame=getMainFrame();
 
          NCanvas canvas=new NCanvas(mainFrame);
          IGraphics2D ctx = (IGraphics2D) canvas.getGraphics();
          ctx.setFillStyle(NColor.BLUE);
          ctx.rectangle(10, 10, 55, 50);
          ctx.fill();
          ctx.setFillStyle(NColor.RED);
          ctx.rectangle(30, 30, 55, 50);
          ctx.fill();
 
          mainFrame.setTitle("Canvas Example");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
   }
 

2.10 Slider

Slider lets selection of a value within a specified minimum and maximum values by adjusting a thumb. A slider can be horizontal or vertical.

   import com.neurokernel.client.*;
   import com.neurokernel.client.constants.Orientation;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
         NGridLayout layout=mainFrame.getLayout();
         layout.setSize(2,1).setGaps(5,5);
 
         NPanel panel=new NPanel(mainFrame);
         layout=panel.getLayout();
         layout.setSize(1,2);
 
         new NButton(panel,"Hello");
         new NButton(panel,"World");
 
         new NSlider(mainFrame, Orientation.HORIZONTAL,0,100,50);
 
         mainFrame.setTitle("Slider Bar Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

2.11 Scale Bar

A Composite scale bar which includes a slider, canvas and label panel

   import com.neurokernel.client.*;
   import com.neurokernel.client.constants.Orientation;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
         NGridLayout layout=mainFrame.getLayout();
         layout.setSize(2,1).setGaps(5,5);
 
         NPanel panel=new NPanel(mainFrame);
         layout=panel.getLayout();
         layout.setSize(1,2);
 
         new NButton(panel,"Hello");
         new NButton(panel,"World");
 
         NScaleBar scale=new NScaleBar(mainFrame, Orientation.HORIZONTAL,0,100,50);
         scale.setPaintTicks(true);
 
         mainFrame.setTitle("Scale Bar Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

2.12 Scroll Bar

Scroll bar lets the user manage which part of the data or document to be displayed in a scroll view container by pressing its buttons or sliding its thumb. It can also be used as a slider if desired. It fires NEventTypes.ADJUST event when the thumb scrolls setting the new value of the scrollbar. A scrollbar can be a horizontal or vertical scrollbar.

   import com.neurokernel.client.*;
   import com.neurokernel.client.constants.Orientation;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
         NGridLayout layout=mainFrame.getLayout();
         layout.setSize(2,1).setGaps(5,5);
 
         NPanel panel=new NPanel(mainFrame);
         layout=panel.getLayout();
         layout.setSize(1,2);
 
         new NButton(panel,"Hello");
         new NButton(panel,"World");
 
         new NScrollBar(mainFrame, Orientation.HORIZONTAL,0,200,0,100);
 
         mainFrame.setTitle("Scroll Bar Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

2.13 Plugin

Plugs another application as a component. Any number of NeuroKernel application can be plugged into another NeuroKernel application. The plugin application main window will be contained in a special component, and will be placed to the parent application’s layout. The plugin application runs by itself in the background, and the display server handles all the rendering. It will even allow modal dialogs to be opened from the plugin application. The communication between parent application and plugin application is done via bi-directional event flow. An application running at a server in New York can be plugged inside another application running at London.

   import com.neurokernel.client.*;
   import com.neurokernel.client.system.IPluginSystem;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
          NFrame mainFrame=getMainFrame();
 
          NCanvas canvas=new NCanvas(mainFrame);
          NPlugin plugin=new NPlugin(mainFrame, "teapot", null);
          IPluginSystem pluginSystem=plugin.getPluginSystem();
          pluginSystem.associateCanvas("MyCanvas", canvas.getGraphics());
 
          mainFrame.setTitle("Plugin Application");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
    }
 

2.14 Gauge

A component to display a gauge with various customizable parts. This gauge component is handled directly by the display server;however, it is always possible to create a more advanced gauge using graphics interfaces offered.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
          NFrame mainFrame=getMainFrame();
 
          NGauge gauge=new NGauge(mainFrame);
 
          gauge.setMaximum(220);
          gauge.setName("Km/h");
          gauge.setStrokeTicks(false);
          gauge.setShadowGlow(true);
 
          gauge.setColor(GaugePart.PLATE, new NColor(0x22,0x22,0x22));
          gauge.setColor(GaugePart.MAJOR_TICKS, new NColor(0xf5,0xf5,0xf5));
          gauge.setColor(GaugePart.MINOR_TICKS, new NColor(0xdd,0xdd,0xdd));
          gauge.setColor(GaugePart.TITLE, NColor.WHITE);
          gauge.setColor(GaugePart.NUMBERS, new NColor(0xee,0xee,0xee));
          gauge.setMajorTicks("0","20","40","60","80","100","120","140","160","180","200","220");
 
          gauge.addColorRange(0, 50, new NColor(0,255,0,40));
          gauge.addColorRange(50, 100, new NColor(255,255,0,40));
          gauge.addColorRange(100, 150, new NColor(255,30,0,62));
          gauge.addColorRange(150, 200, new NColor(255,0,255,62));
          gauge.addColorRange(200, 220, new NColor(0,0,255,62));
          gauge.setValue(60);
 
          mainFrame.setBackground(NColor.BLACK);
          mainFrame.setTitle("Speed Km/h");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
   }
 

A link component that consists of an anchor element. It can have either text or image, and can open URLs to a new native client tab as well as download a specified file.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
         NGridLayout layout=mainFrame.getLayout();
         layout.setSize(2,1).setGaps(5,5);
 
         new NLink(mainFrame,"Hello World");
         new NLink(mainFrame,"NeuroKernel","https://www.neurokernel.com");
 
         mainFrame.setTitle("Link Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

2.16 Image View

Image view displays an image in its content. an image loaded event will be sent to this component with the calculated size information of the image.

   import com.neurokernel.client.*;
   import com.neurokernel.client.annotation.LoadResources;
   import com.neurokernel.client.annotation.Source;
 
   @LoadResources(
           resources = {
               @Source(value = "resources/banner.png", name = "banner"),
           }
   )
   public class ResourcesExample extends NApplication {
         @Override
         public void main(int argc, String[] argv) {
             NFrame mainFrame=getMainFrame();
             new NImageView(mainFrame, (NImage)getResource("banner"));
 
             mainFrame.setTitle("Image View Example");
             mainFrame.setBounds(20,20,200,200);
             mainFrame.setVisible(true);
         }
   }
 
 

2.17 Media Player

Media player component for video and audio

   import com.neurokernel.client.*;
   import com.neurokernel.client.adapter.NActionListener;
 
   public class MyApplication extends NApplication {
      NMediaPlayer player;
 
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
         NGridLayout grida = mainFrame.getLayout();
         grida.setGridSize(2, 1);
         grida.setFixedRow(1, 25);
 
         NURI url=new NURI(mainFrame, "~public/demo/pulsar.mp4");
         player = new NMediaPlayer(mainFrame, url, "video/mp4", MediaType.VIDEO);
         player.setAutoPlay(false);
         player.addMediaSource(new NURI(mainFrame, "~public/demo/pulsar.webm"), "video/webm");
         player.addMediaSource(new NURI(mainFrame, "~public/demo/pulsar.ogv"), "video/ogg");
 
         NButton play = new NButton(mainFrame, "Play");
         play.addActionListener(new NActionListener() {
               @Override
               public void onAction(NEvent e) {
                   player.play();
               }
         });
 
         mainFrame.setTitle("Media Player Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
   }
 

2.18 Media Capture

Capture image through camera. The single frames can be captured and used by the application. Remote applications can not use this component. Only Video is supported in this release. Some clients may require HTTPS connection. Audio capture is not yet supported.

2.19 Native Pane

Native panel is available when application is run at the client side. In server side runtime, it acts as a graphics canvas. Native pane can be used to create visual experiences using third party libraries. It have also ability to hook NeuroKernel graphics interface to a canvas element which makes direct manipulation possible without going through protocol layer. Example below shows the use of a HTML canvas element as a IGraphics interface.

import com.neurokernel.client.*;
import com.neurokernel.client.graphics.*;
 
public class NativePaneExample extends NApplication {
    @Override
    public void main(int argc, String[] argv) {
       NFrame mainFrame=getMainFrame();
       NNativePane nativePanel = createNativePane(mainFrame);
       INativeCanvas nativeCanvas = nativePanel.getCanvas("MyCanvas");
 
       IGraphics2D ctx = (IGraphics2D)nativeCanvas.getGraphicsContext(GraphicsContext.CONTEXT_2D, null);
       ctx.setFillStyle(NColor.BLUE);
       ctx.rectangle(10, 10, 55, 50);
       ctx.fill();
       ctx.setFillStyle(NColor.RED);
       ctx.rectangle(30, 30, 55, 50);
       ctx.fill();
 
       mainFrame.setTitle("Native Pane");
       mainFrame.setBounds(20,20,200,200);
       mainFrame.setVisible(true);
    }
}

2.20 Progress Bar

Creates manageable progress bar component.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
 
         mainFrame.setTitle("Progress Bar Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
 
         NDialog progressBar = new NDialog(toplevel, "Progress Bar");
         NProgressBar progress=new NProgressBar(progressBar);
         progress.setMinimum(0); 
         progress.setMaximum(256);
         progress.setValue(100); 
         progress.setMargin(20, 10, 20, 10);
         progressBar.setBounds(195, 150, 300, 150);
         progressBar.setVisible(true);
 
      }
  }
 

2.21 Terminal Input

Command input and print terminal. This component is also used by the terminal application of the NeuroKernel.

2.22 Text Area

NTextArea is an editable component with multiple rows and columns. It can scroll its content when it is added inside a view port.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
         NGridLayout layout=mainFrame.getLayout();
         layout.setSize(2,1).setGaps(5,5);
 
         new NTextArea(mainFrame).setPromptText("Your Comments");
         new NButton(mainFrame,"Submit");
 
         mainFrame.setTitle("Text Area Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

2.23 Rich Text Area

Rich text area extends text area component but it allows styling and HTML in its content.

2.24 Code Editor

Code editor extends text area component with syntax highlighting capabilities for code. Syntax handler set to use Java syntax by default.

2.25 PDF View

Renders a PDF document page by page

    import com.neurokernel.client.;
 
    public class MyApplication extends NApplication {
        @Override
        public void main(int argc, String[] argv) {
           NFrame mainFrame=getMainFrame();
 
           new NPDFView(mainFrame,new NFile("/neurokernel.pdf"));
           mainFrame.setTitle("PDFView Example");
           mainFrame.setBounds(20,20,400,600);
           mainFrame.setVisible(true);
        }
    }
 

2.26 Applet View

Applet View are different than plugin applications. Applet Views launch an entire OS with limited capability in its container. A miniaturized versions of NeuroKernel/OS for Applet deployment may be built from neurokernel.com site by selecting required modules and components. Applet views can only be launched inside a native pane.

    import com.neurokernel.client.;
 
    public class MyApplication extends NApplication {
        @Override
        public void main(int argc, String[] argv) {
           NFrame mainFrame=getMainFrame();
 
           new NAppletView(mainFrame,NURL.create("https://www.neurokernel.com/neurokernelmini/")));
           mainFrame.setTitle("Applet View Example");
           mainFrame.setBounds(20,20,400,600);
           mainFrame.setVisible(true);
        }
    }
 

2.27 HTML Pane

Displays HTML in a scrollable view. Only supported tags are displayed, others will be removed by the HTML filter.

2.28 SVG View

SVG viewer class. This class is included for convenience, containers and most controls are capable of displaying SVG by default.

2.29 Board

{@code NBoard} component can have a border and title. It may be more efficient to use a titled {@code NBoard} over {@code NTitledPanel} in most cases. When title is set, an etched border is also added to the board. Default location of the title is at the left side as same as panel. Setting the title of a sub grid will automatically put a titled board around the grid cell area. It helps to prevent creating nested panels.

2.30 Extension Component

Abstract class for a core component extension. Only registered and authorized component libraries can be used. Kernel may kill a task that makes repeated attempts to load a library that is not available. Protocol for extension elements can not be cached. The site providing extension library must be a trusted site. Extension development API has not been made public yet. Only NeuroKernel Research will release extension libraries to keep the performance and quality of the system intact. Custom extension components can be ordered separately. It is encouraged to write composite custom components by only using this NeuroKernel API without demanding a low level display server extension.

2.31 Separator

Creates a horizontal or vertical separator.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
         NGridLayout layout=mainFrame.getLayout();
         layout.setSize(3, 1);
         layout.setPadding(4);
         layout.setRowHeights(0, 2, 30);
 
         new NButton(mainFrame,"Flex");
         new NSeparator(mainFrame);
         new NButton(mainFrame,"Fixed");
 
         mainFrame.setTitle("Separator Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

2.32 Spacer

Layout spacer component which is never painted or focused. It is basically a place holder component and can be used for various creative layout purposes.

3. Cells

Cell is an abstract super class for all cell components designed to be used in an NColumn container. Cells can act as individual controls and it is possible to set certain properties individually after a cell is painted inside their parent column. If desired, they can also observe value of another component.

A cell can have two states, selected or not selected. It has also ability to render a check box if implemented. Editing the content of a cell is done by calling the edit method. There are also more advanced cell editing methods in the column container. For a custom cell editor other then the default one assigned by the column, overriding the getEditor method is enough. Returning null from the {@code getEditor} method means that the cell is not to be edited. All editors should be registered with the column container first using addEditor method, or must be in the same context as the parent column container. Cell editors implements ICellEditor interface for recognition.

A cell has two values. One is the persistent content value, the other one is the status value which is by default is the content value itself but can be overridden to hold extra value. Content value is created with the constructor. Extending this class will make the cell paintable by graphics just like NCanvasCell. However the graphics painting is only allowed by overriding paint method.

3.1 Table Cell

NTableCell is the most primitive and performant cell component of all. It is designed to be used in table columns only.

3.2 Tree Cell

Tree cell is used only with tree containers. It sends NEventTypes.CHANGE the containing column container when the state of the tree cell changes to expand or collapse.

Cell component used only with NMenu. A menu cell can have a sub menu, check box, radio button, image, a separator on top of it and can have an keyboard accelerator.

    import com.neurokernel.client.;
 
    public class MyApplication extends NApplication {
        @Override
        public void main(int argc, String[] argv) {
           NFrame mainFrame=getMainFrame();
           mainFrame.setFrameLayout(NFrameLayout.MENUBAR);
           NMenuBar menubar = new NMenuBar(mainFrame);
 
           NMenu menu = new NMenu(mainFrame);
           new NMenuCell(menu, "Options").setChecked(true);
 
           //Add and enable fullscreen action
           NMenuCell fullscr=new NMenuCell(menu, "Full Screen", true);
           fullscr.getEventAction().addFullScreen(mainFrame,true);
 
           menubar.addMenu("File", menu);
 
           mainFrame.setTitle("Menu Cell Example");
           mainFrame.setBounds(20,20,200,200);
           mainFrame.setVisible(true);
        }
    }

3.4 List Cell

List cell can be used with any column container but its basically designed to be used with lists and tables. List cell can have text as well as image. It also implements the check box feature of the cell control.

A cell control that consists of an anchor element. It can have either text or image, and can open URLs to a new native client tab as well as download a specified file.

3.6 Image Cell

Cell component which contains an image in its content. If a checkbox is associated with the image cell, only the check box is shown.

3.7 Canvas Cell

Canvas cell can have custom drawing in its content. The graphics drawing can only be done by overriding the paint method.

   import com.neurokernel.client.*;
   import com.neurokernel.client.graphics.*;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
          NFrame mainFrame=getMainFrame();
 
          NListView list=new NListView(new NScrollView(mainFrame));
 
          list.setRowHeight(50);
          list.addRow(new NCanvasCell() {
               @Override
               public void paint(IGraphics graphics) {
                   IGraphics2D ctx = (IGraphics2D) graphics;
                   ctx.setFillStyle(NColor.BLUE);
                   ctx.rectangle(10, 10, 55, 50);
                   ctx.fill();
                   ctx.setFillStyle(NColor.RED);
                   ctx.rectangle(30, 30, 55, 50);
                   ctx.fill();
               }
          });
 
          list.addRow(new NCanvasCell() {
               @Override
               public void paint(IGraphics graphics) {
                   IGraphics2D ctx = (IGraphics2D) graphics;
                   ctx.setFillStyle(NColor.ORANGE);
                   ctx.rectangle(10, 10, 55, 50);
                   ctx.fill();
                   ctx.setFillStyle(getImage("~data/monitor.gif"),Repetition.REPEAT);
                   ctx.rectangle(30, 30, 55, 50);
                   ctx.fill();
               }
          });
 
          mainFrame.setTitle("Canvas Cell Example");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
   }
 

3.8 SVG Cell

Cell that can handle SVG drawing. It is possible to use Shapes for convenience which can be internally converted to SVG.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
          NFrame mainFrame=getMainFrame();
 
          NListView list=new NListView(new NScrollView(mainFrame));
 
          list.setRowHeight(50);
 
          NSVGCell cell=new NSVGCell();
          ArrayList<NSVGShape> shapes=new ArrayList&lt;&gt;();
          shapes.add(new NCircle(5,5,35));
          shapes.add(new NCircle(30,30,45).fill(NColor.RED));
          cell.setSVG(shapes);
          list.addRow(cell);
 
          cell=new NSVGCell();
          shapes=new ArrayList&lt;&gt;();
          shapes.add(new NCircle(5,5,35));
          shapes.add(new NCircle(30,30,45).fill(NColor.BLUE));
          cell.setSVG(shapes);
          list.addRow(cell);
 
          mainFrame.setTitle("SVG Cell Example");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
   }
 

3.9 HTML Cell

HTML cell can have HTML only. Using HTML cell, it is fairly easy to create a custom cell. HTML is filtered by the system. HTML cell can not have a check box associated with it.

3.10 Panel Cell

Panel cell extends NPanel container and can only be contained inside a cell control except tree cell and row header cell. It always takes the width and height of the container cell and align its layout accordingly.

3.11 Row Header Cell

Row header cell class. This cell can resize interactively in vertical direction.

4. Layout Management

Every container in NeuroKernel UI API has a layout manager which can be accessed with getLayout method of NContainer class. NLayoutManager is the abstract super class of all layout managers accepted by containers. NeuroKernel API comes with ready to use layout managers such as grid layout manager. Developers can write their own layout managers if needed. It is also possible to port Swing or SWT layout managers with ease. First thing to note in the below example, components are automatically placed on the layout to make prototyping faster. It is possible to rearrange the order with various methods available though the base layout manager class, or new ones may be implemented by developers.

import com.neurokernel.client.*;
 
public class GridLayoutExample extends NApplication {
     @Override
     public void main(int argc, String[] argv) {
          NFrame mainFrame = getMainFrame();
          NGridLayout grid = mainFrame.getLayout();
          grid.setSize(2,2); // 2x2 grid
 
          new NButton(mainFrame,"1");
          new NButton(mainFrame,"2");
          new NButton(mainFrame,"3");
          new NButton(mainFrame,"4");
 
          mainFrame.setTitle("Layout Manager");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
     }
 }

Grid layout is a very optimized layout and gives more with less coding. Sub grid layout definitions eliminate nested panel creation to sub layouts. When a layout of a container is set to null using setLayout method, NCoordinateLayout is automatically assigned which requires absolute positioning of the components in the container.

4.1 Coordinate Layout

Coordinate layout does not manage its components. In this layout manager, components set their size and location by themselves using setBounds, setSize or setLocation methods.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
       {@literal @}Override
       public void main(int argc, String[] argv) {
          NFrame mainFrame=getMainFrame();
 
          NScrollPane scrollView=new NScrollPane(mainFrame);
          scrollView.setScrollArea(400,400);
          NPanel panel=new NPanel(scrollView);
          // new NCoordinateLayout() can be used in place of "null"
          panel.setLayout(null); //set to coordinate layout
 
          new NButton(panel,"Hello").setBounds(20,20,100,50);
 
          mainFrame.setTitle("Scroll Pane Example");
          mainFrame.setBounds(20,20,200,200);
          mainFrame.setVisible(true);
       }
   }
 

4.2 Grid Layout

Grid layout is the default layout manager of all core containers. It is made of rows and columns. It also offers row/column manipulation methods to get the desired layout. Grid layout will fill each cell starting from the first row by the order of components in its internal component array. If a later manipulation is needed, swapGridCells method can be used. Default

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
           NFrame mainFrame = getMainFrame();
           NGridLayout grid = mainFrame.getLayout();
           grid.setSize(2,2);
 
           new NButton(mainFrame,"1");
           new NButton(mainFrame,"2");
           new NButton(mainFrame,"3");
           new NButton(mainFrame,"4");
 
           mainFrame.setTitle("My Application");
           mainFrame.setBounds(20,20,200,200);
           mainFrame.setVisible(true);
       }
   }
 

4.2.1 Sub Grid Layout

Creates a sub grid layout in a parent grid cell.

    import com.neurokernel.client.;
 
    public class MyApplication extends NApplication {
        @Override
        public void main(int argc, String[] argv) {
            NFrame mainFrame = getMainFrame();
            NGridLayout grid = mainFrame.getLayout();
            grid.setSize(2,2);
 
            new NButton(mainFrame,"1");
            new NButton(mainFrame,"2");
            new NButton(mainFrame,"3");
 
            //put a subgrid to 2,2
            NSubGridLayout subGrid=gridLayout.addSubGrid(1, 1, 2, 2);
            NBoard board=addTitledBoard("Labels");
            NLabel label=board.getTitleLabel();
            label.setBackground(NColor.BLUE);
 
            new NLabel(mainFrame,"A");
            new NLabel(mainFrame,"B");
            new NLabel(mainFrame,"C");
            new NLabel(mainFrame,"D");
 
            mainFrame.setTitle("Grid Layout");
            mainFrame.setBounds(20,20,200,200);
            mainFrame.setVisible(true);
        }
    }
 

4.3 Card Layout

Card layout manager stacks components on top of each other and displays them one at a time by raising the selected one on top. In order to raise a component to the top of the stack setSelected method is used.

   import com.neurokernel.client.*;
   import com.neurokernel.client.adapter.NActionListener;
 
   public class MyApplication extends NApplication {
       NCardLayout cardLayout;
       @Override
       public void main(int argc, String[] argv) {
           NFrame mainFrame = getMainFrame();
           NGridLayout grid = mainFrame.getLayout();
           grid.setSize(2,1);
 
           new NButton(mainFrame,"Alternate").addActionListener(new NActionListener() {
                int flipFlop;
                @Override
                public void onAction(NEvent e) {
                     cardLayout.setSelected(cardLayout.getComponent(flipFlop));
                     flipFlop = flipFlop==0?1:0;
                }
           });
 
           NPanel cardPanel=new NPanel(mainFrame);
           cardLayout=new NCardLayout();
           cardPanel.setLayout(cardLayout);
 
           new NLabel(cardPanel,"Card 0");
           new NLabel(cardPanel,"Card 1");
 
           mainFrame.setTitle("Card Panel");
           mainFrame.setBounds(20,20,200,200);
           mainFrame.setVisible(true);
       }
   }
 

4.4 Layered Layout

Layered layout manager stacks the components on top of each other and displays the last component in the layout on top of all. Unlike card layout, layered layout do not have any method to control the layer. It may be used to create composite components on a container.

4.5 Border Layout

Border layout manager accepts exactly five components to construct its content. Components are placed in the order of their addition to the layout; however, their positions can be swapped using the method setPlacement if necessary. it arranges and resize its components to fit in five regions in order: north, south, west, east, and center.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
           NFrame mainFrame = getMainFrame();
           NBorderLayout blayout=new NBorderLayout();
           mainFrame.setLayout(blayout);
 
           new NButton(mainFrame,"North");
           new NButton(mainFrame,"South");
           NButton center=new NButton(mainFrame,"Center");
           new NButton(mainFrame,"West");
           new NButton(mainFrame,"East");
 
           blayout.setPlacement(center, NBorderLayout.CENTER);
 
           mainFrame.setTitle("Border Layout");
           mainFrame.setBounds(20,20,200,200);
           mainFrame.setVisible(true);
       }
   }
 

4.6 Flow Layout

Flow layout arranges components in a horizontal direction much like texts in a sentence or paragraph. If the horizontal space in the container is too small to put all the components in one row, the NFlowLayout class uses multiple rows unless overflow flag is set.

   import com.neurokernel.client.*;
 
   public class MyApplication extends NApplication {
       @Override
       public void main(int argc, String[] argv) {
           NFrame mainFrame = getMainFrame();
           mainFrame.setLayout(new NFlowLayout());
 
           for(int i=0;i<10;i++) {
              new NButton(mainFrame,String.valueOf(i));
           }
 
           mainFrame.setTitle("Flow Layout");
           mainFrame.setBounds(20,20,200,200);
           mainFrame.setVisible(true);
       }
   }
 

5. Accessing Sub Controls

Some non-composite controls have parts that can be automatically defined as a sub component. These are simple components such a button, label or image view. These sub controls can be styled as well individually making look more manageable. For example, buttons of NSpinner component can be individually styled.

   import com.neurokernel.client.*;
    import com.neurokernel.client.constants.Order;
 
   public class MyApplication extends NApplication {
      @Override
      public void main(int argc, String[] argv) {
         NFrame mainFrame=getMainFrame();
         NGridLayout layout=mainFrame.getLayout();
         layout.setSize(2,1).setGaps(5,5);
 
         new NSpinner(mainFrame,"0");
         NSpinner  spinner=new NSpinner(mainFrame,"0");
         NButton button=spinner.getSideControl(Order.First);
         button=setBorder(new NRoundedBorder(NBorder.RAISED,3));
 
         mainFrame.setTitle("Spinner Example");
         mainFrame.setBounds(20,20,200,200);
         mainFrame.setVisible(true);
      }
  }
 

6. Using HTML and SVG

   import com.neurokernel.client.*;
   import com.neurokernel.client.dom.html.*;
   import com.neurokernel.client.adapter.NActionListener;
 
   public class MyApplication extends NApplication {
       private IHTML htmlRenderer;
 
       @Override
       public void main(int argc, String[] argv) {
           final NFrame mainFrame=getMainFrame();
           //get container renderer
           htmlRenderer=frame.getHTMLRenderer();
           //create button with HTML
           NButton button=new NButton(mainFrame);
           button.setHTML("<div id=\"mydiv\">NeuroKernel <span>hey</span></div>");          
 
           button.addActionListener(new NActionListener() {
               @Override
               public void onAction(NEvent e) {
                   htmlRenderer.getElement("mydiv").setBackground(NColor.BLUE);
               }
           });
 
           mainFrame.setTitle("HTML Demo");
           mainFrame.setBounds(20,20,200,200);
           mainFrame.setVisible(true);
       }
   }
 
   import com.neurokernel.client.*;
   import com.neurokernel.client.dom.svg.shapes.*;
   import com.neurokernel.client.adapter.NActionListener;
 
   public class MyApplication extends NApplication {
       private NSVGShape circle;
       @Override
       public void main(int argc, String[] argv) {
           final NFrame mainFrame=getMainFrame();
 
           //create button with SVG
           NButton button=new NButton(mainFrame);
           circle=new NCircle(30,30,45).fill(NColor.RED);
           button.setSVG(circle);
 
           button.addActionListener(new NActionListener() {
               @Override
               public void onAction(NEvent e) {
                   circle.fill(NColor.BLUE);
               }
           });
 
           mainFrame.setTitle("SVG Shape Demo");
           mainFrame.setBounds(20,20,200,200);
           mainFrame.setVisible(true);
       }
   }
 

6.1 Utilizing Virtual DOM

   import com.neurokernel.client.*;
   import com.neurokernel.client.dom.*;
   import com.neurokernel.client.adapter.NActionListener;
 
   public class MyApplication extends NApplication {
       private IVirtualDOM vdom;
 
       @Override
       public void main(int argc, String[] argv) {
           final NFrame mainFrame=getMainFrame();
           vdom=frame.getHTMLRenderer().attachVirtualDOM("<div>NeuroKernel <span>hey</span></div>");
           vdom.render();
           NButton button=new NButton(mainFrame,"Hello");
 
           button.addActionListener(new NActionListener() {
               @Override
               public void onAction(NEvent e) {
                   vdom.patch("<div>NeuroKernel "+
                       "<span style=\"background-color:blue;color:white\">/OS</span>"+
                       "</div>");
               }
           });
 
           mainFrame.setTitle("Virtual DOM Demo");
           mainFrame.setBounds(20,20,200,200);
           mainFrame.setVisible(true);
       }
   }
 

7. Animations

NeuroKernel supplies a custom animation manager although in browser transitions can still be used with HTML and SVG elements if desired. The controls can only be animated with the IAnimationControl interface object. Certain animations will notify the application when ends especially the bounds related.

import com.neurokernel.client.*;
import com.neurokernel.client.animation.*;
 
public class AnimationExample extends NApplication {
    @Override
    public void main(int argc, String[] argv) {
         final NFrame mainFrame=getMainFrame();
 
          new NButton(mainFrame,"Move Frame").addActionListener(new NActionListener() {
              NAnimation anim;
              @Override
              public void onAction(NEvent e) {
                   IAnimationControl animControl=mainFrame.getAnimationControl();
                   if(anim!=null) animControl.removeAnimation(anim);
                   anim=new NAnimateLocation(600,600).setEasing(NAnimation.Easing.ELASTIC_OUT);
                   animControl.createAnimation(anim);
                   animControl.startAnimation(anim);
              }
          });
 
         mainFrame.setTitle("Animation Example");
         mainFrame.setBounds(20,20,300,300);
         mainFrame.setVisible(true);
    }
}

8. Responsive Applications

NeuroKernel uses a similar layout system which is available in Swing and SWT. The layout system is controlled by the API and optimized very well. A NeuroKernel application will be made aware of the new display size by the system. By catching this resize event, it is possible to take counter measures to fit the user interface inside the display size. Developers may implement third party helper libraries to ease this transition.

8.1 Supporting All Screens

NeuroKernel applications reflows their layout by default when the parent container resizes. It is possible to create custom layout managers to further manipulate the layout to accommodate smaller screens. NeuroKernel does not use browser supplied layout features.

9. Value Validation

NeuroKernel API controls have built in validation support although a custom one can be crafted easily if the builtin one does not meet the requirements. NValueValidator is used to add new validation rules to controls via addValueValidator method. A container can call validateValues method with specified arguments and it will receive ERROR event if a value fails to validate. The event payload will include the reference to the railed control as well. The validateValues method can also be called directly for each control to test the value.

10. Drag & Drop

NeuroKernel drag and drop features is strong and well designed. Dragging and dropping ant data between any two application is also allowed. Dragging flles to a drop area will automatically cache the files to the client side and let the application know about them. Their raw content can be fetched from the cache if desired.