com.mirth.connect.client.ui.codetemplate.CodeTemplateLibrariesPanel.java Source code

Java tutorial

Introduction

Here is the source code for com.mirth.connect.client.ui.codetemplate.CodeTemplateLibrariesPanel.java

Source

/*
 * Copyright (c) Mirth Corporation. All rights reserved.
 * 
 * http://www.mirthcorp.com
 * 
 * The software in this package is published under the terms of the MPL license a copy of which has
 * been included with this distribution in the LICENSE.txt file.
 */

package com.mirth.connect.client.ui.codetemplate;

import java.awt.Color;
import java.awt.Component;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Enumeration;
import java.util.EventObject;
import java.util.HashMap;
import java.util.Map;
import java.util.prefs.Preferences;

import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextPane;
import javax.swing.JTree;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableCellEditor;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;

import net.miginfocom.swing.MigLayout;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.apache.commons.lang3.tuple.MutableTriple;
import org.apache.commons.lang3.tuple.Triple;
import org.jdesktop.swingx.decorator.HighlighterFactory;
import org.jdesktop.swingx.treetable.DefaultMutableTreeTableNode;
import org.jdesktop.swingx.treetable.DefaultTreeTableModel;
import org.jdesktop.swingx.treetable.MutableTreeTableNode;

import com.mirth.connect.client.ui.ChannelDependenciesDialog;
import com.mirth.connect.client.ui.Mirth;
import com.mirth.connect.client.ui.PlatformUI;
import com.mirth.connect.client.ui.SortableTreeTableModel;
import com.mirth.connect.client.ui.UIConstants;
import com.mirth.connect.client.ui.components.MirthTreeTable;
import com.mirth.connect.model.Channel;
import com.mirth.connect.model.CodeTemplate;
import com.mirth.connect.model.CodeTemplateLibrary;
import com.mirth.connect.util.CodeTemplateUtil;
import com.mirth.connect.util.MirthXmlUtil;

public class CodeTemplateLibrariesPanel extends JPanel {

    private ChannelDependenciesDialog parent;
    private Map<String, CodeTemplateLibrary> libraryMap = new HashMap<String, CodeTemplateLibrary>();
    private String channelId;
    private boolean changed = false;

    public CodeTemplateLibrariesPanel(ChannelDependenciesDialog parent, Channel channel) {
        this.parent = parent;
        this.channelId = channel.getId();
        initComponents(channel);
        initLayout();
    }

    public void initialize() {
        PlatformUI.MIRTH_FRAME.codeTemplatePanel.doRefreshCodeTemplates(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                for (CodeTemplateLibrary library : PlatformUI.MIRTH_FRAME.codeTemplatePanel
                        .getCachedCodeTemplateLibraries().values()) {
                    libraryMap.put(library.getId(), new CodeTemplateLibrary(library));
                }
                Map<String, CodeTemplate> codeTemplateMap = PlatformUI.MIRTH_FRAME.codeTemplatePanel
                        .getCachedCodeTemplates();

                DefaultMutableTreeTableNode rootNode = new DefaultMutableTreeTableNode();

                for (CodeTemplateLibrary library : libraryMap.values()) {
                    boolean enabled = library.getEnabledChannelIds().contains(channelId)
                            || (library.isIncludeNewChannels()
                                    && !library.getDisabledChannelIds().contains(channelId));
                    DefaultMutableTreeTableNode libraryNode = new DefaultMutableTreeTableNode(
                            new ImmutableTriple<String, String, Boolean>(library.getId(), library.getName(),
                                    enabled));

                    for (CodeTemplate codeTemplate : library.getCodeTemplates()) {
                        codeTemplate = codeTemplateMap.get(codeTemplate.getId());
                        if (codeTemplate != null) {
                            libraryNode.add(
                                    new DefaultMutableTreeTableNode(new ImmutableTriple<String, String, Boolean>(
                                            codeTemplate.getId(), codeTemplate.getName(), enabled)));
                        }
                    }

                    rootNode.add(libraryNode);
                }

                ((DefaultTreeTableModel) libraryTreeTable.getTreeTableModel()).setRoot(rootNode);
                libraryTreeTable.expandAll();

                libraryTreeTable.getModel().addTableModelListener(new TableModelListener() {
                    @Override
                    public void tableChanged(TableModelEvent evt) {
                        for (Enumeration<? extends MutableTreeTableNode> libraryNodes = ((DefaultMutableTreeTableNode) libraryTreeTable
                                .getTreeTableModel().getRoot()).children(); libraryNodes.hasMoreElements();) {
                            Triple<String, String, Boolean> triple = (Triple<String, String, Boolean>) libraryNodes
                                    .nextElement().getUserObject();

                            CodeTemplateLibrary library = libraryMap.get(triple.getLeft());
                            if (triple.getRight()) {
                                library.getDisabledChannelIds().remove(channelId);
                                library.getEnabledChannelIds().add(channelId);
                            } else {
                                library.getDisabledChannelIds().add(channelId);
                                library.getEnabledChannelIds().remove(channelId);
                            }
                        }
                    }
                });

                parent.codeTemplateLibrariesReady();
            }
        });
    }

    public Map<String, CodeTemplateLibrary> getLibraryMap() {
        return libraryMap;
    }

    public boolean wasChanged() {
        return changed;
    }

    private void initComponents(Channel channel) {
        setBackground(UIConstants.BACKGROUND_COLOR);

        selectAllLabel = new JLabel("<html><u>Select All</u></html>");
        selectAllLabel.setForeground(Color.BLUE);
        selectAllLabel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent evt) {
                for (Enumeration<? extends MutableTreeTableNode> libraryNodes = ((MutableTreeTableNode) libraryTreeTable
                        .getTreeTableModel().getRoot()).children(); libraryNodes.hasMoreElements();) {
                    MutableTreeTableNode libraryNode = libraryNodes.nextElement();
                    Triple<String, String, Boolean> triple = (Triple<String, String, Boolean>) libraryNode
                            .getUserObject();
                    libraryTreeTable.getTreeTableModel().setValueAt(
                            new MutableTriple<String, String, Boolean>(triple.getLeft(), triple.getMiddle(), true),
                            libraryNode, libraryTreeTable.getHierarchicalColumn());
                }
                libraryTreeTable.updateUI();
            }
        });

        selectSeparatorLabel = new JLabel("|");

        deselectAllLabel = new JLabel("<html><u>Deselect All</u></html>");
        deselectAllLabel.setForeground(Color.BLUE);
        deselectAllLabel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent evt) {
                for (Enumeration<? extends MutableTreeTableNode> libraryNodes = ((MutableTreeTableNode) libraryTreeTable
                        .getTreeTableModel().getRoot()).children(); libraryNodes.hasMoreElements();) {
                    MutableTreeTableNode libraryNode = libraryNodes.nextElement();
                    Triple<String, String, Boolean> triple = (Triple<String, String, Boolean>) libraryNode
                            .getUserObject();
                    libraryTreeTable.getTreeTableModel().setValueAt(
                            new MutableTriple<String, String, Boolean>(triple.getLeft(), triple.getMiddle(), false),
                            libraryNode, libraryTreeTable.getHierarchicalColumn());
                }
                libraryTreeTable.updateUI();
            }
        });

        expandAllLabel = new JLabel("<html><u>Expand All</u></html>");
        expandAllLabel.setForeground(Color.BLUE);
        expandAllLabel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent evt) {
                libraryTreeTable.expandAll();
            }
        });

        expandSeparatorLabel = new JLabel("|");

        collapseAllLabel = new JLabel("<html><u>Collapse All</u></html>");
        collapseAllLabel.setForeground(Color.BLUE);
        collapseAllLabel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent evt) {
                libraryTreeTable.collapseAll();
            }
        });

        final TableCellEditor libraryCellEditor = new LibraryTreeCellEditor();

        libraryTreeTable = new MirthTreeTable() {
            @Override
            public TableCellEditor getCellEditor(int row, int column) {
                if (isHierarchical(column)) {
                    return libraryCellEditor;
                } else {
                    return super.getCellEditor(row, column);
                }
            }
        };

        DefaultTreeTableModel model = new SortableTreeTableModel();
        DefaultMutableTreeTableNode rootNode = new DefaultMutableTreeTableNode();
        model.setRoot(rootNode);

        libraryTreeTable.setLargeModel(true);
        libraryTreeTable.setTreeTableModel(model);
        libraryTreeTable.setOpenIcon(null);
        libraryTreeTable.setClosedIcon(null);
        libraryTreeTable.setLeafIcon(null);
        libraryTreeTable.setRootVisible(false);
        libraryTreeTable.setDoubleBuffered(true);
        libraryTreeTable.setDragEnabled(false);
        libraryTreeTable.setRowSelectionAllowed(true);
        libraryTreeTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        libraryTreeTable.setRowHeight(UIConstants.ROW_HEIGHT);
        libraryTreeTable.setFocusable(true);
        libraryTreeTable.setOpaque(true);
        libraryTreeTable.setEditable(true);
        libraryTreeTable.setSortable(false);
        libraryTreeTable.setAutoCreateColumnsFromModel(false);
        libraryTreeTable.setShowGrid(true, true);
        libraryTreeTable.setTableHeader(null);

        if (Preferences.userNodeForPackage(Mirth.class).getBoolean("highlightRows", true)) {
            libraryTreeTable.setHighlighters(HighlighterFactory
                    .createAlternateStriping(UIConstants.HIGHLIGHTER_COLOR, UIConstants.BACKGROUND_COLOR));
        }

        libraryTreeTable.setTreeCellRenderer(new LibraryTreeCellRenderer());

        libraryTreeTable.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent evt) {
                checkSelection(evt);
            }

            @Override
            public void mouseReleased(MouseEvent evt) {
                checkSelection(evt);
            }

            private void checkSelection(MouseEvent evt) {
                if (libraryTreeTable.rowAtPoint(new Point(evt.getX(), evt.getY())) < 0) {
                    libraryTreeTable.clearSelection();
                }
            }
        });

        libraryTreeTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent evt) {
                if (!evt.getValueIsAdjusting()) {
                    boolean visible = false;
                    int selectedRow = libraryTreeTable.getSelectedRow();

                    if (selectedRow >= 0) {
                        TreePath selectedPath = libraryTreeTable.getPathForRow(selectedRow);
                        if (selectedPath != null) {
                            visible = true;
                            Triple<String, String, Boolean> triple = (Triple<String, String, Boolean>) ((MutableTreeTableNode) selectedPath
                                    .getLastPathComponent()).getUserObject();
                            String description = "";

                            if (selectedPath.getPathCount() == 2) {
                                description = libraryMap.get(triple.getLeft()).getDescription();
                            } else if (selectedPath.getPathCount() == 3) {
                                description = PlatformUI.MIRTH_FRAME.codeTemplatePanel.getCachedCodeTemplates()
                                        .get(triple.getLeft()).getDescription();
                            }

                            if (StringUtils.isBlank(description) || StringUtils.equals(description, CodeTemplateUtil
                                    .getDocumentation(CodeTemplate.DEFAULT_CODE).getDescription())) {
                                descriptionTextPane.setText(
                                        "<html><body class=\"code-template-libraries-panel\"><i>No description.</i></body></html>");
                            } else {
                                descriptionTextPane.setText("<html><body class=\"code-template-libraries-panel\">"
                                        + MirthXmlUtil.encode(description) + "</body></html>");
                            }
                        }
                    }

                    descriptionScrollPane.setVisible(visible);
                    updateUI();
                }
            }
        });

        libraryTreeTableScrollPane = new JScrollPane(libraryTreeTable);

        descriptionTextPane = new JTextPane();
        descriptionTextPane.setContentType("text/html");
        HTMLEditorKit editorKit = new HTMLEditorKit();
        StyleSheet styleSheet = editorKit.getStyleSheet();
        styleSheet.addRule(".code-template-libraries-panel {font-family:\"Tahoma\";font-size:11;text-align:top}");
        descriptionTextPane.setEditorKit(editorKit);
        descriptionTextPane.setEditable(false);
        descriptionScrollPane = new JScrollPane(descriptionTextPane);
        descriptionScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        descriptionScrollPane.setVisible(false);
    }

    private void initLayout() {
        setLayout(new MigLayout("insets 0, novisualpadding, hidemode 3, fill"));
        add(selectAllLabel, "split 3");
        add(selectSeparatorLabel);
        add(deselectAllLabel);
        add(expandAllLabel, "right, split, w 51!");
        add(expandSeparatorLabel);
        add(collapseAllLabel, "w 60!");
        add(libraryTreeTableScrollPane, "newline, grow, sx, push");
        add(descriptionScrollPane, "newline, grow, sx, h 90!");
    }

    private class LibraryTreeCellRenderer extends JPanel implements TreeCellRenderer {

        private JCheckBox checkBox;
        private JLabel filler;
        private JLabel label;

        public LibraryTreeCellRenderer() {
            super(new MigLayout("insets 0, novisualpadding, hidemode 3, fill"));
            checkBox = new JCheckBox();
            add(checkBox);
            filler = new JLabel();
            add(filler, "w 13!");
            label = new JLabel();
            add(label, "grow, push");
        }

        @Override
        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded,
                boolean leaf, int row, boolean hasFocus) {
            if (selected) {
                setBackground(libraryTreeTable.getSelectionBackground());
            } else {
                setBackground(row % 2 == 0 ? UIConstants.HIGHLIGHTER_COLOR : UIConstants.BACKGROUND_COLOR);
            }
            checkBox.setBackground(getBackground());
            label.setBackground(getBackground());

            if (value != null) {
                MutableTreeTableNode node = (MutableTreeTableNode) value;

                if (node.getUserObject() != null) {
                    Triple<String, String, Boolean> triple = (Triple<String, String, Boolean>) node.getUserObject();
                    label.setText(triple.getMiddle());
                    checkBox.setSelected(triple.getRight());
                    if (node.getParent().getParent() == null) {
                        checkBox.setVisible(true);
                        filler.setVisible(false);
                    } else {
                        checkBox.setVisible(false);
                        filler.setVisible(true);
                    }
                }
            }
            return this;
        }
    }

    private class LibraryTreeCellEditor extends DefaultCellEditor {

        private CheckBoxPanel panel;
        private JCheckBox checkBox;
        private JLabel filler;
        private JLabel label;
        private String id;

        public LibraryTreeCellEditor() {
            super(new JCheckBox());
            panel = new CheckBoxPanel(new MigLayout("insets 1 0 0 0, novisualpadding, hidemode 3, fill"));
            checkBox = (JCheckBox) editorComponent;
            panel.add(checkBox);
            filler = new JLabel();
            panel.add(filler, "w 13!");
            label = new JLabel();
            panel.add(label, "grow, push");

            checkBox.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent evt) {
                    changed = true;
                }
            });
        }

        @Override
        public Object getCellEditorValue() {
            return new ImmutableTriple<String, String, Boolean>(id, label.getText(), checkBox.isSelected());
        }

        @Override
        public boolean isCellEditable(EventObject anEvent) {
            return true;
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row,
                int column) {
            Triple<String, String, Boolean> triple = (Triple<String, String, Boolean>) value;
            if (triple != null) {
                id = triple.getLeft();
                label.setText(triple.getMiddle());
                checkBox.setSelected(triple.getRight());
            }

            MirthTreeTable treeTable = (MirthTreeTable) table;
            JTree tree = (JTree) treeTable.getCellRenderer(0, treeTable.getHierarchicalColumn());
            panel.setOffset(tree.getRowBounds(row).x);
            panel.setBackground(table.getSelectionBackground());
            checkBox.setBackground(panel.getBackground());
            label.setBackground(panel.getBackground());

            TreePath path = treeTable.getPathForRow(row);
            if (path != null && path.getPathCount() == 2) {
                checkBox.setVisible(true);
                filler.setVisible(false);
            } else {
                checkBox.setVisible(false);
                filler.setVisible(true);
            }

            return panel;
        }

        private class CheckBoxPanel extends JPanel {

            private int offset;

            public CheckBoxPanel(LayoutManager layout) {
                super(layout);
            }

            public void setOffset(int offset) {
                this.offset = offset;
            }

            @Override
            public void setBounds(int x, int y, int width, int height) {
                super.setBounds(x + offset, y, width - offset, height);
            }
        }
    }

    private JLabel selectAllLabel;
    private JLabel selectSeparatorLabel;
    private JLabel deselectAllLabel;
    private JLabel expandAllLabel;
    private JLabel expandSeparatorLabel;
    private JLabel collapseAllLabel;
    private MirthTreeTable libraryTreeTable;
    private JScrollPane libraryTreeTableScrollPane;
    private JTextPane descriptionTextPane;
    private JScrollPane descriptionScrollPane;
}