uk.nhs.cfh.dsp.srth.desktop.modules.querycreationtreepanel.QueryAuthoringTreePanel.java Source code

Java tutorial

Introduction

Here is the source code for uk.nhs.cfh.dsp.srth.desktop.modules.querycreationtreepanel.QueryAuthoringTreePanel.java

Source

/**
 * Crown Copyright (C) 2008 - 2011
 *
 * 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 uk.nhs.cfh.dsp.srth.desktop.modules.querycreationtreepanel;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdesktop.swingx.JXTree;
import org.jdesktop.swingx.decorator.HighlighterFactory;
import uk.nhs.cfh.dsp.snomed.converters.human.readable.HumanReadableRender;
import uk.nhs.cfh.dsp.snomed.dao.TerminologyConceptDAO;
import uk.nhs.cfh.dsp.snomed.normaliser.NormalFormGenerator;
import uk.nhs.cfh.dsp.srth.desktop.appservice.ApplicationService;
import uk.nhs.cfh.dsp.srth.desktop.modularframework.PropertyChangeTrackerService;
import uk.nhs.cfh.dsp.srth.desktop.modularframework.SelectionService;
import uk.nhs.cfh.dsp.srth.desktop.modularframework.SelectionServiceListener;
import uk.nhs.cfh.dsp.srth.desktop.modules.querycreationtreepanel.model.ReportingQueryStatementTreeModel;
import uk.nhs.cfh.dsp.srth.desktop.modules.querycreationtreepanel.renderer.StyledQueryStatementTreeCellRenderer;
import uk.nhs.cfh.dsp.srth.query.converters.text.QueryExpressionPlainTextRenderer;
import uk.nhs.cfh.dsp.srth.query.model.om.*;
import uk.nhs.cfh.dsp.srth.query.service.QueryService;
import uk.nhs.cfh.dsp.srth.query.service.QueryServiceListener;
import uk.nhs.cfh.dsp.yasb.search.TerminologySearchService;

import javax.swing.*;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

// TODO: Auto-generated Javadoc
/**
 * A custom panel that allows creation of a {@link uk.nhs.cfh.dsp.srth.query.model.om.impl.QueryStatementImpl} via a
 * tree interface.
 *
 * <br> Version : @#VersionNumber#@
 * <br> Written by @author Jay Kola
 * <br> Created on Apr 5, 2009 at 11:19:13 PM
 * <br> Modified on Thursday; November 26, 2009 at 12:03 PM
 * <br> Modified on Sunday; December 6, 2009 at 4:21 PM to create user friendly labels
 */
@SuppressWarnings({ "serial", "unused" })
public class QueryAuthoringTreePanel extends JPanel
        implements ActionListener, QueryServiceListener, SelectionServiceListener {

    /** The active query. */
    private QueryStatement activeQuery;

    /** The selected expression. */
    private QueryExpression selectedExpression;

    /** The reporting query tree model. */
    private ReportingQueryStatementTreeModel reportingQueryTreeModel;

    /** The query actions menu. */
    private JPopupMenu queryActionsMenu;

    /** The logger. */
    private static Log logger = LogFactory.getLog(QueryAuthoringTreePanel.class);

    /** The query interface tree. */
    private JXTree queryInterfaceTree;

    /** The toggle status menu. */
    private JPopupMenu toggleStatusMenu;

    /** The query expression plain text renderer. */
    private QueryExpressionPlainTextRenderer queryExpressionPlainTextRenderer;

    /** The terminology search service. */
    private TerminologySearchService terminologySearchService;

    /** The human readable render. */
    private HumanReadableRender humanReadableRender;

    /** The selection service. */
    private SelectionService selectionService;

    /** The terminology concept dao. */
    private TerminologyConceptDAO terminologyConceptDAO;

    /** The application service. */
    private ApplicationService applicationService;

    /** The active frame. */
    private JFrame activeFrame;

    /** The property change tracker service. */
    private PropertyChangeTrackerService propertyChangeTrackerService;

    /** The query service. */
    private QueryService queryService;

    /** The normal form generator. */
    private NormalFormGenerator normalFormGenerator;

    /** The query expression factory. */
    private QueryExpressionFactory queryExpressionFactory;

    /** The query component expression panel. */
    private QueryComponentExpressionPanel queryComponentExpressionPanel;

    /** The query component expression dialog. */
    private JDialog queryComponentExpressionDialog;

    /**
     * Instantiates a new query authoring tree panel.
     *
     * @param applicationService the application service
     * @param queryService the query service
     * @param terminologySearchService the terminology search service
     * @param terminologyConceptDAO the terminology concept dao
     * @param selectionService the selection service
     * @param queryExpressionPlainTextRenderer the query expression plain text renderer
     * @param propertyChangeTrackerService the property change tracker service
     * @param humanReadableRender the human readable render
     * @param normalFormGenerator the normal form generator
     * @param queryExpressionFactory the query expression factory
     */
    public QueryAuthoringTreePanel(ApplicationService applicationService, QueryService queryService,
            TerminologySearchService terminologySearchService, TerminologyConceptDAO terminologyConceptDAO,
            SelectionService selectionService, QueryExpressionPlainTextRenderer queryExpressionPlainTextRenderer,
            PropertyChangeTrackerService propertyChangeTrackerService, HumanReadableRender humanReadableRender,
            NormalFormGenerator normalFormGenerator, QueryExpressionFactory queryExpressionFactory) {
        this.applicationService = applicationService;
        this.queryService = queryService;
        this.terminologySearchService = terminologySearchService;
        this.terminologyConceptDAO = terminologyConceptDAO;
        this.selectionService = selectionService;
        this.queryExpressionPlainTextRenderer = queryExpressionPlainTextRenderer;
        this.propertyChangeTrackerService = propertyChangeTrackerService;
        this.humanReadableRender = humanReadableRender;
        this.normalFormGenerator = normalFormGenerator;
        this.queryExpressionFactory = queryExpressionFactory;

        activeQuery = queryService.getActiveQuery();
    }

    /**
     * Inits the components.
     */
    public synchronized void initComponents() {
        setName(getClass().getCanonicalName());

        createQueryComponentExpressionDialog();
        // create pop up menu
        createPopupMenus();
        //create tree
        createTreeInterface();

        // set layout and add tree
        setLayout(new BorderLayout());
        add(new JScrollPane(queryInterfaceTree), BorderLayout.CENTER);
    }

    /**
     * Creates the tree interface.
     */
    private void createTreeInterface() {

        reportingQueryTreeModel = new ReportingQueryStatementTreeModel(activeQuery);
        queryInterfaceTree = new JXTree(reportingQueryTreeModel);
        //        queryInterfaceTree.setCellRenderer(new ReportingQueryStatementTreeCellRenderer(humanReadableRender));
        queryInterfaceTree.setCellRenderer(new StyledQueryStatementTreeCellRenderer(humanReadableRender));
        queryInterfaceTree.addHighlighter(HighlighterFactory.createAlternateStriping());
        // add listener for mouse events
        queryInterfaceTree.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                evaluatePopupAction(e);
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                evaluatePopupAction(e);
            }

            private void evaluatePopupAction(MouseEvent e) {
                // get node selected
                int row = queryInterfaceTree.getRowForLocation(e.getX(), e.getY());

                if (row > -1) {
                    TreePath selectedPath = queryInterfaceTree.getPathForLocation(e.getX(), e.getY());
                    Object node = selectedPath.getLastPathComponent();
                    if (node != null && node instanceof QueryExpression) {
                        QueryExpression expression = (QueryExpression) node;
                        // set selected expression
                        selectedExpression = expression;
                        // check if right click
                        if (expression instanceof QueryIntersectionExpression
                                || expression instanceof QueryUnionExpression
                                || expression instanceof QueryStatement) {
                            if (e.isPopupTrigger()) {
                                queryActionsMenu.show(e.getComponent(), e.getX(), e.getY());
                            }
                        } else if (expression instanceof QueryComponentExpression) {
                            if (e.getClickCount() == 2) {
                                QueryComponentExpression componentExpression = (QueryComponentExpression) expression;
                                // get selected sub query and display it in a dialog
                                queryComponentExpressionPanel.setComponentExpression(componentExpression);
                                //                                queryComponentExpressionDialog.setTitle("Author Component Query");
                                queryComponentExpressionDialog.setVisible(true);
                            } else if (e.isPopupTrigger()) {
                                toggleStatusMenu.show(e.getComponent(), e.getX(), e.getY());
                            }
                        }
                    }
                } else {
                    if (queryActionsMenu.isVisible()) {
                        queryActionsMenu.setVisible(false);
                    }

                    if (toggleStatusMenu.isVisible()) {
                        toggleStatusMenu.setVisible(false);
                    }
                }
            }

        });
    }

    /**
     * Creates the popup menus.
     */
    private void createPopupMenus() {

        queryActionsMenu = new JPopupMenu("Query Actions");
        JMenuItem orMenuItem = new JMenuItem("ANY of the following");
        orMenuItem.setActionCommand("Add OR");
        orMenuItem.addActionListener(this);

        JMenuItem andMenuItem = new JMenuItem("ALL of the following");
        andMenuItem.setActionCommand("Add And");
        andMenuItem.addActionListener(this);
        // add submenu to group logical relationships
        JMenu logicalSubMenu = new JMenu("Add Logical query");
        logicalSubMenu.add(andMenuItem);
        logicalSubMenu.add(orMenuItem);

        JMenuItem afterMenuItem = new JMenuItem("After");
        afterMenuItem.setActionCommand("After");
        afterMenuItem.addActionListener(this);
        JMenuItem beforeMenuItem = new JMenuItem("Before");
        beforeMenuItem.setActionCommand("Before");
        beforeMenuItem.addActionListener(this);
        // add submenu to group temporal relationships
        JMenu temporalSubMenu = new JMenu("Add Temporal query");
        temporalSubMenu.add(beforeMenuItem);
        temporalSubMenu.add(afterMenuItem);

        JMenuItem addCriterionMenuItem = new JMenuItem("Add Query criterion");
        addCriterionMenuItem.setActionCommand("Add Query criterion");
        addCriterionMenuItem.addActionListener(this);

        JMenuItem removeMenuItem1 = new JMenuItem("Remove criterion");
        removeMenuItem1.setActionCommand("Remove Expression");
        removeMenuItem1.addActionListener(this);

        queryActionsMenu.add(logicalSubMenu);
        queryActionsMenu.add(temporalSubMenu);
        queryActionsMenu.add(addCriterionMenuItem);
        queryActionsMenu.add(removeMenuItem1);

        queryActionsMenu.add(new AbstractAction("Toggle execution") {

            public void actionPerformed(ActionEvent arg0) {

                // get currently selected expression and toggle run time status between SKIP and EXECUTE
                QueryExpression.QueryRunTimeStatus status = selectedExpression.getRunTimeStatus();
                if (status == QueryExpression.QueryRunTimeStatus.EXECUTE) {
                    selectedExpression.setRunTimeStatus(QueryExpression.QueryRunTimeStatus.SKIP);
                } else {
                    selectedExpression.setRunTimeStatus(QueryExpression.QueryRunTimeStatus.EXECUTE);
                }
                // hide queryActionsMenu
                queryActionsMenu.setVisible(false);
                // revalidate tree
                queryInterfaceTree.revalidate();
            }
        });

        toggleStatusMenu = new JPopupMenu();
        JMenuItem removeMenuItem2 = new JMenuItem("Remove criterion");
        removeMenuItem2.setActionCommand("Remove Expression");
        removeMenuItem2.addActionListener(this);
        toggleStatusMenu.add(removeMenuItem2);
        toggleStatusMenu.add(new AbstractAction("Toggle execution") {

            public void actionPerformed(ActionEvent arg0) {

                // get currently selected expresion and toggle run time status between SKIP and EXECUTE
                QueryExpression.QueryRunTimeStatus status = selectedExpression.getRunTimeStatus();
                if (status == QueryExpression.QueryRunTimeStatus.EXECUTE) {
                    selectedExpression.setRunTimeStatus(QueryExpression.QueryRunTimeStatus.SKIP);
                } else {
                    selectedExpression.setRunTimeStatus(QueryExpression.QueryRunTimeStatus.EXECUTE);
                }

                // hide toggleStatusMenu
                toggleStatusMenu.setVisible(false);
                // revalidate tree
                queryInterfaceTree.revalidate();
                // notify listeners
                queryService.queryChanged(activeQuery, QueryAuthoringTreePanel.this);
            }
        });
    }

    /**
     * Creates the query component expression dialog.
     */
    private void createQueryComponentExpressionDialog() {

        // wait for applicationService  to make a frame available
        while (applicationService == null || activeFrame == null) {
            // check applicationService
            if (applicationService != null && applicationService.getFrameView() != null) {
                activeFrame = applicationService.getFrameView().getActiveFrame();
            }
        }
        // make dialog modal
        queryComponentExpressionPanel = new QueryComponentExpressionPanel(terminologySearchService,
                humanReadableRender, selectionService, terminologyConceptDAO, applicationService,
                propertyChangeTrackerService, normalFormGenerator, queryService, queryExpressionFactory);
        // initialise components
        queryComponentExpressionPanel.initComponents();
        propertyChangeTrackerService.registerListener(queryComponentExpressionPanel);

        queryComponentExpressionDialog = new JDialog(activeFrame, "Component Expression",
                Dialog.ModalityType.DOCUMENT_MODAL);
        queryComponentExpressionDialog.setPreferredSize(new Dimension(350, 450));
        queryComponentExpressionDialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
        queryComponentExpressionDialog.getContentPane().add(queryComponentExpressionPanel);
        queryComponentExpressionDialog.pack();
        queryComponentExpressionDialog.setLocationRelativeTo(activeFrame);
    }

    /* (non-Javadoc)
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */
    public void actionPerformed(ActionEvent e) {
        String actionCommand = e.getActionCommand();
        if ("Add And".equals(actionCommand)) {
            addExpressionAndNotify(queryExpressionFactory.getQueryIntersectionExpression());
        } else if ("Before".equals(actionCommand)) {
            QueryIntersectionExpression intersectionObject = queryExpressionFactory
                    .getQueryIntersectionExpression();
            intersectionObject.setOperator(QueryExpression.QueryOperatorType.BEFORE);
            addExpressionAndNotify(intersectionObject);
        } else if ("After".equals(actionCommand)) {
            QueryIntersectionExpression intersectionObject = queryExpressionFactory
                    .getQueryIntersectionExpression();
            intersectionObject.setOperator(QueryExpression.QueryOperatorType.AFTER);
            addExpressionAndNotify(intersectionObject);
        } else if ("Add OR".equals(actionCommand)) {
            addExpressionAndNotify(queryExpressionFactory.getQueryUnionExpression());
        } else if ("Remove Expression".equals(actionCommand)) {
            // get parent expression of selected expression
            QueryExpression parentExpression = selectedExpression.getParentExpression();
            if (parentExpression != null) {
                // update models
                reportingQueryTreeModel.removeNodeFromParent(selectedExpression);
                // remove actual relationship
                parentExpression.removeChildExpression(selectedExpression);
                // set selected expression to parent expression
                selectedExpression = parentExpression;
                // hide queryActionsMenu
                queryActionsMenu.setVisible(false);
                toggleStatusMenu.setVisible(false);
                // notify listeners
                queryService.queryChanged(activeQuery, this);
            }
        } else if ("Add Query criterion".equals(actionCommand)) {
            // hide queryActionsMenu
            queryActionsMenu.setVisible(false);
            // add a new query component expression to query
            QueryComponentExpression componentExpression = queryExpressionFactory.getQueryComponentExpression();
            // add componentExpression to selectedExpression
            selectedExpression.addChildExpression(componentExpression);
            // update models
            reportingQueryTreeModel.addChildToParent(componentExpression, selectedExpression);
            queryComponentExpressionPanel.setComponentExpression(componentExpression);
            if (queryComponentExpressionDialog != null) {
                queryComponentExpressionDialog.setVisible(true);
            }
        }
    }

    /**
     * Adds the expression and notify.
     *
     * @param queryExpression the query expression
     */
    private void addExpressionAndNotify(QueryExpression queryExpression) {
        // add queryExpression to selectedExpression
        selectedExpression.addChildExpression(queryExpression);
        // update models
        reportingQueryTreeModel.addChildToParent(queryExpression, selectedExpression);
        // hide queryActionsMenu
        queryActionsMenu.setVisible(false);
        // set selected expression to newly added expression
        selectedExpression = queryExpression;
        // notify listeners
        queryService.queryChanged(activeQuery, this);
        Runnable runnable = new Runnable() {
            public void run() {
                queryInterfaceTree.revalidate();
            }
        };

        SwingUtilities.invokeLater(runnable);
    }

    /* (non-Javadoc)
     * @see uk.nhs.cfh.dsp.srth.query.service.QueryServiceListener#queryChanged(uk.nhs.cfh.dsp.srth.query.service.QueryService, uk.nhs.cfh.dsp.srth.query.model.om.QueryStatement, java.lang.Object)
     */
    public void queryChanged(QueryService service, QueryStatement query, Object source) {

        if (query != null) {
            // reset active query
            activeQuery = query;
            logger.debug("Notified model of query change");
            reportingQueryTreeModel.populateModel(activeQuery);
            //            // scroll to active node
            //            if (selectedExpression != null && !(selectedExpression instanceof QueryStatement))
            //            {
            //                TreePath path = new TreePath(reportingQueryTreeModel.getPathToRoot(selectedExpression));
            //                queryInterfaceTree.scrollPathToVisible(path);
            //            }

            // update UI
            Runnable runnable = new Runnable() {
                public void run() {
                    queryInterfaceTree.revalidate();
                    SwingUtilities.updateComponentTreeUI(queryInterfaceTree);
                }
            };

            SwingUtilities.invokeLater(runnable);
        }
    }

    /* (non-Javadoc)
     * @see uk.nhs.cfh.dsp.srth.desktop.modularframework.SelectionServiceListener#selectionChanged(uk.nhs.cfh.dsp.srth.desktop.modularframework.SelectionService, java.lang.Object, java.lang.Object)
     */
    public void selectionChanged(SelectionService service, Object selection, Object source) {

    }
}