SiLeBAT/FSK-Lab

View on GitHub
de.bund.bfr.knime.pmm.nodes/src/de/bund/bfr/knime/pmm/modelanddatajoiner/SecondaryJoiner.java

Summary

Maintainability
F
1 wk
Test Coverage
/*******************************************************************************
 * Copyright (c) 2015 Federal Institute for Risk Assessment (BfR), Germany
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     Department Biological Safety - BfR
 *******************************************************************************/
package de.bund.bfr.knime.pmm.modelanddatajoiner;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import org.knime.core.node.BufferedDataContainer;
import org.knime.core.node.BufferedDataTable;
import org.knime.core.node.CanceledExecutionException;
import org.knime.core.node.ExecutionContext;

import de.bund.bfr.knime.pmm.common.CatalogModelXml;
import de.bund.bfr.knime.pmm.common.CellIO;
import de.bund.bfr.knime.pmm.common.DepXml;
import de.bund.bfr.knime.pmm.common.EstModelXml;
import de.bund.bfr.knime.pmm.common.IndepXml;
import de.bund.bfr.knime.pmm.common.MiscXml;
import de.bund.bfr.knime.pmm.common.ParamXml;
import de.bund.bfr.knime.pmm.common.PmmXmlDoc;
import de.bund.bfr.knime.pmm.common.PmmXmlElementConvertable;
import de.bund.bfr.knime.pmm.common.XmlConverter;
import de.bund.bfr.knime.pmm.common.generictablemodel.KnimeRelationReader;
import de.bund.bfr.knime.pmm.common.generictablemodel.KnimeTuple;
import de.bund.bfr.knime.pmm.common.math.MathUtilities;
import de.bund.bfr.knime.pmm.common.pmmtablemodel.Model1Schema;
import de.bund.bfr.knime.pmm.common.pmmtablemodel.Model2Schema;
import de.bund.bfr.knime.pmm.common.pmmtablemodel.PmmUtilities;
import de.bund.bfr.knime.pmm.common.pmmtablemodel.SchemaFactory;
import de.bund.bfr.knime.pmm.common.pmmtablemodel.TimeSeriesSchema;
import de.bund.bfr.knime.pmm.common.units.Categories;
import de.bund.bfr.knime.pmm.common.units.Category;
import de.bund.bfr.knime.pmm.common.units.ConvertException;

public class SecondaryJoiner implements Joiner, ActionListener {

    private BufferedDataTable modelTable;
    private BufferedDataTable dataTable;

    private Map<String, List<Map<String, String>>> assignmentsMap;

    private List<String> models;
    private Map<String, String> modelNames;
    private Map<String, String> modelFormulas;
    private Map<String, String> dependentVariables;
    private Map<String, Map<String, String>> independentVariableCategories;
    private Map<String, Map<String, String>> independentVariableUnits;
    private Map<Integer, List<String>> dependentParameters;
    private Map<Integer, String> primaryModelNames;
    private Map<String, String> independentParameterCategories;

    private Map<String, JPanel> boxPanels;
    private Map<String, JPanel> buttonPanels;
    private Map<String, List<Map<String, JComboBox<String>>>> comboBoxes;
    private Map<String, List<JButton>> addButtons;
    private Map<String, List<JButton>> removeButtons;

    private boolean isValid;

    public SecondaryJoiner(BufferedDataTable modelTable,
            BufferedDataTable dataTable) {
        this.modelTable = modelTable;
        this.dataTable = dataTable;

        readModelTable();
        readDataTable();
    }

    @Override
    public JComponent createPanel(String assignments) {
        JPanel panel = new JPanel();
        JPanel topPanel = new JPanel();

        boxPanels = new LinkedHashMap<>();
        buttonPanels = new LinkedHashMap<>();
        comboBoxes = new LinkedHashMap<>();
        addButtons = new LinkedHashMap<>();
        removeButtons = new LinkedHashMap<>();
        panel.setLayout(new BorderLayout());
        topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
        assignmentsMap = XmlConverter.xmlToObject(assignments,
                new LinkedHashMap<String, List<Map<String, String>>>());

        for (String modelID : models) {
            List<Map<String, String>> modelAssignments = new ArrayList<>();
            List<Map<String, JComboBox<String>>> modelBoxes = new ArrayList<>();
            List<JButton> modelAddButtons = new ArrayList<>();
            List<JButton> modelRemoveButtons = new ArrayList<>();

            if (assignmentsMap.containsKey(modelID)) {
                modelAssignments = assignmentsMap.get(modelID);
            }

            JPanel modelPanel = new JPanel();
            JPanel leftPanel = new JPanel();
            JPanel rightPanel = new JPanel();

            leftPanel.setLayout(new GridLayout(0, 1));
            rightPanel.setLayout(new GridLayout(0, 1));

            for (Map<String, String> assignment : modelAssignments) {
                Map<String, JComboBox<String>> boxes = new LinkedHashMap<>();
                JPanel assignmentPanel = new JPanel();

                assignmentPanel.setLayout(new FlowLayout(FlowLayout.LEFT));

                JComboBox<String> depBox = new JComboBox<>(getDepParams()
                        .toArray(new String[0]));

                depBox.setSelectedItem(assignment.get(dependentVariables
                        .get(modelID)));
                depBox.addActionListener(this);
                boxes.put(dependentVariables.get(modelID), depBox);
                assignmentPanel.add(new JLabel(dependentVariables.get(modelID)
                        + ":"));
                assignmentPanel.add(depBox);

                for (String indepVar : independentVariableCategories.get(
                        modelID).keySet()) {
                    JComboBox<String> indepBox = new JComboBox<>(
                            getIndepParamsFromCategory(
                                    independentVariableCategories.get(modelID)
                                            .get(indepVar)).toArray(
                                    new String[0]));

                    indepBox.setSelectedItem(assignment.get(indepVar));
                    indepBox.addActionListener(this);
                    boxes.put(indepVar, indepBox);
                    assignmentPanel.add(new JLabel(indepVar + ":"));
                    assignmentPanel.add(indepBox);
                }

                modelBoxes.add(boxes);
                leftPanel.add(assignmentPanel);

                JPanel buttonPanel = new JPanel();
                JButton addButton = new JButton("+");
                JButton removeButton = new JButton("-");

                addButton.addActionListener(this);
                removeButton.addActionListener(this);
                modelAddButtons.add(addButton);
                modelRemoveButtons.add(removeButton);
                buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
                buttonPanel.add(removeButton);
                buttonPanel.add(addButton);
                rightPanel.add(buttonPanel);
            }

            JPanel buttonPanel = new JPanel();
            JButton addButton = new JButton("+");

            addButton.addActionListener(this);
            modelAddButtons.add(addButton);
            buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
            buttonPanel.add(addButton);
            leftPanel.add(new JPanel());
            rightPanel.add(buttonPanel);

            boxPanels.put(modelID, leftPanel);
            buttonPanels.put(modelID, rightPanel);
            comboBoxes.put(modelID, modelBoxes);
            addButtons.put(modelID, modelAddButtons);
            removeButtons.put(modelID, modelRemoveButtons);
            modelPanel.setBorder(BorderFactory.createTitledBorder(modelNames
                    .get(modelID)));
            modelPanel.setLayout(new BorderLayout());
            modelPanel.setToolTipText(modelFormulas.get(modelID));
            modelPanel.add(leftPanel, BorderLayout.CENTER);
            modelPanel.add(rightPanel, BorderLayout.EAST);
            topPanel.add(modelPanel);
        }

        panel.add(topPanel, BorderLayout.NORTH);
        checkIfInputIsValid();

        return new JScrollPane(panel);
    }

    @Override
    public String getAssignments() {
        Map<String, List<Map<String, String>>> assignmentsMap = new LinkedHashMap<>();

        for (String model : comboBoxes.keySet()) {
            List<Map<String, String>> modelAssignments = new ArrayList<>();

            for (Map<String, JComboBox<String>> modelBoxes : comboBoxes
                    .get(model)) {
                Map<String, String> assignment = new LinkedHashMap<>();

                for (String var : modelBoxes.keySet()) {
                    JComboBox<String> box = modelBoxes.get(var);

                    assignment.put(var, (String) box.getSelectedItem());
                }

                modelAssignments.add(assignment);
            }

            assignmentsMap.put(model, modelAssignments);
        }

        return XmlConverter.objectToXml(assignmentsMap);
    }

    @Override
    public BufferedDataTable getOutputTable(String assignments,
            ExecutionContext exec) throws CanceledExecutionException,
            ConvertException {
        BufferedDataContainer buf = exec.createDataContainer(SchemaFactory
                .createM12DataSchema().createSpec());

        assignmentsMap = XmlConverter.xmlToObject(assignments,
                new LinkedHashMap<String, List<Map<String, String>>>());

        Map<Integer, Integer> globalIds = new LinkedHashMap<>();

        for (String model : assignmentsMap.keySet()) {
            for (Map<String, String> replace : assignmentsMap.get(model)) {
                KnimeRelationReader modelReader = new KnimeRelationReader(
                        SchemaFactory.createM2Schema(), modelTable);
                Set<Integer> usedEstIDs = new LinkedHashSet<>();

                while (modelReader.hasMoreElements()) {
                    KnimeTuple modelTuple = modelReader.nextElement();
                    PmmXmlDoc modelXmlSec = modelTuple
                            .getPmmXml(Model2Schema.ATT_MODELCATALOG);
                    String modelIDSec = ((CatalogModelXml) modelXmlSec.get(0))
                            .id + "";
                    Integer estIDSec = ((EstModelXml) modelTuple.getPmmXml(
                            Model2Schema.ATT_ESTMODEL).get(0)).id;

                    if (!model.equals(modelIDSec) || !usedEstIDs.add(estIDSec)) {
                        continue;
                    }

                    String formulaSec = ((CatalogModelXml) modelXmlSec.get(0))
                            .formula;
                    PmmXmlDoc depVarSec = modelTuple
                            .getPmmXml(Model2Schema.ATT_DEPENDENT);
                    String depVarSecName = ((DepXml) depVarSec.get(0))
                            .name;
                    PmmXmlDoc indepVarsSec = modelTuple
                            .getPmmXml(Model2Schema.ATT_INDEPENDENT);
                    PmmXmlDoc newIndepVarsSec = new PmmXmlDoc();
                    List<String> oldIndepVars = new ArrayList<>();

                    if (!replace.containsKey(depVarSecName)) {
                        continue;
                    }

                    String s = replace.get(depVarSecName);
                    String newDepVarSecName = s.substring(0, s.indexOf(" "));
                    String modelName = s.substring(s.indexOf("(") + 1,
                            s.length() - 1);
                    int modelID = -1;

                    for (int id : primaryModelNames.keySet()) {
                        if (primaryModelNames.get(id).equals(modelName)) {
                            modelID = id;
                            break;
                        }
                    }

                    formulaSec = MathUtilities.replaceVariable(formulaSec,
                            depVarSecName, newDepVarSecName);
                    ((DepXml) depVarSec.get(0)).name = newDepVarSecName;

                    boolean error = false;

                    for (PmmXmlElementConvertable el : indepVarsSec
                            .getElementSet()) {
                        IndepXml iv = (IndepXml) el;

                        if (!replace.containsKey(iv.name)) {
                            error = true;
                            break;
                        }

                        oldIndepVars.add(iv.name);
                        formulaSec = MathUtilities.replaceVariable(formulaSec,
                                iv.name, replace.get(iv.name));
                        iv.name = replace.get(iv.name);
                        newIndepVarsSec.add(iv);
                    }

                    if (error) {
                        continue;
                    }

                    ((CatalogModelXml) modelXmlSec.get(0)).formula = formulaSec;

                    List<KnimeTuple> dataTuples = PmmUtilities.getTuples(
                            dataTable, SchemaFactory.createM1DataSchema());
                    Map<Integer, List<KnimeTuple>> tuplesByPrimID = new LinkedHashMap<>();
                    Map<Integer, Map<String, String>> miscUnits = new LinkedHashMap<>();

                    for (KnimeTuple dataTuple : dataTuples) {
                        CatalogModelXml modelXml = (CatalogModelXml) dataTuple
                                .getPmmXml(Model1Schema.ATT_MODELCATALOG)
                                .get(0);

                        if (!tuplesByPrimID.containsKey(modelXml.id)) {
                            tuplesByPrimID.put(modelXml.id,
                                    new ArrayList<KnimeTuple>());
                        }

                        tuplesByPrimID.get(modelXml.id).add(dataTuple);
                    }

                    for (int primID : tuplesByPrimID.keySet()) {
                        miscUnits.put(primID, PmmUtilities
                                .getMiscUnits(tuplesByPrimID.get(primID)));
                    }

                    for (KnimeTuple dataTuple : dataTuples) {
                        int id = ((CatalogModelXml) dataTuple.getPmmXml(
                                Model1Schema.ATT_MODELCATALOG).get(0)).id;

                        if (id != modelID) {
                            continue;
                        }

                        PmmXmlDoc params = dataTuple
                                .getPmmXml(Model1Schema.ATT_PARAMETER);
                        PmmXmlDoc miscs = dataTuple
                                .getPmmXml(TimeSeriesSchema.ATT_MISC);
                        Map<String, String> paramsConvertTo = new LinkedHashMap<>();

                        if (!CellIO.getNameList(params).contains(
                                newDepVarSecName)) {
                            continue;
                        }

                        for (String var : oldIndepVars) {
                            String unit = independentVariableUnits.get(model)
                                    .get(var);
                            String newVar = replace.get(var);

                            if (unit != null) {
                                paramsConvertTo.put(newVar, unit);
                            } else {
                                paramsConvertTo.put(newVar, miscUnits.get(id)
                                        .get(newVar));
                            }
                        }

                        for (PmmXmlElementConvertable el : miscs
                                .getElementSet()) {
                            MiscXml element = (MiscXml) el;

                            if (paramsConvertTo.containsKey(element.name)) {
                                Category cat = Categories
                                        .getCategory(Categories
                                                .getCategoryByUnit(
                                                        element.unit)
                                                .getName());
                                String unit = paramsConvertTo.get(element
                                        .name);

                                element.value = cat.convert(
                                        element.value, element.unit,
                                        unit);
                                element.unit = unit;
                            }
                        }

                        dataTuple.setValue(TimeSeriesSchema.ATT_MISC, miscs);

                        KnimeTuple tuple = new KnimeTuple(
                                SchemaFactory.createM12DataSchema(),
                                modelTuple, dataTuple);

                        tuple.setValue(Model2Schema.ATT_MODELCATALOG,
                                modelXmlSec);
                        tuple.setValue(Model2Schema.ATT_DEPENDENT, depVarSec);
                        tuple.setValue(Model2Schema.ATT_INDEPENDENT,
                                newIndepVarsSec);
                        tuple.setValue(Model2Schema.ATT_DATABASEWRITABLE,
                                Model2Schema.NOTWRITABLE);

                        if (!globalIds.containsKey(id)) {
                            globalIds.put(id,
                                    MathUtilities.getRandomNegativeInt());
                        }

                        tuple.setValue(Model2Schema.ATT_GLOBAL_MODEL_ID,
                                globalIds.get(id));

                        buf.addRowToTable(tuple);
                    }
                }
            }
        }

        buf.close();

        return buf.getTable();
    }

    @Override
    public boolean isValid() {
        return isValid;
    }

    private void readModelTable() {
        models = new ArrayList<>();
        modelNames = new LinkedHashMap<>();
        modelFormulas = new LinkedHashMap<>();
        dependentVariables = new LinkedHashMap<>();
        independentVariableCategories = new LinkedHashMap<>();
        independentVariableUnits = new LinkedHashMap<>();

        KnimeRelationReader reader = new KnimeRelationReader(
                SchemaFactory.createM2Schema(), modelTable);

        while (reader.hasMoreElements()) {
            KnimeTuple row = reader.nextElement();
            PmmXmlDoc modelXml = row.getPmmXml(Model2Schema.ATT_MODELCATALOG);
            DepXml depXml = (DepXml) row.getPmmXml(Model2Schema.ATT_DEPENDENT)
                    .get(0);
            String modelID = ((CatalogModelXml) modelXml.get(0)).id + "";

            if (dependentVariables.containsKey(modelID)) {
                continue;
            }

            models.add(modelID);
            modelNames.put(modelID,
                    ((CatalogModelXml) modelXml.get(0)).name);
            modelFormulas.put(modelID,
                    ((CatalogModelXml) modelXml.get(0)).formula);
            dependentVariables.put(modelID, depXml.name);

            Map<String, String> indepCategories = new LinkedHashMap<>();
            Map<String, String> indepUnits = new LinkedHashMap<>();

            for (PmmXmlElementConvertable el : row.getPmmXml(
                    Model2Schema.ATT_INDEPENDENT).getElementSet()) {
                IndepXml element = (IndepXml) el;

                indepCategories.put(element.name, element.category);
                indepUnits.put(element.name, element.unit);
            }

            independentVariableCategories.put(modelID, indepCategories);
            independentVariableUnits.put(modelID, indepUnits);
        }
    }

    private void readDataTable() {
        dependentParameters = new LinkedHashMap<>();
        primaryModelNames = new LinkedHashMap<>();
        independentParameterCategories = new LinkedHashMap<>();

        KnimeRelationReader reader = new KnimeRelationReader(
                SchemaFactory.createM1DataSchema(), dataTable);

        while (reader.hasMoreElements()) {
            KnimeTuple row = reader.nextElement();
            CatalogModelXml modelXml = (CatalogModelXml) row.getPmmXml(
                    Model1Schema.ATT_MODELCATALOG).get(0);

            if (!primaryModelNames.containsKey(modelXml.id)) {
                List<String> params = new ArrayList<>();

                for (PmmXmlElementConvertable el : row.getPmmXml(
                        Model1Schema.ATT_PARAMETER).getElementSet()) {
                    ParamXml element = (ParamXml) el;

                    params.add(element.name);
                }

                primaryModelNames.put(modelXml.id, modelXml.name);
                dependentParameters.put(modelXml.id, params);
            }

            for (PmmXmlElementConvertable el : row.getPmmXml(
                    TimeSeriesSchema.ATT_MISC).getElementSet()) {
                MiscXml element = (MiscXml) el;

                independentParameterCategories.put(element.name,
                        Categories.getCategoryByUnit(element.unit)
                                .getName());
            }
        }
    }

    private List<String> getDepParams() {
        List<String> params = new ArrayList<>();

        for (int modelID : dependentParameters.keySet()) {
            for (String param : dependentParameters.get(modelID)) {
                params.add(param + " (" + primaryModelNames.get(modelID) + ")");
            }
        }

        return params;
    }

    private List<String> getIndepParamsFromCategory(String category) {
        List<String> params = new ArrayList<>();

        for (String param : independentParameterCategories.keySet()) {
            if (category == null
                    || independentParameterCategories.get(param).equals(
                            category)) {
                params.add(param);
            }
        }

        return params;
    }

    private void addOrRemoveButtonPressed(JButton button) {
        for (String model : addButtons.keySet()) {
            List<JButton> modelAddButtons = addButtons.get(model);
            List<JButton> modelRemoveButtons = removeButtons.get(model);
            List<Map<String, JComboBox<String>>> modelBoxes = comboBoxes
                    .get(model);
            JPanel leftPanel = boxPanels.get(model);
            JPanel rightPanel = buttonPanels.get(model);

            if (modelAddButtons.contains(button)) {
                int index = modelAddButtons.indexOf(button);
                Map<String, JComboBox<String>> boxes = new LinkedHashMap<>();
                JPanel assignmentPanel = new JPanel();

                assignmentPanel.setLayout(new FlowLayout(FlowLayout.LEFT));

                JComboBox<String> depBox = new JComboBox<>(getDepParams()
                        .toArray(new String[0]));

                depBox.setSelectedItem(null);
                depBox.addActionListener(this);
                boxes.put(dependentVariables.get(model), depBox);
                assignmentPanel.add(new JLabel(dependentVariables.get(model)
                        + ":"));
                assignmentPanel.add(depBox);

                for (String indepVar : independentVariableCategories.get(model)
                        .keySet()) {
                    JComboBox<String> indepBox = new JComboBox<>(
                            getIndepParamsFromCategory(
                                    independentVariableCategories.get(model)
                                            .get(indepVar)).toArray(
                                    new String[0]));

                    indepBox.setSelectedItem(null);
                    indepBox.addActionListener(this);
                    boxes.put(indepVar, indepBox);
                    assignmentPanel.add(new JLabel(indepVar + ":"));
                    assignmentPanel.add(indepBox);
                }

                modelBoxes.add(index, boxes);
                leftPanel.add(assignmentPanel, index);

                JPanel buttonPanel = new JPanel();
                JButton addButton = new JButton("+");
                JButton removeButton = new JButton("-");

                addButton.addActionListener(this);
                removeButton.addActionListener(this);
                modelAddButtons.add(index, addButton);
                modelRemoveButtons.add(index, removeButton);
                buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
                buttonPanel.add(removeButton);
                buttonPanel.add(addButton);
                rightPanel.add(buttonPanel, index);
                leftPanel.revalidate();
                rightPanel.revalidate();

                break;
            } else if (modelRemoveButtons.contains(button)) {
                int index = modelRemoveButtons.indexOf(button);

                modelAddButtons.remove(index);
                modelRemoveButtons.remove(index);
                modelBoxes.remove(index);
                leftPanel.remove(index);
                rightPanel.remove(index);
                leftPanel.revalidate();
                rightPanel.revalidate();

                break;
            }
        }
    }

    private void checkIfInputIsValid() {
        Map<String, JComboBox<String>> depVarBoxes = new LinkedHashMap<>();
        isValid = true;

        for (String model : comboBoxes.keySet()) {
            String depVar = dependentVariables.get(model);

            for (Map<String, JComboBox<String>> boxes : comboBoxes.get(model)) {
                JComboBox<String> box = boxes.get(depVar);

                if (box.getSelectedItem() == null) {
                    isValid = false;
                } else {
                    JComboBox<String> sameValueBox = depVarBoxes.get(box
                            .getSelectedItem());

                    if (sameValueBox != null) {
                        box.setForeground(Color.RED);
                        sameValueBox.setForeground(Color.RED);
                        isValid = false;
                    } else {
                        box.setForeground(Color.BLACK);
                        depVarBoxes.put((String) box.getSelectedItem(), box);
                    }
                }
            }
        }

        for (String model : comboBoxes.keySet()) {
            String depVar = dependentVariables.get(model);

            for (Map<String, JComboBox<String>> boxes : comboBoxes.get(model)) {
                Map<String, JComboBox<String>> indepVarBoxes = new LinkedHashMap<>();

                for (String var : boxes.keySet()) {
                    if (var.equals(depVar)) {
                        continue;
                    }

                    JComboBox<String> box = boxes.get(var);

                    if (box.getSelectedItem() == null) {
                        isValid = false;
                    } else {
                        JComboBox<String> sameValueBox = indepVarBoxes.get(box
                                .getSelectedItem());

                        if (sameValueBox != null) {
                            box.setForeground(Color.RED);
                            sameValueBox.setForeground(Color.RED);
                            isValid = false;
                        } else {
                            box.setForeground(Color.BLACK);
                            indepVarBoxes.put((String) box.getSelectedItem(),
                                    box);
                        }
                    }
                }
            }
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() instanceof JComboBox) {
            checkIfInputIsValid();
        } else if (e.getSource() instanceof JButton) {
            addOrRemoveButtonPressed((JButton) e.getSource());
            checkIfInputIsValid();
        }
    }

}