diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9086755 --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +abgaben/ +code/ +vpl/ + +# emacs stuff +*~ +\#*# + +# javadoc stuff +*.html +*.js +*.css + +# intellij stuff +.idea/ +*.iml +build/ +classes/ +out/ diff --git a/tut9/src/AddSet.java b/tut9/src/AddSet.java new file mode 100644 index 0000000..caced45 --- /dev/null +++ b/tut9/src/AddSet.java @@ -0,0 +1,45 @@ +/** + * @param Element type. + * Simple functional set adding an element to another simple functional set. + */ +public class AddSet extends SimpleFunctionalSet +{ + /** + * The element to add. + */ + private final E element; + + /** + * @param elem The element to add. + * @param s The remaining set. + */ + public AddSet(E elem, SimpleFunctionalSet s) + { + super(s); + this.element = elem; + } + + @Override + public boolean contains(Object o) + { + if (this.element == null) + { + if (o == null) + return true; + else + return this.getRemainingSet().contains(o); + } + else if (this.element.equals(o)) + return true; + else + return this.getRemainingSet().contains(o); + } + + /** + * @return The element to add. + */ + public E getElement() + { + return this.element; + } +} diff --git a/tut9/src/EmptySet.java b/tut9/src/EmptySet.java new file mode 100644 index 0000000..b251569 --- /dev/null +++ b/tut9/src/EmptySet.java @@ -0,0 +1,21 @@ +/** + * @param Element type. + * Simple functional set containing no element. + */ +public class EmptySet extends SimpleFunctionalSet +{ + /** + * Creates an empty simple functional set. + */ + public EmptySet() + { + super(null); + } + + @Override + public boolean contains(Object o) + { + return false; + } + +} diff --git a/tut9/src/FunctionalSet.java b/tut9/src/FunctionalSet.java new file mode 100644 index 0000000..b635fc9 --- /dev/null +++ b/tut9/src/FunctionalSet.java @@ -0,0 +1,242 @@ +import java.util.*; + +/** + * Functional data structure for a set. + * + * @param Element type. + */ +public class FunctionalSet implements Set +{ + /** + * The head of the list of operations representing the set. + */ + private SimpleFunctionalSet head; + + public String toString() + { + String res = "{"; + Iterator it = iterator(); + while (it.hasNext()) + { + res = res + it.next(); + if (it.hasNext()) + { + res = res + ", "; + } + } + return res + "}"; + } + + /** + * Creates an empty functional set. + */ + public FunctionalSet() + { + this.head = new EmptySet(); + } + + @Override + public boolean add(E e) + { + if (this.contains(e)) + { + return false; + } + else + { + this.head = new AddSet(e, this.head); + return true; + } + } + + @Override + public boolean addAll(Collection c) + { + boolean res = false; + for (E elem : c) + { + res |= this.add(elem); + } + return res; + } + + @Override + public void clear() + { + this.head = new EmptySet(); + } + + @Override + public boolean contains(Object o) + { + return this.head.contains(o); + } + + @Override + public boolean containsAll(Collection c) + { + for (Object o : c) + { + if (!this.contains(o)) + { + return false; + } + } + return true; + } + + @Override + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + else if (o == null || o.getClass() != this.getClass()) + { + return false; + } + else + { + FunctionalSet set = (FunctionalSet) o; + return this.containsAll(set) && set.containsAll(this); + } + } + + @Override + public int hashCode() + { + int res = 5; + final int prime = 7; + for (E elem : this) + { + res += prime * elem.hashCode(); + } + return res; + } + + @Override + public boolean isEmpty() + { + return this.size() == 0; + } + + @Override + public Iterator iterator() + { + return new FunctionalSetIterator(this, this.head); + } + + @Override + public boolean remove(Object o) + { + if (this.contains(o)) + { + this.head = new RemoveSet(o, this.head); + return true; + } + else + { + return false; + } + } + + @Override + public boolean removeAll(Collection c) + { + boolean res = false; + for (Object o : c) + { + res |= this.remove(o); + } + return res; + } + + @Override + public boolean retainAll(Collection c) + { + List store = new ArrayList(); + boolean change = false; + for (E elem : this) + { + if (c.contains(elem)) + { + store.add(elem); + } + else + { + change = true; + } + } + if (change) + { + this.clear(); + for (E elem : store) + { + this.add(elem); + } + return true; + } + else + { + return false; + } + } + + @Override + public int size() + { + int res = 0; + for (Iterator it = this.iterator(); it.hasNext(); it.next()) + { + res++; + } + return res; + } + + @Override + public Object[] toArray() + { + Object[] res = new Object[this.size()]; + int i = 0; + for (E elem : this) + { + res[i] = elem; + i++; + } + return res; + } + + @SuppressWarnings("unchecked") + @Override + public T[] toArray(T[] a) + { + final int size = this.size(); + final T[] res; + if (a.length < size) + { + res = Arrays.copyOf(a, size); + } + else + { + res = a; + } + int i = 0; + for (E elem : this) + { + try + { + res[i] = (T) elem; + } + catch (ClassCastException e) + { + throw new ArrayStoreException( + "Element " + elem + " cannot be cast to type of specified array!" + ); + } + i++; + } + return res; + } + +} diff --git a/tut9/src/Main.java b/tut9/src/Main.java new file mode 100644 index 0000000..f20acd6 --- /dev/null +++ b/tut9/src/Main.java @@ -0,0 +1,34 @@ +import java.util.*; + +public class Main +{ + public static void main(String args[]) + { + FunctionalSet s = new FunctionalSet<>(); + String line; + do + { + line = SimpleIO.getString("Enter 'add i', 'remove i', 'min', or 'exit'!"); + String[] words = line.split(" "); + switch (words[0]) + { + case "exit": + break; + case "add": + s.add(Integer.parseInt(words[1])); + System.out.println(s); + break; + case "remove": + s.remove(Integer.parseInt(words[1])); + System.out.println(s); + break; + case "min": + System.out.println(s.min(Comparator.naturalOrder())); + break; + default: + System.out.println("Unknown command."); + } + } + while (!"exit".equals(line)); + } +} diff --git a/tut9/src/RemoveSet.java b/tut9/src/RemoveSet.java new file mode 100644 index 0000000..79f2de3 --- /dev/null +++ b/tut9/src/RemoveSet.java @@ -0,0 +1,46 @@ +/** + * @param Element type. + * Simple set removing an object from another simple set. + */ +public class RemoveSet extends SimpleFunctionalSet +{ + /** + * The object to remove. + */ + private final Object obj; + + /** + * @param o The object to remove. + * @param s The remaining set. + */ + public RemoveSet(Object o, SimpleFunctionalSet s) + { + super(s); + this.obj = o; + } + + @Override + public boolean contains(Object o) + { + if (this.obj == null) + { + if (o == null) + return false; + else + return this.getRemainingSet().contains(o); + } + else if (this.obj.equals(o)) + return false; + else + return this.getRemainingSet().contains(o); + } + + /** + * @return The object to remove. + */ + public Object getObject() + { + return this.obj; + } + +} diff --git a/tut9/src/SimpleFunctionalSet.java b/tut9/src/SimpleFunctionalSet.java new file mode 100644 index 0000000..f5b244a --- /dev/null +++ b/tut9/src/SimpleFunctionalSet.java @@ -0,0 +1,40 @@ +/** + * @param Element type. + * Abstract class for simple functional sets just offering a characteristic function realized by the + * contains method. + */ +public abstract class SimpleFunctionalSet +{ + /** + * The remaining set. + */ + private final SimpleFunctionalSet set; + + /** + * @param s The remaining set. + */ + public SimpleFunctionalSet(SimpleFunctionalSet s) + { + this.set = s; + } + + /** + * Returns true if this set contains the specified element. + * More formally, contains(o) returns true if and only if this set + * contains an element e such that + * (o==null ? e==null : e.equals(o)). + * + * @param o Element whose presence in this set is to be tested. + * @return true if this set contains the specified element. + */ + public abstract boolean contains(Object o); + + /** + * @return The remaining set. + */ + public SimpleFunctionalSet getRemainingSet() + { + return this.set; + } + +} diff --git a/tut9/src/SimpleIO.java b/tut9/src/SimpleIO.java new file mode 100644 index 0000000..ee4199f --- /dev/null +++ b/tut9/src/SimpleIO.java @@ -0,0 +1,430 @@ +import javax.swing.*; +import java.awt.*; +import java.util.Optional; +import java.util.Scanner; + +/** + * @author Thomas Stroeder, Maximilian Hippler + * @version 15.11.2019 + * Actual version under: https://git.rwth-aachen.de/maxemann96/SimpleIO + *

+ * Class SimpleIO - class for input of simple input types + * via simple dialog box (or if headless System.in use) + * and output of strings (via dialog box or System.out) + */ + +public class SimpleIO { + /** + * Initial set headless mode by environment variable and system default + * Can be changed with preferConsole() or preferUI() + */ + private static boolean HEADLESS; + + static { + //System default + HEADLESS = GraphicsEnvironment.isHeadless(); + + //If ENV-Variable is set, override default headless flag + try { + HEADLESS |= Optional.ofNullable(System.getenv("SIMPLE_IO_HEADLESS")).orElse("FALSE") + .equalsIgnoreCase("TRUE"); + } catch (SecurityException e) {/*Ignore this exception, do not set flag if thrown*/} + } + + /** + * Gets an input object from the console. If options are supplied, the return-object ist one of options. + * If no options are supplied, T must be a primitive type. + * + * @param tClass This method returns object that are instances of this tClass + * @param title Title of the prompt + * @param messages The messages to display the user + * @param options The provided options, can be null, but then tClass must be primitive + * @param initialOption The initial option (Hint for the user) + * @param To specify return type and some parameter types + * @return The object the user entered + */ + private static T getInputObjectConsole(Class tClass, String title, Object[] messages, + T[] options, T initialOption) { + Scanner scanner = new Scanner(System.in); + + System.out.println(title); + + for (Object o : messages) + System.out.println(o.toString()); + + if (options != null) { + System.out.print("Bitte auswaehlen: |"); + + for (Object option : options) { + if (option == initialOption) { + System.out.print(" (INITIAL)"); + } + + + System.out.print(" " + option.toString() + " |"); + } + + System.out.println(); + } + + String result = scanner.nextLine(); + + if (options != null) { + for (T option : options) { + if (option.toString().equals(result)) + return option; + } + + return result.equals("") && initialOption != null ? initialOption : null; + } else { + return parseInput(tClass, result); + } + } + + /** + * Gets an input object from a JOptionPane. If options are supplied, the return-object ist one of options. + * If no options are supplied, T must be a primitive type. + * + * @param tClass This method returns object that are instances of this tClass + * @param title Title of the prompt + * @param messages The messages to display the user + * @param options The provided options, can be null, but then tClass must be primitive + * @param initialOption The initial option (Hint for the user) + * @param To specify return type and some parameter types + * @return The object the user entered + */ + private static T getInputObjectJOptionPane(Class tClass, String title, Object[] messages, + T[] options, T initialOption) { + T tmp; + + if (options == null) { + tmp = parseInput(tClass, JOptionPane.showInputDialog(null, messages, title, JOptionPane.QUESTION_MESSAGE)); + } else { + // 3 or less options, display with buttons + if (options.length <= 3) { + int result = JOptionPane.showOptionDialog(null, messages, title, + JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, + null, options, initialOption); + + tmp = result == JOptionPane.CLOSED_OPTION ? null : options[result]; + } + //Else display wih JComboBox + else { + JComboBox comboBox = new JComboBox<>(); + + for (T item : options) { + comboBox.addItem(item); + } + + comboBox.setSelectedItem(initialOption); + + Object[] messagesObject = new Object[messages.length + 1]; + System.arraycopy(messages, 0, messagesObject, 0, messages.length); + messagesObject[messages.length] = comboBox; + + int result = JOptionPane.showOptionDialog(null, messagesObject, title, + JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, + null, null, null); + + tmp = result == JOptionPane.OK_OPTION ? (T) comboBox.getItemAt(comboBox.getSelectedIndex()) : null; + } + } + + return tmp; + } + + /** + * Parses the input, input must be primitive + * + * @param parseClass The class to return + * @param input The String-input to parse + * @param The Type of class returned + * @return The parsed input, for an Integer for example, Integer.valueOf(input) is used + */ + private static T parseInput(Class parseClass, String input) { + Object toReturn = null; + + //If user not aborted + if (input != null) { + //First check String + if (parseClass.equals(String.class)) { + toReturn = input; + } + //then boolean + else if (parseClass.equals(Boolean.class)) { + toReturn = Boolean.parseBoolean(input); + } + //now character + else if (parseClass.equals(Character.class)) { + if (input.length() != 1) { + throw new IllegalArgumentException("Ein Char wurde erwartet, nicht der String \"" + input + "\""); + } + + toReturn = input.charAt(0); + } + //Can be an integer or ... + else if (parseClass.equals(Integer.class)) { + toReturn = Integer.valueOf(input); + } + //... a double or ... + else if (parseClass.equals(Double.class)) { + toReturn = Double.valueOf(input); + } + //a float + else if (parseClass.equals(Float.class)) { + toReturn = Float.valueOf(input); + } + } + + //Safe call, if toReturn is not set, its null. If set, each if-Statements guarantees, that it is of type T + return parseClass.cast(toReturn); + } + + /** + * String input from the user via a simple dialog. + * + * @param prompt the message string to be displayed inside dialog + * @return String input from the user. Null if user canceled providing input + **/ + public static String getString(String prompt) { + return getGenericObject(String.class, prompt, null, null); + } + + /** + * char input from the user via a simple dialog. + * + * @param prompt the message string to be displayed inside dialog + * @return char input from the user. Character.MAX_VALUE if user canceled input. + **/ + public static char getChar(String prompt) { + return getChar(prompt, Character.MAX_VALUE); + } + + /** + * char input from the user via a simple dialog. + * + * @param prompt the message string to be displayed inside dialog + * @param defaultValue the value which will be returned if user cancels input + * @return char input from the user. + **/ + public static char getChar(String prompt, char defaultValue) { + Character c = getGenericObject(Character.class, prompt, null, null); + return c == null ? defaultValue : c; + } + + /** + * boolean selection from the user via a simple dialog. + * + * @param prompt message to appear in dialog + * @return boolean selection from the user. False if user canceled input. + **/ + public static boolean getBoolean(String prompt) { + return getBoolean(prompt, false); + } + + /** + * boolean selection from the user via a simple dialog. + * + * @param prompt message to appear in dialog + * @param defaultValue the value which will be returned if user cancels input + * @return boolean selection from the user. + **/ + public static boolean getBoolean(String prompt, boolean defaultValue) { + Boolean b = getGenericObject(Boolean.class, prompt, new Boolean[]{true, false}, true); + return b == null ? defaultValue : b; + } + + /** + * returns integer input from the user via a simple dialog. + * + * @param prompt the message string to be displayed inside dialog + * @return the input integer. Integer.MAX_VALUE if user canceled input + **/ + public static int getInt(String prompt) { + return getInt(prompt, Integer.MAX_VALUE); + } + + /** + * returns integer input from the user via a simple dialog. + * + * @param prompt the message string to be displayed inside dialog + * @param defaultValue the value which will be returned if user cancels input + * @return the input integer + **/ + public static int getInt(String prompt, int defaultValue) { + Integer i = getGenericObject(Integer.class, prompt, null, null); + return i == null ? defaultValue : i; + } + + + /** + * returns a float input from the user via a simple dialog. + * + * @param prompt the message string to be displayed inside dialog + * @return the input float. Float.NaN if user canceled input + **/ + public static float getFloat(String prompt) { + return getFloat(prompt, Float.NaN); + } + + /** + * returns a float input from the user via a simple dialog. + * + * @param prompt the message string to be displayed inside dialog + * @param defaultValue the value which will be returned if user cancels input + * @return the input float + **/ + public static float getFloat(String prompt, float defaultValue) { + Float f = getGenericObject(Float.class, prompt, null, null); + return f == null ? defaultValue : f; + } + + /** + * returns a double input from the user via a simple dialog. + * + * @param prompt the message string to be displayed inside dialog + * @return the input double. Double.NaN if user canceled input + **/ + public static double getDouble(String prompt) { + return getDouble(prompt, Double.NaN); + } + + /** + * returns a double input from the user via a simple dialog. + * + * @param prompt the message string to be displayed inside dialog + * @param defaultValue the value which will be returned if user cancels input + * @return the input double. Double.NaN if user canceled input + **/ + public static double getDouble(String prompt, double defaultValue) { + Double d = getGenericObject(Double.class, prompt, null, null); + return d == null ? defaultValue : d; + } + + /** + * Let the user choose between the specified options and return one of them or null + * + * @param prompt the message string to be displayed inside dialog + * @param options the available options the user choose from + * @param initialObject a hint for the user which option is default + * @return The option, the user has chosen. Null if user canceled input. + */ + public static Object getObject(String prompt, Object[] options, Object initialObject) { + return getGenericObject(Object.class, prompt, options, initialObject); + } + + /** + * Let the user choose between the specified options and return one of them or null + * + * @param prompt the message string to be displayed inside dialog + * @param options the available options the user choose from + * @return The option, the user has chosen. Null if user canceled input + */ + public static Object getObject(String prompt, Object[] options) { + return getGenericObject(Object.class, prompt, options, null); + } + + /** + * Let the user choose one item from any enum, return null if cancelled + * + * @param prompt the message string to be displayed inside dialog + * @param enumClass the enum class + * @param initialOption the option which is default selected + * @param The enum item class + * @return The option, the user has chosen. Null if user canceled input + */ + public static > T getFromEnum(String prompt, Class enumClass, T initialOption) { + return getGenericObject(enumClass, prompt, enumClass.getEnumConstants(), initialOption); + } + + /** + * Let the user choose one item from any enum, return null if cancelled + * + * @param prompt the message string to be displayed inside dialog + * @param enumClass the enum class + * @param The enum item class + * @return The option, the user has chosen. Null if user canceled input + */ + public static > T getFromEnum(String prompt, Class enumClass) { + return getGenericObject(enumClass, prompt, enumClass.getEnumConstants(), null); + } + + /** + * Let the user choose between the specified options and return one of them. if options are null, + * tClass must be primitive, so that the input can be parsed + * + * @param tClass The class to return + * @param prompt the message string to be displayed inside dialog + * @param options the available options the user choose from (can be null) + * @param initialOption a hint for the user which option is default (can be null) + * @param The Type of class returned + * @return The option, the user has chosen. Null if user canceled input + */ + public static T getGenericObject(Class tClass, String prompt, + T[] options, T initialOption) { + boolean isPrimitive = tClass == Double.class || tClass == Integer.class || tClass == Float.class + || tClass == String.class || tClass == Character.class || tClass == Boolean.class; + + boolean hasOptions = options != null && options.length > 0; + + if (!isPrimitive && !hasOptions) { + throw new IllegalArgumentException("Dies ist kein primitiver Datentyp, bitte spezifizieren."); + } + + String title = "Eingabefenster"; + T toReturn = null; + boolean success = false; + Object[] commentArray = {prompt, "", ""}; +// commentArray[1] = "Please enter a " + tClass.getName(); + while (!success) { + try { + toReturn = HEADLESS ? getInputObjectConsole(tClass, title, commentArray, options, initialOption) : + getInputObjectJOptionPane(tClass, title, commentArray, options, initialOption); + success = true; + } catch (IllegalArgumentException e) { + //Ignore exception, prompt user again! + commentArray[2] = "Falsche Eingabe, bitte wiederholen!"; + } + } + + return toReturn; + } + + /** + * Prints the String passed as content in a window. + * + * @param content the displayed String + **/ + public static void output(String content) { + output(content, "Ausgabe"); + } + + + /** + * prints the string "content" in a window with the title "prompt" + * + * @param content the string to be displayed + * @param prompt the name of the window + **/ + public static void output(String content, String prompt) { + if (HEADLESS) { + System.out.println(content); + } else { + JOptionPane.showMessageDialog(null, content, prompt, JOptionPane.PLAIN_MESSAGE); + } + } + + /** + * If the environment is not headless, input and output will be handled by ui + */ + public static void preferUI() { + HEADLESS = GraphicsEnvironment.isHeadless(); + } + + /** + * input and output will be handled by console + */ + public static void preferConsole() { + HEADLESS = true; + } +}