ArduinoPanelFilter.java

/*******************************************************************************
 * jArduino: Arduino C++ Code Generation From Java
 * Copyright 2020 Tony Washer
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package net.sourceforge.jarduino.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.Border;

import net.sourceforge.jarduino.message.ArduinoMsgFilter;
import net.sourceforge.jarduino.message.ArduinoNamedObject;
import net.sourceforge.jarduino.message.ArduinoNode;
import net.sourceforge.jarduino.message.ArduinoSystem;

/**
 * The filter panel.
 */
public class ArduinoPanelFilter {
    /**
     * The parent panel.
     */
    private final ArduinoPanelSource theParent;

    /**
     * The panel.
     */
    private final JPanel thePanel;

    /**
     * The basis button.
     */
    private final ArduinoScrollButton<ArduinoNamedObject> theBasis;

    /**
     * The reset button.
     */
    private final JButton theReset;

    /**
     * The public button.
     */
    private final JButton thePublic;

    /**
     * The Filter Table.
     */
    private final ArduinoTableFilter theTable;

    /**
     * Constructor.
     * @param pParent the parent panel
     * @param pFrame the frame
     */
    ArduinoPanelFilter(final ArduinoPanelSource pParent,
                       final JFrame pFrame) {
        /* Store parameters */
        theParent = pParent;

        /* Create the table */
        theTable = new ArduinoTableFilter(this);

        /* Create the source button */
        final JButton mySource = new JButton();
        mySource.setText("Message Filter");
        mySource.addActionListener(e -> theParent.showSource());

        /* Create the basis button */
        theBasis = new ArduinoScrollButton<>(pFrame);
        theBasis.setFormatter(ArduinoPanelFilter::getNodeName);
        theBasis.onSelect(this::setNode);

        /* Create the Reset button */
        theReset = new JButton();
        theReset.setText("Reset");
        theReset.addActionListener(e -> setNode(theBasis.getSelectedItem()));

        /* Create the public button */
        thePublic = new JButton();
        thePublic.setText("Private");
        thePublic.addActionListener(e -> {
            final ArduinoMsgFilter myFilter = getFilter();
            myFilter.togglePublicFields();
            thePublic.setText(myFilter.publicFields() ? "Public" : "Private");
            theParent.updateFilter();
        });

        /* Create the basis panel */
        final JPanel myBasisPanel = new JPanel();
        myBasisPanel.setLayout(new BoxLayout(myBasisPanel, BoxLayout.X_AXIS));
        myBasisPanel.add(Box.createHorizontalStrut(ArduinoPanelMain.STRUTSIZE));
        myBasisPanel.add(Box.createHorizontalStrut(ArduinoPanelMain.STRUTSIZE));
        myBasisPanel.add(theBasis.getComponent());
        myBasisPanel.add(Box.createHorizontalGlue());
        myBasisPanel.add(theReset);
        myBasisPanel.add(Box.createHorizontalGlue());
        Border myBorder = BorderFactory.createTitledBorder("Filter Basis");
        myBasisPanel.setBorder(myBorder);

        /* Create the Field panel */
        final JPanel myFieldPanel = new JPanel();
        myFieldPanel.setLayout(new BoxLayout(myFieldPanel, BoxLayout.X_AXIS));
        myFieldPanel.add(Box.createHorizontalStrut(ArduinoPanelMain.STRUTSIZE));
        myFieldPanel.add(thePublic);
        myFieldPanel.add(Box.createHorizontalStrut(ArduinoPanelMain.STRUTSIZE));
        myBorder = BorderFactory.createTitledBorder("Fields");
        myFieldPanel.setBorder(myBorder);

        /* Create the Source panel */
        final JPanel mySourcePanel = new JPanel();
        mySourcePanel.setLayout(new BoxLayout(mySourcePanel, BoxLayout.X_AXIS));
        mySourcePanel.add(Box.createHorizontalStrut(ArduinoPanelMain.STRUTSIZE));
        mySourcePanel.add(mySource);
        mySourcePanel.add(Box.createHorizontalStrut(ArduinoPanelMain.STRUTSIZE));
        myBorder = BorderFactory.createTitledBorder("View");
        mySourcePanel.setBorder(myBorder);

        /* Create the control panel */
        final JPanel myControl = new JPanel();
        myControl.setLayout(new BoxLayout(myControl, BoxLayout.X_AXIS));
        myControl.add(myBasisPanel);
        myControl.add(myFieldPanel);
        myControl.add(mySourcePanel);

        /* Create the message panel */
        final JPanel myFilterPanel = new JPanel(new BorderLayout());
        myFilterPanel.add(new JScrollPane(theTable.getComponent()), BorderLayout.CENTER);
        myBorder = BorderFactory.createTitledBorder("Message Filter");
        myFilterPanel.setBorder(myBorder);

        /* Create the panel */
        thePanel = new JPanel(new BorderLayout());
        thePanel.add(myControl, BorderLayout.PAGE_START);
        thePanel.add(myFilterPanel, BorderLayout.CENTER);

        /* Set Dimensions */
        thePanel.setPreferredSize(new Dimension(ArduinoPanelMain.WIDTH, ArduinoPanelMain.HEIGHT));
    }

    /**
     * Obtain the panel.
     * @return the panel
     */
    JComponent getComponent() {
        return thePanel;
    }

    /**
     * Obtain the filter.
     * @return the filter
     */
    ArduinoMsgFilter getFilter() {
        return theTable.getFilter();
    }

    /**
     * Obtain the node name.
     * @param pNode the node
     * @return the display name
     */
    private static String getNodeName(final ArduinoNamedObject pNode) {
        return pNode instanceof ArduinoSystem ? "All" : pNode.getName();
    }

    /**
     * Set System.
     * @param pSystem the system.
     */
    void setSystem(final ArduinoSystem pSystem) {
        /* Declare system to table */
        theTable.configureForSystem(pSystem);

        /* Reset the basis button */
        theBasis.removeAll();
        theBasis.add(pSystem);

        /* Add all the nodes to the button */
        for (ArduinoNode myNode : pSystem.getNodes()) {
            /* Add to the list (unless it is the nullNode) */
            if (!myNode.getName().equals(ArduinoNode.NULL_NODE)) {
                theBasis.add(myNode);
            }
        }
    }

    /**
     * Set Node.
     * @param pNode the node.
     */
    private void setNode(final ArduinoNamedObject pNode) {
        /* Declare system to table */
        theTable.configureForNode(pNode);
    }

    /**
     * Update the filter.
     */
    void updateFilter() {
        /* Update source details */
        theParent.updateFilter();

        /* Set reset visibility */
        theReset.setVisible(theTable.isBespoke());
    }
}