uk.nhs.cfh.dsp.yasb.expression.builder.RefinedExpressionBuilderPanel.java Source code

Java tutorial

Introduction

Here is the source code for uk.nhs.cfh.dsp.yasb.expression.builder.RefinedExpressionBuilderPanel.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.yasb.expression.builder;

import com.jidesoft.swing.JideButton;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdesktop.application.Application;
import org.jdesktop.application.Task;
import org.jdesktop.swingx.JXCollapsiblePane;
import org.jdesktop.swingx.JXList;
import uk.nhs.cfh.dsp.snomed.converters.human.readable.HumanReadableRender;
import uk.nhs.cfh.dsp.snomed.dao.TerminologyConceptDAO;
import uk.nhs.cfh.dsp.snomed.dao.utils.TerminologyConceptUtils;
import uk.nhs.cfh.dsp.snomed.expression.model.CloseToUserExpression;
import uk.nhs.cfh.dsp.snomed.expression.model.impl.CloseToUserExpressionImpl;
import uk.nhs.cfh.dsp.snomed.expression.model.impl.SnomedRelationshipPropertyExpression;
import uk.nhs.cfh.dsp.snomed.normaliser.NormalFormGenerator;
import uk.nhs.cfh.dsp.snomed.objectmodel.SnomedConcept;
import uk.nhs.cfh.dsp.snomed.objectmodel.SnomedRelationship;
import uk.nhs.cfh.dsp.snomed.objectmodel.impl.SnomedRelationshipImpl;
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.PropertyChangeTrackerServiceListener;
import uk.nhs.cfh.dsp.srth.desktop.modularframework.SelectionService;
import uk.nhs.cfh.dsp.srth.desktop.modularframework.SelectionServiceListener;
import uk.nhs.cfh.dsp.yasb.concept.hierarchy.panel.SnomedConceptHierarchyPanel;
import uk.nhs.cfh.dsp.yasb.expression.builder.model.PropertyExpressionListModel;
import uk.nhs.cfh.dsp.yasb.expression.builder.panels.ConceptPanel;
import uk.nhs.cfh.dsp.yasb.expression.builder.renderer.ExpressionListCellRenderer;
import uk.nhs.cfh.dsp.yasb.expression.renderer.ExpressionRenderingLabel;
import uk.nhs.cfh.dsp.yasb.search.TerminologySearchService;
import uk.nhs.cfh.dsp.yasb.searchpanel.SearchPanel;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;

// TODO: Auto-generated Javadoc
/**
 * A custom {@link javax.swing.JPanel} that allows the user to generate a post-coordinated expression
 * as a {@link uk.nhs.cfh.dsp.snomed.expression.model.CloseToUserExpression}
 *
 * <br>Version : @#VersionNumber#@
 * <br>Written by @author Jay Kola
 * <br>Created on Feb 23, 2010 at 12:26:28 PM
 */
public class RefinedExpressionBuilderPanel extends JPanel
        implements SelectionServiceListener, PropertyChangeTrackerServiceListener {

    /** The close to user expression. */
    private CloseToUserExpression closeToUserExpression;

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

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

    /** The search panel. */
    private SearchPanel searchPanel;

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

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

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

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

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

    /** The collapsible pane. */
    private JXCollapsiblePane collapsiblePane;

    /** The laterality label. */
    private JLabel lateralityLabel;

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

    /** The concept hierarchy dialog. */
    private JDialog conceptHierarchyDialog;

    /** The laterality hierarchy panel. */
    private SnomedConceptHierarchyPanel lateralityHierarchyPanel;

    /** The laterality relationship. */
    private SnomedRelationship lateralityRelationship;

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

    /** The Constant EXPRESSION_CHANGED. */
    private static final String EXPRESSION_CHANGED = "EXPRESSION_CHANGED";

    /** The laterality parent concept. */
    private SnomedConcept lateralityParentConcept;

    /** The border offset. */
    private static int borderOffset = 5;

    /** The rendering label. */
    private ExpressionRenderingLabel renderingLabel;

    /** The focus concept panel. */
    private ConceptPanel focusConceptPanel;

    /** The properties list. */
    private JXList propertiesList;

    /** The properties scroll pane. */
    private JScrollPane propertiesScrollPane;

    /** The selected property expression. */
    private SnomedRelationshipPropertyExpression selectedPropertyExpression;

    /** The active relationship. */
    private SnomedRelationship activeRelationship;

    /** The property expression list model. */
    private PropertyExpressionListModel propertyExpressionListModel;

    /**
     * Instantiates a new refined expression builder panel.
     *
     * @param terminologySearchService the terminology search service
     * @param applicationService the application service
     * @param selectionService the selection service
     * @param terminologyConceptDAO the terminology concept dao
     * @param propertyChangeTrackerService the property change tracker service
     * @param humanReadableRender the human readable render
     * @param normalFormGenerator the normal form generator
     */
    public RefinedExpressionBuilderPanel(TerminologySearchService terminologySearchService,
            ApplicationService applicationService, SelectionService selectionService,
            TerminologyConceptDAO terminologyConceptDAO, PropertyChangeTrackerService propertyChangeTrackerService,
            HumanReadableRender humanReadableRender, NormalFormGenerator normalFormGenerator) {
        this.terminologySearchService = terminologySearchService;
        this.applicationService = applicationService;
        this.selectionService = selectionService;
        this.terminologyConceptDAO = terminologyConceptDAO;
        this.propertyChangeTrackerService = propertyChangeTrackerService;
        this.humanReadableRender = humanReadableRender;
        this.normalFormGenerator = normalFormGenerator;
    }

    /**
     * empty constructor for IOC.
     */
    public RefinedExpressionBuilderPanel() {
        // empty constructor for IOC
    }

    /**
     * Inits the components.
     */
    public synchronized void initComponents() {

        // generate and store concept corresponding to Side |182353008|
        if (terminologyConceptDAO != null) {
            lateralityParentConcept = TerminologyConceptUtils.getConceptForID(terminologyConceptDAO, "182353008");
        }

        // add a collapsible panel in NORTH position with a concept search panel
        searchPanel = new SearchPanel(terminologySearchService, selectionService, applicationService,
                terminologyConceptDAO);
        searchPanel.initComponents();
        searchPanel.setPreferredSize(new Dimension(350, 450));
        collapsiblePane = new JXCollapsiblePane(new BorderLayout());
        collapsiblePane.add(searchPanel, BorderLayout.CENTER);
        collapsiblePane.setCollapsed(true);

        // create panel for rendering label
        renderingLabel = new ExpressionRenderingLabel(humanReadableRender);
        renderingLabel.initComponents();

        focusConceptPanel = new ConceptPanel(humanReadableRender);
        focusConceptPanel.initComponents();

        // create top panel with some instructions
        JPanel p1 = new JPanel();
        p1.setLayout(new BoxLayout(p1, BoxLayout.LINE_AXIS));
        p1.add(focusConceptPanel);

        // add button for editing focus concept
        JideButton editFocusConceptButton = new JideButton(new AbstractAction("Edit") {
            public void actionPerformed(ActionEvent e) {
                if (collapsiblePane.isCollapsed()) {
                    collapsiblePane.setCollapsed(false);
                } else {
                    collapsiblePane.setCollapsed(true);
                }
            }
        });
        p1.add(Box.createHorizontalGlue());
        p1.add(editFocusConceptButton);

        JPanel topPanel = new JPanel();
        topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.PAGE_AXIS));
        topPanel.add(renderingLabel);
        topPanel.add(p1);

        // create scrollPane that contains the properties
        propertyExpressionListModel = new PropertyExpressionListModel(normalFormGenerator);
        propertiesList = new JXList(propertyExpressionListModel);
        //        propertiesList.setCellRenderer(new PropertyExpressionListCellRenderer(selectionService,
        //                terminologyConceptDAO, applicationService, humanReadableRender));
        propertiesList.setCellRenderer(new ExpressionListCellRenderer(selectionService, terminologyConceptDAO,
                applicationService, humanReadableRender));
        propertiesScrollPane = new JScrollPane();
        propertiesScrollPane.setViewportView(propertiesList);

        //        // add mouse listeners to tree
        //        propertiesList.addMouseListener(new MouseAdapter() {
        //
        //            @Override
        //            public void mouseClicked(MouseEvent e) {
        //                int row = propertiesList.getSelectedIndex();
        //                if(row > -1 && e.getClickCount() == 2)
        //                {
        //                    // get selection
        //                    Object selection = propertiesList.getSelectedValue();
        //
        //                    // evaluate selection and set behaviour
        //                    if(selection instanceof SnomedRelationshipPropertyExpression)
        //                    {
        //                        SnomedRelationshipPropertyExpression propertyExpression =
        //                                (SnomedRelationshipPropertyExpression) selection;
        //                        // get contained relationship
        //                        SnomedRelationship relationship = propertyExpression.getRelationship();
        //                        if(relationship != null)
        //                        {
        //                            // set as selected propertyExpression
        //                            selectedPropertyExpression = propertyExpression;
        //                            // set as active relationship
        //                            activeRelationship = relationship;
        //                        }
        //                    }
        //                }
        //            }
        //        });

        // create laterality hierarchy panel
        createLateralityConceptHierarchyDialog();

        // add panel for adding laterality directly
        JPanel bottomPanel = new JPanel(new BorderLayout());
        // add label and button for laterilty value
        lateralityLabel = new JLabel();
        JButton editLateralityButton = new JButton(new AbstractAction("Edit") {
            public void actionPerformed(ActionEvent e) {
                /*
                 get lateralityHierarchyPanel and set parent to
                 Side |182353008|
                */

                lateralityHierarchyPanel.setConcept(lateralityParentConcept);
                // show conceptHierarchyDialog
                conceptHierarchyDialog.setLocationRelativeTo(activeFrame);
                conceptHierarchyDialog.setVisible(true);
            }
        });
        bottomPanel.add(new JLabel("<html><b>Laterality of concept </b></html>"), BorderLayout.WEST);
        bottomPanel.add(lateralityLabel, BorderLayout.CENTER);
        bottomPanel.add(editLateralityButton, BorderLayout.EAST);

        // add panels to this panel and main panel
        JPanel mainPanel = new JPanel(new BorderLayout());
        mainPanel.add(topPanel, BorderLayout.NORTH);
        mainPanel.add(propertiesScrollPane, BorderLayout.CENTER);

        // add to this panel
        setLayout(new BorderLayout());
        setBorder(BorderFactory.createEmptyBorder(borderOffset, borderOffset, borderOffset, borderOffset));
        add(collapsiblePane, BorderLayout.NORTH);
        add(mainPanel, BorderLayout.CENTER);
        add(bottomPanel, BorderLayout.SOUTH);
    }

    /**
     * Creates the laterality concept hierarchy dialog.
     */
    private synchronized void createLateralityConceptHierarchyDialog() {

        // wait for applicationService  to make a frame available
        while (activeFrame == null) {
            // check applicationService and set active frame
            if (applicationService != null) {
                activeFrame = applicationService.getFrameView().getActiveFrame();
            }
        }
        // create a laterality relationship that will be reused
        lateralityRelationship = new SnomedRelationshipImpl();
        lateralityRelationship.setRelationshipType("272741003");
        lateralityRelationship.setName("Laterality");

        // create lateralityHierarchyPanel panel
        lateralityHierarchyPanel = new SnomedConceptHierarchyPanel(terminologyConceptDAO, selectionService,
                applicationService);
        lateralityHierarchyPanel.initComponents();

        // wrap lateralityHierarchyPanel in a dialog
        conceptHierarchyDialog = new JDialog(activeFrame, "Concept Hierarchy", Dialog.ModalityType.DOCUMENT_MODAL);
        conceptHierarchyDialog.getContentPane().add(lateralityHierarchyPanel);
        conceptHierarchyDialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
        conceptHierarchyDialog.pack();
    }

    /**
     * Gets the close to user expression.
     *
     * @return the close to user expression
     */
    public CloseToUserExpression getCloseToUserExpression() {
        return closeToUserExpression;
    }

    /**
     * Sets the close to user expression.
     *
     * @param closeToUserExpression the new close to user expression
     */
    public void setCloseToUserExpression(CloseToUserExpression closeToUserExpression) {
        if (closeToUserExpression != null) {
            //            propertyChangeTrackerService.firePropertyChanged(EXPRESSION_CHANGED, getCloseToUserExpression(),
            //                    closeToUserExpression, this);
            this.closeToUserExpression = closeToUserExpression;
            renderingLabel.setExpression(this.closeToUserExpression);
            focusConceptPanel.setConcept(this.closeToUserExpression.getSingletonFocusConcept());
            populatePropertiesList();
        }
    }

    /**
     * Populate properties list.
     */
    private void populatePropertiesList() {

        class PopulateModelTask extends Task<Void, Void> {
            private CloseToUserExpression cte;

            PopulateModelTask(Application application, CloseToUserExpression closeToUserExpression) {
                super(application);
                this.cte = closeToUserExpression;
            }

            @Override
            protected Void doInBackground() throws Exception {
                propertyExpressionListModel.setCloseToUserExpression(cte);
                return null;
            }
        }

        PopulateModelTask task = new PopulateModelTask(applicationService.getActiveApplication(),
                getCloseToUserExpression());
        applicationService.getActiveApplication().getContext().getTaskService().execute(task);
    }

    /* (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 selectionService, Object selection, Object source) {
        // check source is not self and handle appropriately
        if (selection instanceof SnomedConcept) {
            SnomedConcept concept = (SnomedConcept) selection;
            if (source.equals(searchPanel)) {
                // create new close to use expression using concept and set as expression in snomedConceptRendererPanel
                CloseToUserExpression localExpression = new CloseToUserExpressionImpl(concept);
                // notify listeners of closeToUserExpression  change
                propertyChangeTrackerService.firePropertyChanged(EXPRESSION_CHANGED, getCloseToUserExpression(),
                        localExpression, this);
                // collapse searchPanel
                collapsiblePane.setCollapsed(true);
            } else if (source.equals(lateralityHierarchyPanel)) {
                if (getCloseToUserExpression() != null) {
                    // set lateralityLabel
                    lateralityLabel.setText(concept.getPreferredLabel());
                    lateralityLabel.setToolTipText(concept.getConceptID());
                    // set values for lateralityRelationship
                    lateralityRelationship.setTargetConcept(concept);
                    lateralityRelationship.setTargetConceptID(concept.getConceptID());
                    // notify listeners
                    notifyListeners();
                }

                // close conceptHierarchyDialog
                conceptHierarchyDialog.setVisible(false);
            }
        }
    }

    /**
     * Notify listeners.
     */
    private void notifyListeners() {
        CloseToUserExpression oldValue = getCloseToUserExpression();
        // add laterality to closeToUserExpression
        getCloseToUserExpression().addRefinement(new SnomedRelationshipPropertyExpression(lateralityRelationship));
        // notify listeners of closeToUserExpression  change
        propertyChangeTrackerService.firePropertyChanged(EXPRESSION_CHANGED, oldValue, getCloseToUserExpression(),
                this);
    }

    /**
     * Register.
     */
    public synchronized void register() {
        selectionService.registerListener(this);
        propertyChangeTrackerService.registerListener(this);
    }

    /**
     * Un register.
     */
    public synchronized void unRegister() {
        selectionService.unregisterListener(this);
        propertyChangeTrackerService.unregisterListener(this);
    }

    /* (non-Javadoc)
     * @see uk.nhs.cfh.dsp.srth.desktop.modularframework.PropertyChangeTrackerServiceListener#propertyChanged(java.lang.String, java.lang.Object, java.lang.Object, java.lang.Object)
     */
    public void propertyChanged(String propertyName, Object oldValue, Object newValue, Object source) {
        if (EXPRESSION_CHANGED.equalsIgnoreCase(propertyName) && newValue instanceof CloseToUserExpression) {
            // set closeToUserExpression to newValue
            setCloseToUserExpression((CloseToUserExpression) newValue);
        }
    }

    /**
     * Sets the terminology concept dao.
     *
     * @param terminologyConceptDAO the new terminology concept dao
     */
    public synchronized void setTerminologyConceptDAO(TerminologyConceptDAO terminologyConceptDAO) {
        this.terminologyConceptDAO = terminologyConceptDAO;
    }

    /**
     * Sets the terminology search service.
     *
     * @param terminologySearchService the new terminology search service
     */
    public synchronized void setTerminologySearchService(TerminologySearchService terminologySearchService) {
        this.terminologySearchService = terminologySearchService;
    }

    /**
     * Sets the application service.
     *
     * @param applicationService the new application service
     */
    public synchronized void setApplicationService(ApplicationService applicationService) {
        this.applicationService = applicationService;
    }

    /**
     * Sets the selection service.
     *
     * @param selectionService the new selection service
     */
    public synchronized void setSelectionService(SelectionService selectionService) {
        this.selectionService = selectionService;
    }

    /**
     * Sets the human readable render.
     *
     * @param humanReadableRender the new human readable render
     */
    public synchronized void setHumanReadableRender(HumanReadableRender humanReadableRender) {
        this.humanReadableRender = humanReadableRender;
    }

    /**
     * Sets the property change tracker service.
     *
     * @param propertyChangeTrackerService the new property change tracker service
     */
    public synchronized void setPropertyChangeTrackerService(
            PropertyChangeTrackerService propertyChangeTrackerService) {
        this.propertyChangeTrackerService = propertyChangeTrackerService;
    }

    /**
     * Sets the normal form generator.
     *
     * @param normalFormGenerator the new normal form generator
     */
    public synchronized void setNormalFormGenerator(NormalFormGenerator normalFormGenerator) {
        this.normalFormGenerator = normalFormGenerator;
    }
}