Skip to content

Commit

Permalink
Merge pull request #150 from usdAG/feat/operation-comments
Browse files Browse the repository at this point in the history
feat: Add operation and lane comments, add lane name
  • Loading branch information
felixb1515 authored Jul 15, 2024
2 parents 55bf9d1 + 0db33e9 commit d2ba7e2
Show file tree
Hide file tree
Showing 13 changed files with 212 additions and 8 deletions.
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@

<resource>
<directory>res</directory>
<filtering>true</filtering>
</resource>

</resources>
Expand Down
Binary file added res/comment.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified res/disable.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified res/help.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added res/no_comment.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified res/operation.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified res/remove.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified res/stop.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified res/stop_active.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions res/version.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version = ${project.version}
36 changes: 36 additions & 0 deletions src/main/java/de/usd/cstchef/operations/Operation.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.EOFException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand All @@ -19,6 +21,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
Expand All @@ -28,6 +31,7 @@
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JSpinner;
Expand Down Expand Up @@ -68,6 +72,8 @@ public abstract class Operation extends JPanel {
private static ImageIcon disableIcon = new ImageIcon(Operation.class.getResource("/disable.png"));
private static ImageIcon removeIcon = new ImageIcon(Operation.class.getResource("/remove.png"));
private static ImageIcon helpIcon = new ImageIcon(Operation.class.getResource("/help.png"));
private static ImageIcon commentIcon = new ImageIcon(Operation.class.getResource("/comment.png"));
private static ImageIcon noCommentIcon = new ImageIcon(Operation.class.getResource("/no_comment.png"));

private NotifyChangeListener notifyChangeListener;

Expand All @@ -80,6 +86,9 @@ public abstract class Operation extends JPanel {
private Box contentBox;
private Map<String, Component> uiElements;

private String comment;
private JButton commentBtn;

private int operationSkip = 0;
private int laneSkip = 0;

Expand Down Expand Up @@ -122,6 +131,19 @@ public Operation() {
removeBtn.setToolTipText("Remove");
JButton helpBtn = createIconButton(Operation.helpIcon);
helpBtn.setToolTipText(opInfos.description());
commentBtn = createIconButton(noCommentIcon);

commentBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
commentBtn.setToolTipText(getComment());
String comment = JOptionPane.showInputDialog("Edit comment:", commentBtn.getToolTipText());
commentBtn.setToolTipText(comment);
setComment(comment);
ImageIcon newIcon = comment.isEmpty() ? Operation.noCommentIcon : Operation.commentIcon;
commentBtn.setIcon(newIcon);
}
});


disableBtn.addActionListener(new ActionListener() {
@Override
Expand Down Expand Up @@ -162,6 +184,8 @@ public void actionPerformed(ActionEvent e) {
header.add(titleLbl);
header.add(Box.createHorizontalStrut(6));
header.add(helpBtn);
header.add(Box.createHorizontalStrut(3));
header.add(commentBtn);
header.add(Box.createHorizontalGlue());
header.add(disableBtn);
header.add(Box.createHorizontalStrut(3));
Expand Down Expand Up @@ -189,6 +213,18 @@ public void actionPerformed(ActionEvent e) {
this.refreshColors();
}

public String getComment() {
return this.comment;
}

public void setComment(String comment) {
if(comment != null) {
this.comment = comment;
commentBtn.setIcon(Operation.commentIcon);
commentBtn.setToolTipText(comment);
}
}

public Map<String, Object> getState() {
Map<String, Object> properties = new HashMap<>();
for (String key : this.uiElements.keySet()) {
Expand Down
99 changes: 92 additions & 7 deletions src/main/java/de/usd/cstchef/view/RecipePanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;

Expand Down Expand Up @@ -350,10 +352,23 @@ public void setFormatMessage(HttpRequestResponse requestResponse, MessageType me
}

public void restoreState(String jsonState) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
// TODO do we want to remove all existing operations before loading here?
this.clear(); // Yes!
this.clear();
ObjectMapper mapper = new ObjectMapper();
JsonNode stepNodes = mapper.readTree(jsonState);
JsonNode rootNode = mapper.readTree(jsonState);
JsonNode stepNodes;
JsonNode versionNode;

// check if "version" ObjectNode is there (since 1.3.2)
if(rootNode.get(0) != null && rootNode.get(0).get("version") == null) {
// recipes saved by CSTC <= 1.3.1
stepNodes = rootNode;
}
else {
// currently 1.3.2
versionNode = rootNode.get(0);
stepNodes = rootNode.get(1);
}

if (!stepNodes.isArray()) {
throw new IOException("wrong data format");
}
Expand All @@ -364,40 +379,107 @@ public void restoreState(String jsonState) throws IOException, ClassNotFoundExce
throw new IOException("wrong data format");
}

for (int i = 0; i < operationNodes.size(); i++) {
RecipeStepPanel panel = (RecipeStepPanel) this.operationLines.getComponent(step);

/* two types of ObjectNodes for every RecipeStepPanel:
Lane information (always at index 0, if set) and the Operations
If there's a lane ObjectNode we need to tell the inner loop to begin at index 1.
The inner loop iterates over the Operations
*/
int index = 0;
if(operationNodes.get(0) != null) {
if(operationNodes.get(0).get("lane_title") != null) {
index = 1;
panel.setTitle(operationNodes.get(0).get("lane_title").asText());
}
if(operationNodes.get(0).get("lane_comment") != null) {
index = 1;
panel.setComment(operationNodes.get(0).get("lane_comment").asText());
}
}

for (int i = index; i < operationNodes.size(); i++) {
JsonNode operationNode = operationNodes.get(i);
String operation = operationNode.get("operation").asText();
Map<String, Object> parameters = mapper.convertValue(operationNode.get("parameters"), Map.class);
Class<Operation> cls = (Class<Operation>) Class.forName(operation);

// check if it is an operation
Operation op = cls.newInstance();
op.load(parameters);
op.setDisabled(!operationNode.get("is_enabled").asBoolean());
RecipeStepPanel panel = (RecipeStepPanel) this.operationLines.getComponent(step);
panel.addComponent(op, i);

// check if "comment" attribute is set (since 1.3.2)
if(operationNode.get("comment") != null) {
if(operationNode.get("comment").asText() != "null") {
op.setComment(operationNode.get("comment").asText());
}
}
// depending on if lane name is set we may start the loop at index 1, but want to add the first component at index 0
panel.addComponent(op, index == 1 ? i-1 : 0);
}
}
}

private String getStateAsJSON() throws IOException {
ObjectMapper mapper = new ObjectMapper();
ArrayNode rootNode = mapper.createArrayNode();
ObjectNode versionNode = mapper.createObjectNode();
ArrayNode stepsNode = mapper.createArrayNode();

for (int step = 0; step < this.operationSteps; step++) {
ArrayNode operationsNode = mapper.createArrayNode();

RecipeStepPanel stepPanel = (RecipeStepPanel) this.operationLines.getComponent(step);

// save lane name in case it differs from the default
int laneNumber = step + 1;
boolean laneNodeCreated = false;
if(!stepPanel.getTitle().equals("Lane " + laneNumber)) {
laneNodeCreated = true;
ObjectNode laneNode = mapper.createObjectNode();
laneNode.put("lane_title", stepPanel.getTitle());
// save comment in same node in case it is set
if(!stepPanel.getComment().equals("")) {
laneNode.put("lane_comment", stepPanel.getComment());
}
operationsNode.add(laneNode);
}

// save comment in case it's not already
if(!laneNodeCreated && !stepPanel.getComment().equals("")) {
ObjectNode laneNode = mapper.createObjectNode();
laneNode.put("lane_comment", stepPanel.getComment());
operationsNode.add(laneNode);
}

List<Operation> operations = stepPanel.getOperations();
for (Operation op : operations) {
ObjectNode operationNode = mapper.createObjectNode();
operationNode.put("operation", op.getClass().getName());
operationsNode.add(operationNode);
operationNode.putPOJO("parameters", op.getState());
operationNode.putPOJO("is_enabled", !op.isDisabled());
// "comment":null if empty
operationNode.put("comment", op.getComment());
}
stepsNode.add(operationsNode);
}
return mapper.writeValueAsString(stepsNode);

/* maven performs a substitution at compile time in "/res/version.properties"
with the version from pom.xml and here it reads from this file
*/
Properties properties = new Properties();
properties.load(RecipePanel.class.getResourceAsStream("/version.properties"));
String version = properties.getProperty("version");

versionNode.put("version", version);

rootNode.add(versionNode);
rootNode.add(stepsNode);

return mapper.writeValueAsString(rootNode);
}

private void save(File file) throws IOException {
Expand Down Expand Up @@ -587,6 +669,9 @@ private void saveFilterState() {
private void clear() {
for (int step = 0; step < this.operationSteps; step++) {
RecipeStepPanel stepPanel = (RecipeStepPanel) this.operationLines.getComponent(step);
int laneIndex = step + 1;
stepPanel.setTitle("Lane " + laneIndex);
stepPanel.clearComment();
stepPanel.clearOperations();
}
}
Expand Down
83 changes: 82 additions & 1 deletion src/main/java/de/usd/cstchef/view/RecipeStepPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,24 @@
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
Expand All @@ -27,6 +37,13 @@ public class RecipeStepPanel extends JPanel {
private JPanel operationsLine;
private GridBagConstraints addContraints;
private ChangeListener changeListener;
private JTextField contentTextField;

private String comment;
private JButton commentBtn;

private static ImageIcon commentIcon = new ImageIcon(Operation.class.getResource("/comment.png"));
private static ImageIcon noCommentIcon = new ImageIcon(Operation.class.getResource("/no_comment.png"));

public RecipeStepPanel(String title, ChangeListener changelistener) {
this.changeListener = changelistener;
Expand All @@ -41,12 +58,39 @@ public RecipeStepPanel(String title, ChangeListener changelistener) {
CompoundBorder border = new CompoundBorder(lineBorder, margin);
headerBox.setBorder(border);

JTextField contentTextField = new JTextField();
contentTextField = new JTextField();
contentTextField.setBorder(null);
contentTextField.setBackground(new Color(0, 0, 0, 0));
contentTextField.setText(title);
contentTextField.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
String newTitle = JOptionPane.showInputDialog("Edit title:", getTitle());
contentTextField.setText(newTitle.length() <= 50 ? newTitle : getTitle());
setTitle(newTitle.length() <= 50 ? newTitle : getTitle()); // lane name should be leq 50 chars
}
});
headerBox.add(contentTextField);

JPanel panel = new JPanel();
panel.setBackground(new Color(0, 0, 0, 0)); // transparent

commentBtn = createIconButton(noCommentIcon);

commentBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
commentBtn.setToolTipText(getComment());
String comment = JOptionPane.showInputDialog("Edit comment:", commentBtn.getToolTipText());
commentBtn.setToolTipText(comment);
setComment(comment);
ImageIcon newIcon = comment.isEmpty() ? RecipeStepPanel.noCommentIcon : RecipeStepPanel.commentIcon;
commentBtn.setIcon(newIcon);
}
});

panel.add(commentBtn);
headerBox.add(panel);

this.add(headerBox, BorderLayout.NORTH);

// body
Expand Down Expand Up @@ -124,4 +168,41 @@ public void clearOperations() {
operationsLine.repaint();
this.changeListener.stateChanged(new ChangeEvent(this));
}

public String getTitle() {
return contentTextField.getText();
}

public void setTitle(String title) {
contentTextField.setText(title);
}

private JButton createIconButton(ImageIcon icon) {
JButton btn = new JButton();
btn.setBorder(BorderFactory.createEmptyBorder());
btn.setIcon(icon);
btn.setContentAreaFilled(false);
btn.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
btn.setAlignmentX(Component.RIGHT_ALIGNMENT);

return btn;
}

public String getComment() {
return this.comment;
}

public void setComment(String comment) {
if(comment != null) {
this.comment = comment;
commentBtn.setIcon(RecipeStepPanel.commentIcon);
commentBtn.setToolTipText(comment);
}
}

public void clearComment() {
this.comment = "";
commentBtn.setToolTipText("");
commentBtn.setIcon(RecipeStepPanel.noCommentIcon);
}
}

0 comments on commit d2ba7e2

Please sign in to comment.