| previous section: Integrating Almo in Java applications: Using the Almo GUI |
Integrating Almo in Java applications: Customizing the Almo GUI
If you are unhappy with the DefaultTaskPanel, you can create an own panel for elements. For this purpose you have to do the following steps:
- Derive a panel from the super-class AlmoElementPanel
- Write actionPerformed methods that interact with the Almo element
Here we will create a customized panel for an Operation. The first Operation of our example Workflow is Operation1, which shall be started via its panel.
Content
Creating a customized panel for elements
Let us take a look at the code of the panel:
public class Operation1Panel extends AlmoElementPanel {
public static final String START = "START";
private JButton jButton = null;
private JLabel jLabel = null;
private Operation1 o1;
/**
* Constructor.
*
*/
public Operation1Panel(Operation1 o1) {
super();
initialize();
this.o1 = o1;
}
private void initialize() {
jLabel = new JLabel();
jLabel.setText("Panel for Operation 1");
this.setLayout(new BorderLayout());
this.setSize(new java.awt.Dimension(200,200));
this.add(getJButton(), java.awt.BorderLayout.SOUTH);
this.add(jLabel, java.awt.BorderLayout.NORTH);
}
private JButton getJButton() {
if (jButton == null) {
jButton = new JButton();
jButton.setText("Start");
jButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
Operation1Panel.this.setCommand(Operation1Panel.START);
Operation1Panel.this.getJButton().setEnabled(false);
Operation1Panel.this.o1.startThread();
}
});
}
return jButton;
}
public void init() {
this.getJButton().setEnabled(true);
this.setCommand("");
}
}
![]() |
This method initializes the general layout. |
![]() |
We want to access the Almo Operation with an instance variable. |
![]() |
The actionPerformed method interacts with the Almo Operation. |
![]() |
We set the command String of the super-class AlmoElementPanel. |
![]() |
After the button was clicked, we do not want the user to click it again. Otherwise another Operation Thread might be started, which might lead to unpredictable behaviour of our Workflow. |
![]() |
After that we start the Thread associated with the Operation. |
![]() |
This method is called, when the Operation is started. Beforehand the Thread of the Operation was stopped or not even started, so clicking the button is the only way to start the Operation Thread. The command String is set to an empty String, so that the Thread does not get started by chance. |
Interaction with the Operation
Now let us take a look at the code of the Operation to see how we can interact with the customized panel:
public class Operation1 extends Operation {
public Operation1(String s) {
super(s);
}
public void initPanel() {
Operation1Panel p = new Operation1Panel(this);
this.setPanel(p);
}
public void startOperation() {
this.setMaximum(10);
Operation1Panel p = (Operation1Panel) this.getPanel();
p.init();
}
public void run() {
int i=0;
Exception e = new Exception("init exception");
this.error("error at start",e);
Operation1Panel p = (Operation1Panel) this.getPanel();
if (p.getCommand().equals(Operation1Panel.START)) {
while (this.isRunning()) {
i++;
this.startWaiting();
try {
Thread.sleep(100);
}
catch (InterruptedException ex) {
}
this.stopWaiting();
try {
Thread.sleep(200);
}
catch (InterruptedException ex) {
}
if (i==1) {
this.error("error at 1");
}
this.setProgress(i);
this.print(this.getLabel()+": "+i);
if (i==10)
this.stopThread();
}
}
else
this.pauseThread();
this.finishThread();
}
public void initObject(Object o) {
}
public void stopOperation() {
}
}
![]() |
We use the initPanel method to set up our panel from above. |
![]() |
If the Operation is started, we call the init method from our panel to enable the button. Note that the getPanel method will only return an object of class AlmoElementPanel. That is why we have to cast the returned object to Operation1Panel. |
![]() |
When the Thread of the Operation is started and the command String of our panel equals the "START" String, then we simulate a process like we did with all other example Operation implementations. |
![]() |
If the simulation of our process is completed, we call the stopThread method to finish the Operation. |
![]() |
In case the command String does not equal "START" it is imperative to call the pauseThread method, otherwise the Operation would be finished, without starting the simulation of the process. |
![]() |
Depending whether the pauseThread or stopThread method was called beforehand, the finishThread method will pause or finish the Operation. Remember the methods you need to call to control the Thread. |
![]() ![]() |
These methods have to be overridden, but they do nothing. |
The result
Now what do we have achieved? You will get the following GUI, when the Workflow is started:
Note that the button is enabled and clicking it, is the only way to start the Operation. After clicking the button the Operation starts and by disabling the button, it can only be started again, if the Operation was stopped and restarted.

Summary
Of course this example is very simple. But it shall give you the basic knowledge for creating your own element panels. The crucial thing is the interaction between the panel and the element. Within the actionPerformed methods of your panel, I recommend using the setCommand method from the super-class AlmoElementPanel and starting the associated element. Within the element you should use the getCommand method to determine, which actions shall be taken.
| previous section: Integrating Almo in Java applications: Using the Almo GUI |
