workcraft/workcraft

View on GitHub
workcraft/SonPlugin/src/org/workcraft/plugins/son/gui/ParallelSimDialog.java

Summary

Maintainability
A
3 hrs
Test Coverage
package org.workcraft.plugins.son.gui;

import org.workcraft.plugins.son.SON;
import org.workcraft.plugins.son.algorithm.Path;
import org.workcraft.plugins.son.algorithm.SimulationAlg;
import org.workcraft.plugins.son.elements.TransitionNode;
import org.workcraft.plugins.son.util.Step;
import org.workcraft.utils.GuiUtils;

import javax.swing.*;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

@SuppressWarnings("rawtypes")
public class ParallelSimDialog extends JDialog {
    private static final long serialVersionUID = 1L;

    private static final Color selectedColor = new Color(255, 228, 181);

    private final SON net;
    private final boolean isRev;
    private final Step possibleFire;
    private final Step minFire;
    private final TransitionNode clickedEvent;
    private JPanel eventPanel;
    private JPanel buttonsPanel;
    private JPanel eventInfoPanel;
    private final Collection<Path> sync;
    private final Dimension buttonSize = new Dimension(80, 25);
    private final HashSet<TransitionNode> selectedEvents = new HashSet<>();
    private int modalResult = 0;

    class EventItem {
        private final String label;
        private boolean selected = false;
        private final TransitionNode event;

        EventItem(String label, TransitionNode event) {
            this.label = label;
            this.event = event;
        }

        public boolean isSelected() {
            return selected;
        }

        public void setSelected(boolean selected) {
            this.selected = selected;
        }

        @Override
        public String toString() {
            return label;
        }

        public TransitionNode getEvent() {
            return event;
        }

        public void setForegroudColor(Color color) {
            event.setForegroundColor(color);
        }

        public void setFillColor(Color color) {
            event.setFillColor(color);
        }
    }

    class CheckListRenderer extends JCheckBox implements ListCellRenderer {

        private static final long serialVersionUID = 1L;

        @Override
        public Component getListCellRendererComponent(
                JList list, Object value, int index,
                boolean isSelected, boolean hasFocus) {

            setEnabled(list.isEnabled());
            setSelected(((EventItem) value).isSelected());
            setFont(list.getFont());

            setBackground(list.getBackground());
            setForeground(list.getForeground());
            setText(value.toString());
            return this;
        }
    }

    @SuppressWarnings("unchecked")
    private void createEventItemsPanel() {

        eventPanel = new JPanel();

        DefaultListModel listModel = new DefaultListModel();

        for (TransitionNode event : this.possibleFire) {
            EventItem item = new EventItem(net.getNodeReference(event) + "  " + event.getLabel(), event);
            listModel.addElement(item);
        }

        JList eventList = new JList(listModel);
        eventList.setCellRenderer(new CheckListRenderer());
        eventList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        eventList.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent event) {
                JList list = (JList) event.getSource();

                int index = list.locationToIndex(event.getPoint());
                try {
                    EventItem item = (EventItem) list.getModel().getElementAt(index);
                    item.setSelected(!item.isSelected());

                    ArrayList<EventItem> itemList = new ArrayList<>();
                    for (int i = 0; i < list.getModel().getSize(); i++) {
                        itemList.add((EventItem) list.getModel().getElementAt(i));
                    }

                    if (item instanceof EventItem) {
                        SimulationAlg simuAlg = new SimulationAlg(net);
                        if (item.isSelected()) {
                            selectedEvents.add(item.getEvent());

                            Step minFire = simuAlg.getMinFire(item.getEvent(), sync, possibleFire, isRev);

                            for (TransitionNode e : minFire) {
                                for (EventItem eventItem : itemList) {
                                    if (e == eventItem.getEvent()) {
                                        selectedEvents.add(e);
                                        eventItem.setSelected(true);
                                        eventItem.setFillColor(selectedColor);
                                    }
                                }
                            }
                            item.setFillColor(selectedColor);
                        }

                        if (!item.isSelected()) {
                            selectedEvents.remove(item.getEvent());

                            Step minFire = simuAlg.getMinFire(item.getEvent(), sync, possibleFire, !isRev);

                            //unselected related synchronous events.
                            for (TransitionNode e : minFire) {
                                for (EventItem eventItem : itemList) {
                                    if (e == eventItem.getEvent()) {
                                        selectedEvents.remove(e);
                                        eventItem.setSelected(false);
                                        eventItem.setFillColor(Color.WHITE);
                                    }
                                }
                            }

                            item.setFillColor(Color.WHITE);
                        }

                        for (int i = 0; i < list.getModel().getSize(); i++) {
                            list.repaint(list.getCellBounds(i, i));
                        }
                    }
                } catch (ArrayIndexOutOfBoundsException e) { }
            }
        });

        eventList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        JScrollPane listScroller = new JScrollPane(eventList);
        listScroller.setPreferredSize(new Dimension(250, 150));
        listScroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        listScroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

        listScroller.getVerticalScrollBar().setPreferredSize(new Dimension(12, 0));
        listScroller.getHorizontalScrollBar().setPreferredSize(new Dimension(12, 0));

        eventPanel.setPreferredSize(new Dimension(250, 150));
        eventPanel.setLayout(new BorderLayout());
        eventPanel.add(listScroller, BorderLayout.CENTER);
        eventPanel.setBorder(GuiUtils.getTitledBorder("Possible parallel execution:"));
    }

    private void createButtonsPanel() {
        buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));

        JButton runButton = new JButton("Run");
        runButton.setPreferredSize(buttonSize);
        runButton.addActionListener(event -> {
            modalResult = 1;
            net.refreshAllColor();
            setVisible(false);
        });

        JButton cancelButton = new JButton("Cancel");
        cancelButton.setPreferredSize(buttonSize);
        cancelButton.addActionListener(event -> {
            modalResult = 2;
            net.refreshAllColor();
            setVisible(false);
        });

        buttonsPanel.add(cancelButton);
        buttonsPanel.add(runButton);
    }

    private void createEventInfoPanel() {
        eventInfoPanel = new JPanel();

        String[] colNames = {"Name", "Label"};

        JTable table = new JTable(createData(), colNames);
        table.setEnabled(false);
        TableColumn firsetColumn = table.getColumnModel().getColumn(0);
        firsetColumn.setPreferredWidth(12);

        eventInfoPanel.setLayout(new BoxLayout(eventInfoPanel, BoxLayout.Y_AXIS));
        eventInfoPanel.setBorder(GuiUtils.getTitledBorder("Parallel execution:"));
        eventInfoPanel.add(table);
    }

    private String[][] createData() {
        String[][] dataVal = new String[this.minFire.size() + 1][2];

        dataVal[0][0] = net.getNodeReference(clickedEvent) + "(clicked)";
        dataVal[0][1] = this.clickedEvent.getLabel();

        if (!minFire.isEmpty()) {
            for (int i = 1; i < minFire.size() + 1; i++) {
                dataVal[i][0] = net.getNodeReference(minFire.get(i - 1));
            }
            for (int i = 1; i < minFire.size() + 1; i++) {
                dataVal[i][1] = minFire.get(i - 1).getLabel();
            }
        }

        return dataVal;

    }

    public ParallelSimDialog(Window owner, SON net,
            Step possibleFire, Step minFire,
            TransitionNode event, boolean isRev,
            Collection<Path> sync) {
        super(owner, "Parallel Execution Setting", ModalityType.TOOLKIT_MODAL);

        this.net = net;
        this.isRev = isRev;
        this.possibleFire = possibleFire;
        this.minFire = minFire;
        this.clickedEvent = event;
        this.sync = sync;

        setColor(minFire, event);

        //this.setSize(new Dimension(280, 260));
        createButtonsPanel();
        createEventItemsPanel();
        createEventInfoPanel();

        JPanel interfacePanel = new JPanel(new BorderLayout(10, 10));
        interfacePanel.add(eventInfoPanel, BorderLayout.NORTH);
        interfacePanel.add(eventPanel, BorderLayout.CENTER);
        interfacePanel.add(buttonsPanel, BorderLayout.SOUTH);

        add(interfacePanel);
        pack();
        setLocationRelativeTo(owner);

        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                getSONModel().refreshAllColor();
            }
        });

        addWindowFocusListener(new WindowFocusListener() {
            @Override
            public void windowGainedFocus(WindowEvent e) {
            }

            @Override
            public void windowLostFocus(WindowEvent e) {
                if (modalResult == 0) {
                    setVisible(true);
                }
            }
        });

    }

    private void setColor(List<TransitionNode> preEvents, TransitionNode event) {
        event.setFillColor(selectedColor);
        for (TransitionNode e : preEvents) {
            e.setFillColor(selectedColor);
        }
    }

    public SON getSONModel() {
        return this.net;
    }

    public HashSet<TransitionNode> getSelectedEvent() {
        return this.selectedEvents;
    }

    public int getModalResult() {
        return modalResult;
    }

}