package addOns; import java.awt.BorderLayout; import java.awt.Dimension; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import java.util.stream.Collectors; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.text.NumberFormatter; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonIOException; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; import api.AddOn; import classes.AbstractCanvasObject; import classes.Constrain; import classes.GroupNode; import classes.Flexibility; import classes.HolonElement; import classes.HolonElement.Priority; import classes.HolonObject; import classes.HolonSwitch; import ui.controller.Control; import ui.model.Model; public class Randomizer implements AddOn { private Control control; private int minAmountOfElements = 3; private int maxAmountOfElements = 7; private JPanel content = new JPanel(); //To Test the Layout Faster public static void main(String[] args) { JFrame newFrame = new JFrame("exampleWindow"); Randomizer instance = new Randomizer(); newFrame.setContentPane(instance.getPanel()); newFrame.pack(); newFrame.setVisible(true); newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } private File file; public double randomChance = 1.0; public Randomizer(){ content.setLayout(new BorderLayout()); content.add(createParameterPanel(), BorderLayout.CENTER); JButton buttonRun = new JButton("Run"); buttonRun.addActionListener(actionEvent -> run()); content.add(buttonRun, BorderLayout.PAGE_END); content.setPreferredSize(new Dimension(300,300)); } private JPanel createParameterPanel() { JPanel parameterPanel = new JPanel(null); parameterPanel.setPreferredSize(new Dimension(300,300)); JLabel minAmount = new JLabel("minAmountOfElements:"); minAmount.setBounds(20, 60 , 200, 20); parameterPanel.add(minAmount); JLabel maxAmount = new JLabel("maxAmountOfElements:"); maxAmount.setBounds(20, 85 , 200, 20); parameterPanel.add(maxAmount); //Integer formatter NumberFormat format = NumberFormat.getIntegerInstance(); format.setGroupingUsed(false); format.setParseIntegerOnly(true); NumberFormatter integerFormatter = new NumberFormatter(format); integerFormatter.setMinimum(0); integerFormatter.setCommitsOnValidEdit(true); JFormattedTextField minAmountTextField = new JFormattedTextField(integerFormatter); minAmountTextField.setValue(this.minAmountOfElements); minAmountTextField.setToolTipText("Only positive Integer."); minAmountTextField.addPropertyChangeListener(actionEvent -> this.minAmountOfElements = Integer.parseInt(minAmountTextField.getValue().toString())); minAmountTextField.setBounds(220, 60, 50, 20); parameterPanel.add(minAmountTextField); JFormattedTextField maxAmountTextField = new JFormattedTextField(integerFormatter); maxAmountTextField.setValue(this.maxAmountOfElements); maxAmountTextField.setToolTipText("Only positive Integer."); maxAmountTextField.addPropertyChangeListener(actionEvent -> this.maxAmountOfElements = Integer.parseInt(maxAmountTextField.getValue().toString())); maxAmountTextField.setBounds(220, 85, 50, 20); parameterPanel.add(maxAmountTextField); JButton chooseFileButton = new JButton("Choose File"); chooseFileButton.setBounds(20, 10, 200, 30); chooseFileButton.addActionListener(actionEvent -> file = openCatalogFile()); parameterPanel.add(chooseFileButton); JSlider bitSlider = createFlipChanceSlider(); bitSlider.setBounds(10, 110, 280, 80); parameterPanel.add(bitSlider); return parameterPanel; } private void run() { List holonElementCatalog = new ArrayList(); if(file == null)file = openCatalogFile(); if(file == null) return; readCatalogFromJson(file, holonElementCatalog); holonElementCatalog.forEach(con -> con.checkValues()); List holonObjectList = new ArrayList(); rollOutNodes(control.getModel().getObjectsOnCanvas(), holonObjectList, control.getModel().getCurIteration()); holonObjectList.forEach(con -> { con.getElements().clear(); int randomAmountOfElementsToAdd = Random.nextIntegerInRange(minAmountOfElements, maxAmountOfElements + 1); for(int i = 0; i < randomAmountOfElementsToAdd; i++) { HolonElement ele = holonElementCatalog.get(Random.nextIntegerInRange(0, holonElementCatalog.size())).createHolonElement(control.getModel(), Random.nextDouble() < randomChance , con.getName()); con.getElements().add(ele); } }); control.calculateStateAndVisualForCurrentTimeStep(); control.updateCanvas(); } private void rollOutNodes(List nodes, List consumerList, int timeStep) { for (AbstractCanvasObject aCps : nodes) { if (aCps instanceof HolonObject) { HolonObject hO = (HolonObject) aCps; //if(hO.getEnergyAtTimeStep(control.getModel().getCurIteration()) < 0) consumerList.add(hO); } else if(aCps instanceof GroupNode) { rollOutNodes(((GroupNode)aCps).getNodes(), consumerList ,timeStep ); } } } @Override public JPanel getPanel() { return content; } @Override public void setController(Control control) { this.control = control; } private class HolonElementSketch { //HolonElement public String name; public int minAmount; public int maxAmount; public float energy; public String priority; //Flexibility public double flexChance; @Expose public float minCost; public float maxCost; /** The Duration in TimeSteps how long the Flexibility is activated.*/ private int minDuration; private int maxDuration; /** The Duration after a successful activation between the next possible activation.*/ private int minCooldown; private int maxCooldown; public HolonElementSketch(String name, int minAmount, int maxAmount, float energy) { this.name = name; this.minAmount = minAmount; this.maxAmount = maxAmount; this.energy = energy; } public HolonElement createHolonElement(Model model, boolean active, String nameOfHolonObject) { HolonElement ele = new HolonElement(name, Random.nextIntegerInRange(minAmount, maxAmount + 1), energy , model); ele.setActive(active); if(Random.nextDouble() < flexChance)addFlex(ele, nameOfHolonObject); ele.setPriority(Priority.valueOf(priority)); return ele; } public void checkValues() { minAmount = Math.abs(minAmount); maxAmount = Math.abs(maxAmount); if(maxAmount < minAmount) { //Swap int intermediate = minAmount; minAmount = maxAmount; maxAmount = intermediate; } minDuration = Math.abs(minDuration); maxDuration = Math.abs(maxDuration); if(maxDuration < minDuration) { //Swap int intermediate = minDuration; minDuration = maxDuration; maxDuration = intermediate; } minCooldown = Math.abs(minCooldown); maxCooldown = Math.abs(maxCooldown); if(maxCooldown < minCooldown) { //Swap int intermediate = minCooldown; minCooldown = maxCooldown; maxCooldown = intermediate; } minCost = Math.abs(minCost); maxCost = Math.abs(maxCost); if(maxCost < minCost) { //Swap float intermediate = minCost; minCost = maxCost; maxCost = intermediate; } flexChance = Math.max(0, Math.min(1, flexChance)); //Clamp } public void addFlex(HolonElement ele, String nameOfHolonObject) { Flexibility toCreateFlex = new Flexibility(ele); boolean flexType = ele.isActive(); toCreateFlex.name = nameOfHolonObject + "_" + ele.getEleName() + (flexType?"_OnFlex":"_OffFlex"); toCreateFlex.speed = 0; toCreateFlex.setDuration(Random.nextIntegerInRange(minDuration, maxDuration+1)); toCreateFlex.cost = Random.nextFloatInRange(minCost, maxCost); toCreateFlex.setCooldown(Random.nextIntegerInRange(minCooldown, maxCooldown+1)); toCreateFlex.offered=true; if(flexType) { toCreateFlex.constrainList.add(Constrain.createOnConstrain()); }else { toCreateFlex.constrainList.add(Constrain.createOffConstrain()); } ele.flexList.add(toCreateFlex); } } private JSlider createFlipChanceSlider() { JSlider flipChance =new JSlider(JSlider.HORIZONTAL,0, 100, 100); flipChance.setBorder(BorderFactory.createTitledBorder("ActiveProbability")); flipChance.setMajorTickSpacing(50); flipChance.setMinorTickSpacing(5); flipChance.setPaintTicks(true); Hashtable labelTable = new Hashtable(); labelTable.put( Integer.valueOf(0), new JLabel("0.0") ); labelTable.put( Integer.valueOf(50), new JLabel("0.5") ); labelTable.put( Integer.valueOf(100), new JLabel("1.0") ); flipChance.addChangeListener(actionEvent ->randomChance =(double)flipChance.getValue()/100.0); flipChance.setLabelTable( labelTable ); flipChance.setPaintLabels(true); return flipChance; } private static class Random{ private static java.util.Random random = new java.util.Random(); /** * True or false * @return the random boolean. */ public static boolean nextBoolean(){ return random.nextBoolean(); } /** * Between 0.0(inclusive) and 1.0 (exclusive) * @return the random double. */ public static double nextDouble() { return random.nextDouble(); } public static float nextFloatInRange(float min, float max) { return min + random.nextFloat() * Math.abs(max - min); } public static double nextDoubleInRange(double min, double max) { return min + random.nextDouble() * Math.abs(max - min); } /** * Random Int in Range [min;max[ with UniformDistirbution * @param min * @param max * @return */ public static int nextIntegerInRange(int min, int max) { return min + random.nextInt(max - min); } } private void readCatalogFromJson(File file, List catalog) { Gson gson = new Gson(); JsonParser parser = new JsonParser(); try { JsonElement jsonTreeRoot = parser.parse(new FileReader(file)); if(jsonTreeRoot.isJsonArray()) { JsonArray jsonArray = jsonTreeRoot.getAsJsonArray(); jsonArray.forEach(jsonObject -> { HolonElementSketch newObject= gson.fromJson( jsonObject, HolonElementSketch.class); catalog.add(newObject); }); } } catch (JsonSyntaxException e) { e.printStackTrace(); } catch (JsonIOException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } } public File openCatalogFile() { JFileChooser fileChooser = new JFileChooser(); fileChooser.setCurrentDirectory(new File(System.getProperty("user.dir")+"/randomizerConfigFiles/")); fileChooser.setFileFilter(new FileNameExtensionFilter("JSON Files", "json")); fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); fileChooser.setAcceptAllFileFilterUsed(false); int result = fileChooser.showOpenDialog(content); if(result == JFileChooser.APPROVE_OPTION) { //Found a file return fileChooser.getSelectedFile(); } return null; } }