Package org.openquark.gems.client

Source Code of org.openquark.gems.client.CreateMinimalWorkspacePanel$ListWithCheckBoxes$LabelWithCheckBox

/*
* Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright notice,
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of Business Objects nor the names of its contributors
*       may be used to endorse or promote products derived from this software
*       without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/


/*
* CreateMinimalWorkspacePanel.java
* Creation date: May 25, 2006.
* By: Joseph Wong
*/
package org.openquark.gems.client;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.ItemSelectable;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.EventListener;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;

import org.openquark.cal.compiler.FieldName;
import org.openquark.cal.compiler.ModuleName;
import org.openquark.cal.services.CALWorkspace;
import org.openquark.cal.services.VaultElementInfo;
import org.openquark.util.Pair;
import org.openquark.util.UnsafeCast;
import org.openquark.util.model.EventListenerList;
import org.openquark.util.ui.LabelProvider;


/**
* This class implements a reusable panel for specifying the modules creating a minimal workspace.
*
* @author Joseph Wong
*/
class CreateMinimalWorkspacePanel extends JPanel {

    private static final long serialVersionUID = -8843872729742066027L;

    /**
     * A JList that adds check-boxes to each row and maintains a set of "checked"
     * values. Implements ItemSelectable so listeners can keep track of which
     * values are selected according to the check boxes.
     *
     * @author Robin Salkeld
     */
    public static class ListWithCheckBoxes extends JList implements ItemSelectable {
       
        private static final long serialVersionUID = -3360677654265720512L;

        /** The background color of the parent list */
        private static final Color BACKGROUND = SystemColor.text;
       
        /** The label provider used to render the cells */
        private final LabelProvider labelProvider;
       
        /** The set of listeners triggered when checkboxes are set or cleared */
        private final EventListenerList checkboxListeners = new EventListenerList(ItemListener.class);
       
        /** An internal flag for determining whether events should be blocked. */
        private boolean blockEvents = false;
       
        public ListWithCheckBoxes(LabelProvider labelProvider) {
            super();
            this.labelProvider = labelProvider;
            setBackground(BACKGROUND);
            setCellRenderer(new LabelWithCheckBoxCellRenderer());
            addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    handleMousePressedEvent(e);
                }
            });
        }
       
        /**
         * Returns a list of objects that are selected by the user.
         * @return the checked values
         */
        public Set<ModuleName> getCheckedValues() {
            Set<ModuleName> retval = new HashSet<ModuleName>();
            ListModel model = getModel();
            for (int i = 0, size = model.getSize(); i < size; i++) {
                LabelWithCheckBox checkBox = (LabelWithCheckBox) model.getElementAt(i);
                if (checkBox.isSelected()) {
                    retval.add((ModuleName)checkBox.getObject());
                }
            }
            return retval;
        }
       
        /**
         * {@inheritDoc}
         */
        public void addItemListener(ItemListener l) {
            checkboxListeners.add(l);
        }
       
        /**
         * {@inheritDoc}
         */
        public Object[] getSelectedObjects() {
            return getCheckedValues().toArray();
        }
       
        /**
         * {@inheritDoc}
         */
        public void removeItemListener(ItemListener l) {
            checkboxListeners.remove(l);
        }
       
        /**
         * Builds the valid elements list.
         */
        public void buildList(Set<FieldName> selectedValues, List<ModuleName> allValues) {
            DefaultListModel model = new DefaultListModel();
            for (int i = 0, size = allValues.size(); i < size; i++) {
                Object value = allValues.get(i);
               
                LabelWithCheckBox checkBox = new LabelWithCheckBox(value, labelProvider);
                checkBox.setBackground(BACKGROUND);
                if (selectedValues.contains(value)) {
                    checkBox.setSelected(true);
                }
               
                model.add(i, checkBox);
            }
            setModel(model);
        }
       
        /**
         * Selects all the elements in the list.
         */
        public void selectAll() {
            blockEvents = true;
            DefaultListModel model = (DefaultListModel)getModel();
            for (int i = 0, n = model.getSize(); i < n; i++) {
                LabelWithCheckBox checkBox = (LabelWithCheckBox)model.get(i);
                checkBox.setSelected(true);
            }
            blockEvents = false;
            fireEvent(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED, model, ItemEvent.SELECTED));
            repaint();
        }
       
        /**
         * Deselects all the elements in the list.
         */
        public void deselectAll() {
            blockEvents = true;
            DefaultListModel model = (DefaultListModel)getModel();
            for (int i = 0, n = model.getSize(); i < n; i++) {
                LabelWithCheckBox checkBox = (LabelWithCheckBox)model.get(i);
                checkBox.setSelected(false);
            }
            blockEvents = false;
            fireEvent(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED, model, ItemEvent.DESELECTED));
            repaint();
        }
       
        /**
         * This event handler is called whenever the mouse button is pressed.
         * @param event
         */
        private void handleMousePressedEvent(MouseEvent event) {
            int index = locationToIndex(event.getPoint());
            if (index >= 0) {
                LabelWithCheckBox checkBox =
                    (LabelWithCheckBox) getModel().getElementAt(index);
                if (checkBox.isEnabled()) {
                    checkBox.setSelected(!checkBox.isSelected());
                }
                repaint();
            }
        }
       
        /**
         * Fires an item state change event to all relevant listeners.
         */
        private void fireEvent(ItemEvent event) {
            if (!blockEvents) {
                for (Iterator<EventListener> iter = checkboxListeners.getListeners(); iter.hasNext();) {
                    ItemListener listener = (ItemListener)iter.next();
                    listener.itemStateChanged(event);
                }
            }
        }
       
        /**
         * A simple panel that emulates a checkbox, with custom node type icons.
         */
        private class LabelWithCheckBox extends JPanel {
            private static final long serialVersionUID = 4609318443869473231L;

            /** Stores a reference to the object */
            private final Object object;
           
            /** Do not display the text with this checkbox */
            private JCheckBox checkBox;
           
            /** Display the node type name and icon with this component */
            private JLabel label;
           
            /** The label provider used to render the object */
            private final LabelProvider labelProvider;
           
            public LabelWithCheckBox(Object object, LabelProvider labelProvider) {
                super(new BorderLayout());
                this.object = object;
                this.labelProvider = labelProvider;
                initializeUI();
            }
           
            /**
             * Returns the object associated with this check box.
             * @return Object
             */
            public Object getObject() {
                return object;
            }
           
            /**
             * Sets the selection state of this check box and fires listeners as needed.
             * @param selected
             */
            public void setSelected(boolean selected) {
                boolean wasSelected = checkBox.isSelected();
                checkBox.setSelected(selected);
               
                if (wasSelected != selected) {
                    int stateChange = (wasSelected ? ItemEvent.DESELECTED : ItemEvent.SELECTED);
                    ItemEvent event = new ItemEvent(ListWithCheckBoxes.this, ItemEvent.ITEM_STATE_CHANGED,
                            getObject(), stateChange);
                    fireEvent(event);
                }
            }
           
            /**
             * Returns the selection state of this check box.
             * @return boolean
             */
            public boolean isSelected() {
                return checkBox.isSelected();
            }
           
            /**
             * {@inheritDoc}
             */
            @Override
            public void setBackground(Color color) {
                super.setBackground(color);
                if (checkBox != null) {
                    checkBox.setBackground(color);
                }
                if (label != null) {
                    label.setBackground(color);
                }
            }
           
            /**
             * Initializes the UI and add comonents to the panel.  This should be
             * called once only.
             */
            private void initializeUI() {
                checkBox = new JCheckBox();
                add(checkBox, BorderLayout.WEST);
               
                label = new JLabel(labelProvider.getText(object));
                Icon icon = labelProvider.getIcon(object, false);
                if (icon != null) {
                    label.setIcon(icon);
                }
                add(label, BorderLayout.CENTER);
            }
           
            /**
             * {@inheritDoc}
             */
            @Override
            public void setEnabled(boolean enabled) {
                super.setEnabled(enabled);
               
                label.setEnabled(enabled);
                checkBox.setEnabled(enabled);
            }
           
        }
       
        /**
         * A simple <code>ListCellRenderer</code> that is able to render checkboxes
         * in a JList component.
         */
        private static class LabelWithCheckBoxCellRenderer implements ListCellRenderer {
           
            /**
             * {@inheritDoc}
             */
            public Component getListCellRendererComponent(JList list, Object value,
                    int index, boolean isSelected, boolean cellHasFocus) {
                return (LabelWithCheckBox) value;
            }
        }
       
        /**
         * {@inheritDoc}
         */
        @Override
        public void setEnabled(boolean enabled) {
            super.setEnabled(enabled);
           
            DefaultListModel model = (DefaultListModel)getModel();
            for (int i = 0, n = model.getSize(); i < n; i++) {
                LabelWithCheckBox checkBox = (LabelWithCheckBox)model.get(i);
                checkBox.setEnabled(enabled);
            }
        }
    }
   
    /** The list of checkboxes for the user to specify which modules should be the root set of the minimal workspace. */
    private ListWithCheckBoxes fromList;
   
    /** The list for displaying all the modules in the minimal workspace. */
    private JList modulesInMinimalWorkspaceList;
   
    /** The current workspace. */
    private final CALWorkspace workspace;

    /** The button for selecting all the modules in the list of checkboxes. */
    private final JButton selectAllButton = new JButton(GemCutter.getResourceString("CreateMinimalWorkspaceSelectAll"));

    /** The button for deselecting all the modules in the list of checkboxes. */
    private final JButton deselectAllButton = new JButton(GemCutter.getResourceString("CreateMinimalWorkspaceDeselectAll"));
   
    /**
     * Constructs a CreateMinimalWorkspacePanel.
     * @param workspace the current workspace.
     */
    CreateMinimalWorkspacePanel(CALWorkspace workspace) {
       
        super(new GridLayout(2, 0));
      
        if (workspace == null) {
            throw new NullPointerException();
        }
       
        this.workspace = workspace;
       
        ModuleName[] moduleNames = workspace.getModuleNames();
        Arrays.sort(moduleNames);

        Dimension listDimension = new Dimension(130, 130);

        JPanel fromListPanel = new JPanel(new BorderLayout());
        {
            fromList = new ListWithCheckBoxes(new LabelProvider() {
               
                public Icon getIcon(Object item, boolean expanded) {
                    return null;
                }
               
                public String getText(Object item) {
                    return item.toString();
                }
               
                public String getTooltipText(Object item) {
                    return item.toString();
                }
            });
           
            fromList.buildList(Collections.<FieldName>emptySet(), Arrays.asList(moduleNames));
           
            fromList.addItemListener(new ItemListener() {
                public void itemStateChanged(ItemEvent e) {
                    updateModulesInMinimalWorkspaceList();
                }
            });
           
            JScrollPane fromListScrollPane = new JScrollPane(fromList);
            fromListScrollPane.setMinimumSize(listDimension);
            fromListScrollPane.setPreferredSize(listDimension);
           
            fromListPanel.add(fromListScrollPane, BorderLayout.CENTER);
           
            JPanel buttonPanel = new JPanel(new BorderLayout());
            {
                JPanel innerButtonPanel = new JPanel();
                {
                    innerButtonPanel.setLayout(new GridLayout(0, 1));
                   
                    selectAllButton.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                            fromList.selectAll();
                        }
                    });
                   
                    deselectAllButton.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                            fromList.deselectAll();
                        }
                    });
                   
                    innerButtonPanel.add(wrapWithBorder(selectAllButton, 0, 6, 3, 0));
                    innerButtonPanel.add(wrapWithBorder(deselectAllButton, 3, 6, 0, 0));
                }
                buttonPanel.add(innerButtonPanel, BorderLayout.NORTH);
            }
            fromListPanel.add(buttonPanel, BorderLayout.EAST);
           
            fromListPanel.setBorder(
                BorderFactory.createCompoundBorder(
                    BorderFactory.createEmptyBorder(0, 0, 12, 0),
                    BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), GemCutter.getResourceString("CreateMinimalWorkspaceSelectModules"))));
        }
        this.add(fromListPanel);
       
        JPanel toListPanel = new JPanel(new BorderLayout());
        {
            modulesInMinimalWorkspaceList = new JList();
            modulesInMinimalWorkspaceList.setModel(new DefaultListModel());
           
            modulesInMinimalWorkspaceList.setCellRenderer(new ListCellRenderer() {
                private final JLabel label = new JLabel();
                private final Font origFont = label.getFont();
                private final Font boldFont = origFont.deriveFont(Font.BOLD);
               
                public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                    Pair<ModuleName, Boolean> p = UnsafeCast.<Pair<ModuleName, Boolean>>unsafeCast(value);
                    ModuleName moduleName = p.fst();
                    boolean isUserSelected = (p.snd()).booleanValue();
                    label.setText(moduleName.toSourceText());
                    if (!list.isEnabled()) {
                        label.setForeground(SystemColor.textInactiveText);
                    } else if (isUserSelected) {
                        label.setForeground(SystemColor.textText);
                        label.setFont(boldFont);
                    } else {
                        label.setForeground(SystemColor.textText);
                        label.setFont(origFont);
                    }
                   
                    return label;
                }
            });
           
            JScrollPane toListScrollPane = new JScrollPane(modulesInMinimalWorkspaceList);
            toListScrollPane.setMinimumSize(listDimension);
            toListScrollPane.setPreferredSize(listDimension);
           
            toListPanel.add(toListScrollPane, BorderLayout.CENTER);

            toListPanel.setBorder(
                BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), GemCutter.getResourceString("CreateMinimalWorkspaceModulesInMinimalWorkspace")));
        }
        this.add(toListPanel);
    }
   
    /**
     * Wraps the specified component with a panel with a empty border of the
     * specified dimensions.
     *
     * @param component the component to be wrapped.
     * @param top an integer specifying the width of the top, in pixels.
     * @param left an integer specifying the width of the left side, in pixels.
     * @param bottom an integer specifying the width of the right side, in pixels.
     * @param right an integer specifying the width of the bottom, in pixels.
     * @return a new panel containing the component.
     */
    private JPanel wrapWithBorder(Component component, int top, int left, int bottom, int right) {
        JPanel panel = new JPanel(new BorderLayout());
        panel.add(component, BorderLayout.CENTER);
        panel.setBorder(BorderFactory.createEmptyBorder(top, left, bottom, right));
        return panel;
    }
   
    /**
     * Updates the list of modules in the minimal workspace.
     */
    private void updateModulesInMinimalWorkspaceList() {
        DefaultListModel model = (DefaultListModel)modulesInMinimalWorkspaceList.getModel();
        model.clear();
       
        CALWorkspace.DependencyFinder depFinder = getDependencyFinder();
       
        List <Pair<ModuleName, Boolean>> items = new ArrayList<Pair<ModuleName, Boolean>>();
       
        SortedSet<ModuleName> rootSet = depFinder.getRootSet();
        SortedSet<ModuleName> importedModulesSet = depFinder.getImportedModulesSet();
       
        for (final ModuleName moduleName : rootSet) {
            items.add(new Pair<ModuleName, Boolean>(moduleName, Boolean.TRUE));
        }
       
        for (final ModuleName moduleName : importedModulesSet) {
            items.add(new Pair<ModuleName, Boolean>(moduleName, Boolean.FALSE));
        }
       
        Collections.sort(items, new Comparator<Pair<ModuleName, Boolean>>() {
            public int compare(Pair<ModuleName, Boolean> a, Pair<ModuleName, Boolean> b) {
                ModuleName aKey = a.fst();
                ModuleName bKey = b.fst();
                return aKey.compareTo(bKey);
            }
        });
       
        for (int i = 0, n = items.size(); i < n; i++) {
            model.addElement(items.get(i));
        }
    }

    /**
     * @return a dependency finder based on the root set specified in {@link #fromList}.
     */
    CALWorkspace.DependencyFinder getDependencyFinder() {
        return workspace.getDependencyFinder(fromList.getCheckedValues());
    }

    /**
     * @return the content of the minimal workspace declaration.
     */
    String getMinimalWorkspaceDeclaration() {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
       
        CALWorkspace.DependencyFinder depFinder = getDependencyFinder();
       
        pw.println("// This CAL workspace declaration file is automatically generated at " + new Date());
       
        pw.println();
        pw.println("// imported modules");
        for (final ModuleName moduleName : depFinder.getImportedModulesSet()) {
            pw.println(getWorkspaceDeclarationLine(moduleName));
        }

        pw.println();
        pw.println("// root modules");
        for (final ModuleName moduleName : depFinder.getRootSet()) {
            pw.println(getWorkspaceDeclarationLine(moduleName));
        }
       
        pw.flush();
       
        return sw.toString();
    }
   
    /**
     * Returns a line for a workspace declaration based on the given module name.
     * @param moduleName
     * @return a line for a workspace declaration.
     */
    private String getWorkspaceDeclarationLine(ModuleName moduleName) {
        VaultElementInfo vaultInfo = workspace.getVaultInfo(moduleName);
        if (vaultInfo instanceof VaultElementInfo.Basic) {
            return ((VaultElementInfo.Basic)vaultInfo).toDeclarationString();
        } else {
            return "StandardVault " + moduleName;
        }
    }
   
    /**
     * {@inheritDoc}
     */
    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
       
        fromList.setEnabled(enabled);
        selectAllButton.setEnabled(enabled);
        deselectAllButton.setEnabled(enabled);
        modulesInMinimalWorkspaceList.setEnabled(enabled);
        modulesInMinimalWorkspaceList.repaint(); // to force the repainting of this list with disabled labels
    }
}
TOP

Related Classes of org.openquark.gems.client.CreateMinimalWorkspacePanel$ListWithCheckBoxes$LabelWithCheckBox

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.