Commit 91a440f6 authored by Nils Vreman's avatar Nils Vreman
Browse files

Added ScheduLearn project to my project folder

parents
package gui.tasksetgui;
public class RemoveDialog extends MultiInputPane {
public RemoveDialog() {
super(1);
}
protected String[] labelTitles() {
return new String[] {"Priority"};
}
protected String generateDialogMessage() {
return "Please Enter Priority Of Task To Remove";
}
}
package gui.tasksetgui;
import java.util.HashMap;
import java.util.Map;
import java.awt.Color;
import gui.GridPanel;
import gui.UpdateListener;
public class TaskGrid extends GridPanel implements UpdateListener, MarkListener {
private String[] attributes = new String[] {"Pri", "e", "p", "d"};
private Map<String, TaskLabel> labelMap;
private UpdateListener updateListener;
private MarkListener markListener;
// attributes should contain [prio, exectime, period, deadline]
public TaskGrid(String[] taskAttributes) {
super(1, 4);
labelMap = new HashMap<>();
for (int i = 0; i < 4; i++) {
TaskLabel label = new TaskLabel(taskAttributes[i]);
label.addUpdateListener(this);
label.addMarkListener(this);
if (i == 0) label.setEditable(false); // Forbids people from changing priority
add(label);
labelMap.put(attributes[i], label);
}
}
public TaskGrid(String prio, String exec, String period, String deadline) {
this(new String[] {prio, exec, period, deadline});
}
/*
* return: attributes from this gridLine
*/
public int[] getAttributes() {
int[] attr = new int[4];
for (int i = 0; i < 4; i++) {
TaskLabel label = labelMap.get(attributes[i]);
attr[i] = Integer.parseInt(label.getText());
}
return attr;
}
/*
* Compares two taskgrid objects and returns the equality between the two
*/
public boolean equals(TaskGrid tg) {
return getAttributes()[0] == tg.getAttributes()[0];
}
/*
* 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 update(Object obj) {
updateListener.update(this);
}
/*
* The function to be performed when the tasklabel class is marked.
* NOTE: TWO INTERFACES ARE NEEDED SUCH THAT THE UI ISN'T UPDATED ONLY WHEN MARKED.
*/
public void markUpdate(Object obj) {
markListener.markUpdate(this);
}
/*
* Sets observer of this class
* (Would have used observable superclass unless I already had a superclass)
*/
public void addUpdateListener(UpdateListener updateListener) {
this.updateListener = updateListener;
}
/*
* Sets observer of this class
* (Would have used observable superclass unless I already had a superclass)
*/
public void addMarkListener(MarkListener markListener) {
this.markListener = markListener;
}
/*
* Marks all the tasklabels of this taskgrid.
*/
public void mark() {
colorize(Color.YELLOW);
}
/*
* Unmarks all the tasklabels of this taskgrid.
*/
public void unmark() {
colorize(Color.WHITE);
}
//Private help function to reduce code size
private void colorize(Color c) {
for (TaskLabel tl : labelMap.values()) {
tl.setBackground(c);
}
}
}
package gui.tasksetgui;
import javax.swing.JLabel;
import javax.swing.BorderFactory;
import javax.swing.border.BevelBorder;
import java.awt.Color;
import gui.GridPanel;
public class TaskGridHeader extends GridPanel {
// attributes should contain [prio, exectime, period, deadline]
public TaskGridHeader(String[] taskAttributes) {
super(1, 4);
setBackground(Color.WHITE);
for (int i = 0; i < 4; i++) {
JLabel label = new JLabel(taskAttributes[i]);
label.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
add(label);
}
}
public TaskGridHeader(String prio, String exec, String period, String deadline) {
this(new String[]{prio, exec, period, deadline});
}
}
package gui.tasksetgui;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.awt.Color;
import javax.swing.JTextField;
import gui.UpdateListener;
public class TaskLabel extends JTextField implements MouseListener {
private UpdateListener updateListener;
private MarkListener markListener;
public TaskLabel(String text) {
// Front-end Characteristics
super(text);
setBackground(Color.WHITE);
setOpaque(true);
setDocument(new TaskLabelFilter());
setText(text);
// Add Listener for when mouse does something with object
addMouseListener(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]+")) {
updateListener.update();
}
}
});
}
/*
* Sets observer of this class
* (Would have used observable superclass unless I already had a superclass)
*/
public void addUpdateListener(UpdateListener updateListener) {
this.updateListener = updateListener;
}
/*
* Sets observer of this class
* (Would have used observable superclass unless I already had a superclass)
*/
public void addMarkListener(MarkListener markListener) {
this.markListener = markListener;
}
// MouseListener Functions.
/*
* Invoked when the mouse button has been clicked (pressed and released) on a component.
*/
public void mouseClicked(MouseEvent e) {
markListener.markUpdate(this);
}
/*
* Invoked when a mouse button has been pressed on a component.
*/
public void mousePressed(MouseEvent e) {}
/*
* Invoked when a mouse button has been released on a component.
*/
public void mouseReleased(MouseEvent e) {}
/*
* Invoked when the mouse enters a component.
*/
public void mouseEntered(MouseEvent e) {}
/*
* Invoked when the mouse exits a component.
*/
public void mouseExited(MouseEvent e) {}
}
package gui.tasksetgui;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
public class TaskLabelFilter extends PlainDocument {
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
if (str == null) return;
String oldString = getText(0, getLength());
String newString = oldString.substring(0, offs) + str + oldString.substring(offs);
try {
Integer.parseInt(newString);
super.insertString(offs, str, a);
} catch (NumberFormatException e) {}
}
}
package gui.tasksetgui;
import javax.swing.BoxLayout;
import javax.swing.JPanel;
import java.awt.Dimension;
import java.util.Observer;
import java.util.Observable;
import java.util.Optional;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.NoSuchElementException;
import tasks.Taskset;
import gui.BoxPanel;
import gui.UpdateListener;
public class TasksetDisplay extends BoxPanel implements Observer, UpdateListener, MarkListener {
private Taskset taskset;
private TaskGridHeader header = new TaskGridHeader(" Priority", "Exectime", " Period", "Deadline");
private List<TaskGrid> gridList = new ArrayList<>();
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);
this.taskset = taskset;
taskset.addObserver(this);
add(header);
setMaximumSize(new Dimension(300, 35));
add(createVerticalStrut(offset));
}
public void update(Observable obs, Object obj) {
//Updates the box list
removeAll();
gridList.clear();
add(header);
Set<Integer> priorities = taskset.getPriorities();
for (int i : priorities) {
int[] t = taskset.getTask(i).get().attributes();
TaskGrid tg = new TaskGrid(parse(i), parse(t[0]), parse(t[1]), parse(t[2]));
tg.addUpdateListener(this);
tg.addMarkListener(this);
add(tg);
gridList.add(tg);
if (marked.map(taskgrid -> taskgrid.equals(tg)).orElse(false)) marked = Optional.of(tg);
revalidate();
}
// This section fixes the offset from
// the lowest priority task to the Southern border.
int taskOffset = priorities.size()*35;
if (offset - taskOffset > 0) {
setMaximumSize(new Dimension(300, 35 + taskOffset));
add(createVerticalStrut(offset - taskOffset));
revalidate();
}
// Mark the previously marked one.
marked.ifPresent(taskGrid -> taskGrid.mark());
}
/*
* 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 update(Object obj) {
TaskGrid tg = (TaskGrid) obj;
int[] attributes = tg.getAttributes();
try {
taskset.changeTask(attributes[0], attributes[1], attributes[2], attributes[3]);
} catch (NoSuchElementException e) {}
}
/*
* The function to be performed when the observable class is marked.
* NOTE: TWO INTERFACES ARE NEEDED SUCH THAT THE UI ISN'T UPDATED ONLY WHEN MARKED.
*/
public void markUpdate(Object obj) {
marked = Optional.of((TaskGrid) obj);
for (TaskGrid tg : gridList) {
//if (marked.map(taskgrid -> taskgrid.equals(tg)).orElse(false)) marked = Optional.of(tg);
tg.unmark();
}
marked.get().mark();
}
/*
* Removes marked task. Not if none is marked.
*/
public void removeMarked() {
int prio = marked
.map(grid -> grid.getAttributes()[0])
.orElse(-1);
try {
if (prio != -1) {
taskset.removeTask(prio);
marked = Optional.empty();
}
} catch (NoSuchElementException e) {}
}
// Private help method.
private String parse(int i) {
return String.valueOf(i);
}
}
package gui.tasksetgui;
import static java.awt.BorderLayout.CENTER;
import static java.awt.BorderLayout.NORTH;
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) {
setBackground(Color.LIGHT_GRAY);
setBorder(BorderFactory.createTitledBorder("Taskset"));
TasksetDisplay tsDisplay = new TasksetDisplay(ts);
add(CENTER, tsDisplay);
add(NORTH, new ButtonPanel(ts, tsDisplay, status));
}
}
1,2,2
1,4,4
1,8,8
1,16,16
package model;
public interface Cell {
public String toString();
public int value();
}
package model;
public class ColorCell implements Cell {
private ColorEnum color;
public ColorCell(int taskNbr) {
color = ColorEnum.valueOf(taskNbr);
}
public String toString() {
return color.toString();
}
public int value() {
return color.value();
}
}
package model;
import java.awt.Color;
public enum ColorEnum {
YELLOW(1),
GREEN(2),
RED(3),
BLUE(4),
MAGENTA(5),
CYAN(6),
ORANGE(7);
private int task;
private ColorEnum(int task) { this.task = task; }
public static ColorEnum valueOf(int task) {
switch(task) {
case 1: return (ColorEnum) YELLOW;
case 2: return (ColorEnum) GREEN;
case 3: return (ColorEnum) RED;
case 4: return (ColorEnum) BLUE;
case 5: return (ColorEnum) MAGENTA;
case 6: return (ColorEnum) CYAN;
case 7: default: return (ColorEnum) ORANGE;
}
}
public String toString() {
switch(this) {
case YELLOW: return "YELLOW";
case GREEN: return "GREEN";
case RED: return "RED";
case BLUE: return "BLUE";
case MAGENTA: return "MAGENTA";
case CYAN: return "CYAN";
case ORANGE: return "ORANGE";
default: return "";
}
}
public Color color() {
switch(this) {
case YELLOW: return Color.YELLOW;
case GREEN: return Color.GREEN;
case RED: return Color.RED;
case BLUE: return Color.BLUE;
case MAGENTA: return Color.MAGENTA;
case CYAN: return Color.CYAN;
case ORANGE: default: return Color.ORANGE;
}
}
public int value() { return task; }
}
package model;
public class EmptyCell implements Cell {
public String toString() { return ""; }
public int value() { return 0; }
}
package model;
import tasks.Taskset;
import tasks.Task;
import strategy.SchedulingStrategy;
import strategy.NoneStrategy;
import java.util.Arrays;
public class Schedule {
private SchedulingStrategy strategy;
private int[] schedule;
private Taskset ts;
public Schedule(Taskset ts) {
this.ts = ts;
strategy = new NoneStrategy();
}
public void setStrategy(SchedulingStrategy strategy) {
this.strategy = strategy;
schedule = strategy.generate(ts);
}
public SchedulingStrategy getStrategy() { return strategy; }
public boolean isValid() {
// If strategy does not exist or utilization is greater than 1:
// return false
if (strategy instanceof NoneStrategy ||
ts.utilization() > 1)
return false;
for (int taskNbr : ts.getPriorities()) {
Task t = ts.getTask(taskNbr).get(); //I know it exists so I can collect it from the optional directly
// Introduce this check to prevent deadline from being longer than period.
if (t.deadline() > t.period()) return false;
//Loops through the length of the hyperperiod as long as the generated schedule has enough length.
for (int i = 0; i < ts.hyperperiod(); i += t.period()) {
int added = 0;
for (int j = i; j < i + t.deadline(); j++) {
if (schedule[j] == taskNbr) added++;
}
if (added != t.exectime()) return false;
}
}
return true;
}
public int[] generateSchedule() {
schedule = strategy.generate(ts);
return schedule;
}
}
package model;
import java.util.Observable;
import java.util.Observer;
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;
import tasks.Taskset;
import strategy.SchedulingStrategy;
import strategy.NoneStrategy;
public class SchedulingModel extends Observable implements Observer {
private Schedule solution;
private Taskset taskset;
private Status status;
private Map<String, Cell> cells;
public SchedulingModel(Taskset ts, Status status) {
taskset = ts;
taskset.addObserver(this);
this.status = status;
solution = new Schedule(taskset);
cells = new HashMap<>();
}
/*
* Change Scheduling strategy
*/
public void setStrategy(SchedulingStrategy strategy) {
solution.setStrategy(strategy);
taskset.setComparator(strategy.prioComparator()); // Sets the comparator which orders the tasks
status.setStatus("Strategy Changed To " + strategy);
setChanged();
notifyObservers();
}
/*
* Get schedule as an int vector, each pos represent task number
*/
public int[] getSolution() {
return solution.generateSchedule();
}
/*
* returns whether solution matches the schedule generated by the user
*/
public boolean match() {
int[] sol = solution.generateSchedule();
if (cells.size() != countNonZero(sol)) return false; // Checks if have the same number of elements in both
int[] userSol = new int[sol.length];
Arrays.fill(userSol, -1);
for (Map.Entry<String, Cell> entry : cells.entrySet()) {