package graph; import java.util.HashMap; import java.util.List; import java.util.Arrays; /** * Die Klasse GraphElement ist eine Oberklasse von Knoten und Kanten. * Sie ist nur für die interne Verarbeitung wichtig. * * @author Thomas Schaller * @version 28.02.2023 (v7.0) * v7.0: Die am Element gespeicherten Informationen werden in einer Hashmap gespeichert. Daher können beliebige weitere Informationen abgelegt werden. * Es wird auch gespeichert, als welcher Typ die Information übergeben wurde. */ public abstract class GraphElement implements Comparable { protected HashMap daten; protected HashMap typen; protected Graph g; protected String sortierKriterium; public GraphElement() { daten = new HashMap(); typen = new HashMap(); } /** * Setzt den Status einer Kante, der in einem String gespeichert ist. * Form: markiert,geloescht,farbe * Dabei sind markiert und geloescht boolsche Werte (0 = false, 1 = true) und * die farbe eine Zahl * @param status Statusstring */ public void setStatus(String status) { List items = Arrays.asList(status.split("\\s*,\\s*")); for(int i=0; i< items.size(); i++) { String[] pair = items.get(i).split(":"); daten.put(pair[0], pair[1]); } } /** * Liefert den Status einer Kante als String. * Form: markiert,geloescht,farbe * Dabei sind markiert und geloescht boolsche Werte (0 = false, 1 = true) und * die farbe eine Zahl * @return Statusstring */ public String getStatus() { String s = ""; for (String i : daten.keySet()) { s = s + ","+i+":"+daten.get(i); } s = s.substring(1); return s; } /** Setzt das Sortierkriterium des Knoten/der Kante. * @param name Bezeichnung des Wertes nach dem sortiert werden soll */ public void setSortierkriterium(String name) { sortierKriterium = name; } /** Gibt die Beschreibung des Knoten / der Kante als Kurztext für die Anzeige im * Kreis bzw. Kasten zurück. Dabei wird jeder Eintrag der Liste als eigene Zeile * dargestellt. Es werden nur die Werte angezeigt. Es sind max. 2 Zeilen zulässig. * @param namen Namen der Werte, die im Kurztext angezeigt werden sollen. */ public abstract List getKurztext(String[] namen); /** Gibt die Beschreibung des Knoten / der Kante als Langtext für die Anzeige im * Tooltip-Fenster zurück. Dabei wird jeder Eintrag der Liste als eigene Zeile * dargestellt. Es wird jeweils die Bezeichnung und der Wert ausgegeben. * @param namen Namen der Werte, die im Tooltip angezeigt werden sollen. */ public abstract List getLangtext(String[] namen); /** Speichert den Graphen, in den Knoten/Kante eingefügt wurde. Damit kann er selbst seine Nummer * ermitteln. * @param g Graph */ public void setGraph(Graph g) { this.g = g; } /** Speichert zusätzliche Daten am Knoten oder der Kante * @param name Bezeichnung der Art der Daten * @param wert Wert der zu speichernden Daten */ public void set(String name, String wert) { wert = wert.replaceAll(":", ""); wert = wert.replaceAll(",", ""); daten.put(name.toLowerCase(), wert); typen.put(name.toLowerCase(), "String"); } /** Speichert zusätzliche Daten am Knoten oder der Kante * Double.POSITIVE_INFINITY bzw. NEGATIVE_INFINITY wird als +/- unendlich dargestellt * @param name Bezeichnung der Art der Daten * @param wert Wert der zu speichernden Daten */ public void set(String name, double wert) { if(wert == Double.POSITIVE_INFINITY) { daten.put(name.toLowerCase(), "\u221e"); } else { if(wert == Double.NEGATIVE_INFINITY) { daten.put(name.toLowerCase(), "-\u221e"); } else { if((int) wert == wert) { daten.put(name.toLowerCase(), ""+(int) wert); } else { daten.put(name.toLowerCase(), ""+wert); } } } typen.put(name.toLowerCase(), "Number"); } /** Speichert zusätzliche Daten am Knoten oder der Kante * Integer.MAX_VALUE bzw. MIN_VALUE werden als +/- unendlich dargestellt. * @param name Bezeichnung der Art der Daten * @param wert Wert der zu speichernden Daten */ public void set(String name, int wert) { typen.put(name.toLowerCase(), "Number"); if(wert == Integer.MAX_VALUE) { daten.put(name.toLowerCase(), "\u221e"); return; } if(wert == Integer.MIN_VALUE) { daten.put(name.toLowerCase(), "-\u221e"); return; } daten.put(name.toLowerCase(), ""+wert); } /** Speichert zusätzliche Daten am Knoten oder der Kante * @param name Bezeichnung der Art der Daten * @param wert Wert der zu speichernden Daten */ public void set(String name, boolean wert) { typen.put(name.toLowerCase(), "Boolean"); daten.put(name.toLowerCase(), ""+wert); } /** Gibt zusätzliche Daten als String zurück * @param name Bezeichnung der zusätzlichen Daten * @return Wert von "name" oder "", wenn name nicht gespeichert ist */ public String getString(String name) { if(daten.containsKey(name.toLowerCase())) { return daten.get(name.toLowerCase()); } else { return ""; } } /** Gibt zusätzliche Daten als int zurück * @param name Bezeichnung der zusätzlichen Daten * @return Wert von "name" oder 0, wenn name nicht gespeichert ist oder keine Zahl ist */ public int getInt(String name) { try{ if(daten.get(name.toLowerCase()).equals("\u221e")) return Integer.MAX_VALUE; if(daten.get(name.toLowerCase()).equals("-\u221e")) return Integer.MIN_VALUE; return Integer.parseInt(daten.get(name.toLowerCase())); } catch(Exception e) { return 0; } } /** Gibt zusätzliche Daten als int zurück * @param name Bezeichnung der zusätzlichen Daten * @return Wert von "name" oder 0, wenn name nicht gespeichert ist oder keine Zahl ist */ public double getDouble(String name) { try{ if(daten.get(name.toLowerCase()).equals("\u221e")) return Double.POSITIVE_INFINITY; if(daten.get(name.toLowerCase()).equals("-\u221e")) return Double.NEGATIVE_INFINITY; return Double.parseDouble(daten.get(name.toLowerCase())); } catch(Exception e) { return 0.0; } } /** Gibt zusätzliche Daten als int zurück * @param name Bezeichnung der zusätzlichen Daten * @return Wert von "name" oder false, wenn name nicht gespeichert ist oder kein Boolean ist */ public boolean getBoolean(String name) { try{ return Boolean.parseBoolean(daten.get(name.toLowerCase())); } catch(Exception e) { return false; } } /** Vergleicht den Knoten/Kante mit einem anderen Knoten/Kante bezüglich seines Sortierkriteriums * Das Sortierkriterium ist normalerweise der "Wert", kann aber mit setSortierkriterium gesetzt werden. * @param e anderer Knoten * @return kleiner 0 der andere Knoten hat einen größeren Wert, größer 0 der andere Knoten hat einen kleineren Wert, gleich 0 beide sind gleich */ public int compareTo(GraphElement e) { double w1, w2; String s1 = sortierKriterium.toLowerCase(); String s2 = e.sortierKriterium.toLowerCase(); if(!typen.get(s1).equals(e.typen.get(s2))) return 0; if(typen.get(s1).equals("String")){ return getString(s1).compareTo(e.getString(s2)); } if(typen.get(s1).equals("Number")){ return (int) (getDouble(s1) - e.getDouble(s2)); } if(typen.get(s1).equals("Boolean")){ if(getBoolean(s1) == e.getBoolean(s2)) return 0; if(getBoolean(s1)) return 1; else return -1; } return 0; } }