diff --git a/gui/ScheduLearn.java b/gui/ScheduLearn.java index a6d39ee0393412e69e9cfe603fd19f74f3514367..f5455eed15578d5383ade1141b7dc5424bfbfe55 100644 --- a/gui/ScheduLearn.java +++ b/gui/ScheduLearn.java @@ -31,7 +31,7 @@ public class ScheduLearn extends JFrame { // ................ - JPanel tasksetPanel = new TasksetPanel(ts, status); + JPanel tasksetPanel = new TasksetPanel(ts); JPanel schedulePanel = new SchedulePanel(scheduleMdl, currentSlot, rows, cols); JPanel actionPanel = new ActionPanel(tasksetPanel, schedulePanel); diff --git a/gui/tasksetgui/AddButton.java b/gui/tasksetgui/AddButton.java index be83bd664bcb09ca1956c6ce4caed87125371a56..a64c68cbd5ce7bde060a186c771d4a56b55d7a35 100644 --- a/gui/tasksetgui/AddButton.java +++ b/gui/tasksetgui/AddButton.java @@ -2,31 +2,20 @@ package gui.tasksetgui; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.Optional; +import javax.swing.JButton; -import tasks.Taskset; -import model.Status; - -public class AddButton extends ActionButton { - protected AddButton(Taskset taskset, Status status) { - super(taskset, status, "Add Task"); +public class AddButton extends JButton { + + protected AddButton(TasksetDisplay display) { + super("Add Task"); + addEventHandler(display); } - protected void addEventHandler(Taskset taskset, Status status) { + protected void addEventHandler(TasksetDisplay display) { addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - try { - Optional<int[]> opValues = new AddDialog().generateDialog(); - if (opValues.isPresent()) { - int[] values = opValues.get(); - taskset.addTask(values[0], values[1], values[2]); - status.setStatus("Task Added"); - } - } catch (NumberFormatException error) { - status.setStatus("Invalid Input"); - } + display.addEmpty(); } }); } - } diff --git a/gui/tasksetgui/ButtonPanel.java b/gui/tasksetgui/ButtonPanel.java index b65af47f0e58ff94068203c858b6df8587e2ecf2..48977795d067f64d0c2e42080a43b0f3ad67c0c6 100644 --- a/gui/tasksetgui/ButtonPanel.java +++ b/gui/tasksetgui/ButtonPanel.java @@ -1,13 +1,11 @@ package gui.tasksetgui; -import tasks.Taskset; -import model.Status; import gui.GridPanel; public class ButtonPanel extends GridPanel { - public ButtonPanel(Taskset taskset, TasksetDisplay display, Status status) { + public ButtonPanel(TasksetDisplay display) { super(1, 2); - add(new AddButton(taskset, status)); + add(new AddButton(display)); add(new RemoveButton(display)); } } diff --git a/gui/tasksetgui/EmptyLabel.java b/gui/tasksetgui/EmptyLabel.java new file mode 100644 index 0000000000000000000000000000000000000000..e9621fa835cca7f2f53f5b7cd49d05213ea5cc4c --- /dev/null +++ b/gui/tasksetgui/EmptyLabel.java @@ -0,0 +1,67 @@ +package gui.tasksetgui; + +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.FocusListener; +import java.awt.event.FocusEvent; +import java.awt.Color; +import javax.swing.JTextField; + +public class EmptyLabel extends JTextField implements FocusListener { + + private String previousText; + private EmptyListener emptyListener; + + public EmptyLabel(String text) { + // Front-end Characteristics + super(text); + setBackground(Color.WHITE); + setOpaque(true); + setDocument(new TaskLabelFilter()); + setText(text); + + // Add Listener for when focus is placed inside + addFocusListener(this); + + // Add Listener that does something with object when <Enter> is pressed + addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (getText().matches("[0-9]+")) { + emptyListener.emptyUpdate(); + } + } + }); + } + + /* + * Sets observer of this class + * (Would have used observable superclass unless I already had a superclass) + */ + public void addEmptyListener(EmptyListener emptyListener) { + this.emptyListener = emptyListener; + } + + /* + * FocusListener Functions. + */ + + /* + * Invoked when a component gains the keyboard focus. + */ + public void focusGained(FocusEvent e) { + previousText = getText(); + } + + /* + * Invoked when a component loses the keyboard focus. + */ + public void focusLost(FocusEvent e) { + if (!previousText.equals(getText()) && getText().matches("[0-9]+")) { + emptyListener.emptyUpdate(); + } else { + setText(previousText); + } + } +} diff --git a/gui/tasksetgui/EmptyListener.java b/gui/tasksetgui/EmptyListener.java new file mode 100644 index 0000000000000000000000000000000000000000..5d04dcbd2e34a6445b03fabb331c6af19e6078ca --- /dev/null +++ b/gui/tasksetgui/EmptyListener.java @@ -0,0 +1,13 @@ +package gui.tasksetgui; + +/* + * NOTE: TWO INTERFACES ARE NEEDED SUCH THAT THE UI ISN'T UPDATED WHEN MARKED. + */ +public interface EmptyListener { + + /* + * The update action to perform when something happens with EmptyTaskGrid + */ + public void emptyUpdate(); + +} diff --git a/gui/tasksetgui/EmptyTaskGrid.java b/gui/tasksetgui/EmptyTaskGrid.java new file mode 100644 index 0000000000000000000000000000000000000000..fdfc3e848ea6f6b036cebe24c2443ced8afe1a8c --- /dev/null +++ b/gui/tasksetgui/EmptyTaskGrid.java @@ -0,0 +1,86 @@ +package gui.tasksetgui; + +import java.util.HashMap; +import java.util.Map; +import java.awt.Color; + +import gui.GridPanel; + +public class EmptyTaskGrid extends GridPanel implements EmptyListener { + + private String[] attributes = new String[] {"Pri", "e", "p", "d"}; + private boolean full = false; + private Map<String, EmptyLabel> labelMap; + private EmptyListener emptyListener; + + // attributes should contain [prio, exectime, period, deadline] + public EmptyTaskGrid(String prio) { + super(1, 4); + labelMap = new HashMap<>(); + // Add priority label + EmptyLabel prioLabel = new EmptyLabel(prio); + prioLabel.addEmptyListener(this); + prioLabel.setEditable(false); // Forbids people from changing priority + add(prioLabel); + labelMap.put(attributes[0], prioLabel); + + + for (int i = 1; i < 4; i++) { + EmptyLabel label = new EmptyLabel(""); + label.addEmptyListener(this); + + add(label); + labelMap.put(attributes[i], label); + } + + colorize(Color.RED); + } + + /* + * return: attributes from this gridLine + */ + public int[] getAttributes() { + int[] attr = new int[4]; + for (int i = 0; i < 4; i++) { + EmptyLabel label = labelMap.get(attributes[i]); + attr[i] = Integer.parseInt(label.getText()); + } + return attr; + } + + /* + * Check whether this taskgrid is still empty + */ + public boolean isEmpty() { + for (int i = 1; i < 4; i++) { + EmptyLabel label = labelMap.get(attributes[i]); + if (label.getText().isEmpty()) { + return true; + } + } + return false; + } + + /* + * The function to be performed when the observable class is updated. + * NOTE: TWO INTERFACES ARE NEEDED SUCH THAT THE UI ISN'T UPDATED ONLY WHEN MARKED. + */ + public void emptyUpdate() { + emptyListener.emptyUpdate(); + } + + /* + * Sets observer of this class + * (Would have used observable superclass unless I already had a superclass) + */ + public void addEmptyListener(EmptyListener emptyListener) { + this.emptyListener = emptyListener; + } + + //Private help function to reduce code size + private void colorize(Color c) { + for (EmptyLabel tl : labelMap.values()) { + tl.setBackground(c); + } + } +} diff --git a/gui/tasksetgui/TasksetDisplay.java b/gui/tasksetgui/TasksetDisplay.java index 2dd86729b3261d422b80e298593e3364bf91b93a..7117e9647b82696a03ced9f403f9d292ba84ea36 100644 --- a/gui/tasksetgui/TasksetDisplay.java +++ b/gui/tasksetgui/TasksetDisplay.java @@ -17,13 +17,16 @@ import tasks.Taskset; import gui.BoxPanel; import gui.UpdateListener; -public class TasksetDisplay extends BoxPanel implements Observer, UpdateListener, MarkListener { +public class TasksetDisplay extends BoxPanel implements Observer, UpdateListener, MarkListener, EmptyListener { + private final int offset = 200; private Taskset taskset; - private TaskGridHeader header = new TaskGridHeader(" Priority", "Exectime", " Period", "Deadline"); private List<TaskGrid> gridList = new ArrayList<>(); + + private TaskGridHeader header = new TaskGridHeader(" Priority", "Exectime", " Period", "Deadline"); + private Optional<EmptyTaskGrid> empty = Optional.empty(); private Optional<TaskGrid> marked = Optional.empty(); // Used to indicate which taskgrid is marked - private final int offset = 200; + public TasksetDisplay(Taskset taskset) { super(BoxLayout.PAGE_AXIS); @@ -67,6 +70,12 @@ public class TasksetDisplay extends BoxPanel implements Observer, UpdateListener // Mark the previously marked one. marked.ifPresent(taskGrid -> taskGrid.mark()); + + // Add empty if exists + if (empty.isPresent()) { + add(empty.get()); + revalidate(); + } } /* @@ -97,6 +106,32 @@ public class TasksetDisplay extends BoxPanel implements Observer, UpdateListener marked.get().mark(); } + /* + * Updates the empty grid when things happen + */ + public void emptyUpdate() { + if (empty.isPresent() && !empty.get().isEmpty()) { + int[] attr = empty.get().getAttributes(); + empty = Optional.empty(); + taskset.addTask(attr[1], attr[2], attr[3]); + } + } + + /* + * Adds EmptyTaskGrid unless one already exists + */ + public void addEmpty() { + if (!empty.isPresent()) { + String prio = parse(taskset.nbrTasks() + 1); + + EmptyTaskGrid emptyGrid = new EmptyTaskGrid(prio); + emptyGrid.addEmptyListener(this); + empty = Optional.of(emptyGrid); + + add(emptyGrid); + revalidate(); + } + } /* * Removes marked task. Not if none is marked. diff --git a/gui/tasksetgui/TasksetPanel.java b/gui/tasksetgui/TasksetPanel.java index 92671bebda6ae90fd0595bcecf691a4592d4cf50..a06b42c64467eeaa02bc2c30635f9862a7b356c5 100644 --- a/gui/tasksetgui/TasksetPanel.java +++ b/gui/tasksetgui/TasksetPanel.java @@ -6,18 +6,17 @@ import java.awt.Color; import javax.swing.BorderFactory; import gui.BorderPanel; -import model.Status; import tasks.Taskset; public class TasksetPanel extends BorderPanel { - public TasksetPanel(Taskset ts, Status status) { + public TasksetPanel(Taskset ts) { setBackground(Color.LIGHT_GRAY); setBorder(BorderFactory.createTitledBorder("Taskset")); TasksetDisplay tsDisplay = new TasksetDisplay(ts); add(CENTER, tsDisplay); - add(NORTH, new ButtonPanel(ts, tsDisplay, status)); + add(NORTH, new ButtonPanel(tsDisplay)); } }