alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.java.tools;

import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.lang.reflect.Modifier;
import java.text.FieldPosition;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.TreeSet;
import javax.swing.SwingUtilities;
import javax.swing.tree.TreePath;
import org.netbeans.api.mdr.MDRepository;
import org.netbeans.jmi.javamodel.ClassDefinition;
import org.netbeans.jmi.javamodel.JavaClass;
import org.netbeans.jmi.javamodel.Method;
import org.netbeans.jmi.javamodel.Parameter;
import org.netbeans.modules.java.ui.nodes.elements.ClassNode;
import org.netbeans.modules.java.ui.nodes.elements.ElementFormat;
import org.netbeans.modules.java.ui.nodes.elements.MethodNode;
import org.netbeans.modules.javacore.internalapi.JMIElementCookie;
import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
import org.openide.ErrorManager;
import org.openide.explorer.ExplorerManager;
import org.openide.explorer.ExplorerPanel;
import org.openide.explorer.view.BeanTreeView;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.nodes.NodeOp;
import org.openide.util.NbBundle;
import org.openide.util.Task;
import org.openide.util.TaskListener;

/**
 *
 * @author  Vitezslav Stejskal
 */
public class OverridePanel2 extends javax.swing.JPanel implements PropertyChangeListener {

    public static final String PROP_VALID = "OverridePanel2.valid"; //NOI18N
    
    private static final Node WAIT_NODE = new WaitNode();
    private static final ClassElementsComparator CLASS_ELEMENTS_COMPARATOR = new ClassElementsComparator();
    private static final MethodElementsComparator METHOD_ELEMENTS_COMPARATOR = new MethodElementsComparator();
    private static final ElementFormat CLASS_ELEMENT_FORMAT = new ElementFormat(NbBundle.getMessage(OverridePanel2.class, "FMT_DefaultClassFormat2")); //NOI18N
    private static final ElementFormat METHOD_ELEMENT_FORMAT = new ElementFormat(NbBundle.getMessage(OverridePanel2.class, "FMT_DefaultMethodFormat2")); //NOI18N
    private static final ElementFormat METHOD_ELEMENT_TOOLTIP1_FORMAT = new ElementFormat(NbBundle.getMessage(OverridePanel2.class, "FMT_DefaultMethodFormat_Tooltip1")); //NOI18N
    private static final ElementFormat METHOD_ELEMENT_TOOLTIP2_FORMAT = new ElementFormat(NbBundle.getMessage(OverridePanel2.class, "FMT_DefaultMethodFormat_Tooltip2")); //NOI18N

    private JMIInheritanceSupport support;
    private HashMap /**/ selection = new HashMap();
    private BeanTreeView view;
    private boolean lastFired;
    
    /** Creates new form OverridePanel2 */
    public OverridePanel2(JMIInheritanceSupport support) {
        this.support = support;
        
        initComponents();
        chkShowClasses.setSelected(false);
        chkSuperCalls.setSelected(true);
        
        view = new BeanTreeView();
        view.setPopupAllowed(false);
        view.setRootVisible(false);
        view.setDefaultActionAllowed(false);
        lblList.setLabelFor(view);
        panel.add(view, BorderLayout.CENTER);
        panel.getExplorerManager().setRootContext(new AbstractNode(new Ch()));
        panel.getExplorerManager().addPropertyChangeListener(this);
        initA11Y();
    }
    
    public Collection getMethods() {
        return selection.values();
    }
    
    public boolean isGenerateSuperCalls() {
        return chkSuperCalls.isSelected();
    }

    public boolean isGenerateJavadoc() {
        return chkJavadoc.isSelected();
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {//GEN-BEGIN:initComponents
        java.awt.GridBagConstraints gridBagConstraints;

        lblTop = new javax.swing.JLabel();
        chkShowClasses = new javax.swing.JCheckBox();
        chkAbstractOnly = new javax.swing.JCheckBox();
        lblList = new javax.swing.JLabel();
        panel = new ExplorerPanel();
        chkSuperCalls = new javax.swing.JCheckBox();
        chkJavadoc = new javax.swing.JCheckBox();

        setLayout(new java.awt.GridBagLayout());

        lblTop.setText(org.openide.util.NbBundle.getBundle(OverridePanel2.class).getString("LBL_OverridePanel2_Top"));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(12, 12, 12, 12);
        add(lblTop, gridBagConstraints);

        chkShowClasses.setText(org.openide.util.NbBundle.getBundle(OverridePanel2.class).getString("LBL_OverridePanel2_ShowClasses"));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 12, 6, 0);
        add(chkShowClasses, gridBagConstraints);

        chkAbstractOnly.setText(org.openide.util.NbBundle.getBundle(OverridePanel2.class).getString("LBL_OverridePanel2_AbstractOnly"));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 6, 6, 12);
        add(chkAbstractOnly, gridBagConstraints);

        lblList.setText(org.openide.util.NbBundle.getMessage(OverridePanel2.class, "LBL_OverridePanel2_View"));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(0, 12, 3, 12);
        add(lblList, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 12, 6, 12);
        add(panel, gridBagConstraints);

        chkSuperCalls.setText(org.openide.util.NbBundle.getBundle(OverridePanel2.class).getString("LBL_OverridePanel2_SuperCalls"));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 12, 12, 0);
        add(chkSuperCalls, gridBagConstraints);

        chkJavadoc.setText(org.openide.util.NbBundle.getBundle(OverridePanel2.class).getString("LBL_OverridePanel2_Javadoc"));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 6, 12, 12);
        add(chkJavadoc, gridBagConstraints);

    }//GEN-END:initComponents
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox chkAbstractOnly;
    private javax.swing.JCheckBox chkJavadoc;
    private javax.swing.JCheckBox chkShowClasses;
    private javax.swing.JCheckBox chkSuperCalls;
    private javax.swing.JLabel lblList;
    private javax.swing.JLabel lblTop;
    private org.openide.explorer.ExplorerPanel panel;
    // End of variables declaration//GEN-END:variables

    private void initA11Y() {
        this.getAccessibleContext().setAccessibleDescription(getString("ACSD_OverridePanel2")); //NOI18N
        chkShowClasses.setMnemonic(getString("CTL_OverridePanel2_ShowClasses").charAt(0)); //NOI18N
        chkShowClasses.getAccessibleContext().setAccessibleDescription(getString("ACSD_OverridePanel2_ShowClasses")); //NOI18N
        chkAbstractOnly.setMnemonic(getString("CTL_OverridePanel2_AbstractOnly").charAt(0)); //NOI18N
        chkAbstractOnly.getAccessibleContext().setAccessibleDescription(getString("ACSD_OverridePanel2_AbstractOnly")); //NOI18N
        chkSuperCalls.setMnemonic(getString("CTL_OverridePanel2_SuperCalls").charAt(0)); //NOI18N
        chkSuperCalls.getAccessibleContext().setAccessibleDescription(getString("ACSD_OverridePanel2_SuperCalls")); //NOI18N
        chkJavadoc.setMnemonic(getString("CTL_OverridePanel2_Javadoc").charAt(0)); //NOI18N
        chkJavadoc.getAccessibleContext().setAccessibleDescription(getString("ACSD_OverridePanel2_Javadoc")); //NOI18N
        lblList.setDisplayedMnemonic(getString("CTL_OverridePanel2_View").charAt(0)); //NOI18N
        view.getAccessibleContext().setAccessibleDescription(getString("ACSD_OverridePanel2_View")); //NOI18N
    }
    
    private static String getString(String key) {
        return NbBundle.getMessage(OverridePanel2.class, key);
    }
    
    public void addNotify() {
        super.addNotify();
        lastFired = !selection.isEmpty();
        firePropertyChange(PROP_VALID, !lastFired, lastFired);
        view.requestFocus();
    }
    
    // ---- PropertyChangeListener implemenetation
    
    public void propertyChange(PropertyChangeEvent evt) {
        if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) {
            Node n[] = panel.getExplorerManager().getSelectedNodes();
            HashMap methods = new HashMap();

            for (int i = 0; i < n.length; i++) {
                Object mte = ((JMIElementCookie) n[i].getCookie(JMIElementCookie.class)).getElement();
                if (mte != null && (mte instanceof Method)) {
                    methods.put(new JMIInheritanceSupport.MethodKey((Method)mte), mte);
                }
            }

            selection = methods;
            
            if (lastFired != !selection.isEmpty()) {
                lastFired = !selection.isEmpty();
                firePropertyChange(PROP_VALID, !lastFired, lastFired);
            }
        }
    }
    
    // ---- private implementation
    
    private Collection computeClasses() {
        ArrayList result = new ArrayList();
        TreeSet ifaces = new TreeSet(CLASS_ELEMENTS_COMPARATOR);

        support.getClasses(result, true, false);
        support.getClasses(ifaces, false, true);
        result.addAll(ifaces);
        
        return result;
    }
    
    private Collection computeMethods(ClassDefinition cle, boolean abstractOnly, boolean deep) {
        TreeSet result = new TreeSet(METHOD_ELEMENTS_COMPARATOR);

        if (deep) {
            return support.getAllMethods(result, abstractOnly);
        } else {
            return support.getMethods(result, cle, abstractOnly);
        }
    }

    private void updateSelection() {
        Node root = panel.getExplorerManager().getRootContext();
        Node ch[] = root.getChildren().getNodes(true);
        ArrayList selectedNodes = new ArrayList();
        
        // expand whole tree 
        view.expandAll();

        // find previously selected nodes
        if (chkShowClasses.isSelected()) {
            for (int i = 0; i < ch.length; i++) {
                Node chch[] = ch[i].getChildren().getNodes(true);
                for (int j = 0; j < chch.length; j++) {
                    Method mte = (Method) ((JMIElementCookie) chch[j].getCookie(JMIElementCookie.class)).getElement();
                    if (mte != null && selection.containsKey(new JMIInheritanceSupport.MethodKey(mte))) {
                        selectedNodes.add(chch[j]);
                    }
                }
            }
        } else {
            for (int i = 0; i < ch.length; i++) {
                Method mte = (Method) ((JMIElementCookie) ch[i].getCookie(JMIElementCookie.class)).getElement();
                if (mte != null && selection.containsKey(new JMIInheritanceSupport.MethodKey(mte))) {
                    selectedNodes.add(ch[i]);
                }
            }
        }
        
        try {
            panel.getExplorerManager().setSelectedNodes((Node []) selectedNodes.toArray(new Node[selectedNodes.size()]));
        } catch (PropertyVetoException e) {
            ErrorManager.getDefault().notify(e);
        }
        
        panel.getExplorerManager().addPropertyChangeListener(this);
    }
    
    private static final class WaitNode extends AbstractNode {
        public WaitNode() {
            super(Children.LEAF);
            setIconBase("org/openide/src/resources/wait"); // NOI18N
            setDisplayName(NbBundle.getMessage(WaitNode.class, "LBL_WaitNode_DisplayName")); //NOI18N
            setName(getClass().getName());
        }
    } // End of WaitNode class
    
    private final class Ch extends Children.Keys implements PropertyChangeListener, ActionListener {
        
        public Ch() {
            support.reset();
        }
        
        protected void addNotify() {
            update();
            chkShowClasses.addActionListener(this);
            chkAbstractOnly.addActionListener(this);
            support.addPropertyChangeListener(this);
        }

        protected void removeNotify() {
            chkShowClasses.removeActionListener(this);
            chkAbstractOnly.removeActionListener(this);
            support.removePropertyChangeListener(this);
            setKeys(Collections.EMPTY_LIST);
        }
        
        protected Node[] createNodes(Object key) {
            if (key instanceof Node) {
                return new Node [] { (Node)key };
            } else if (key instanceof JavaClass) {
                ClassNode node = new ClassNode((JavaClass) key,
                    new ClassElementCh((JavaClass) key), false);
                node.setElementFormat(CLASS_ELEMENT_FORMAT);
                return new Node [] { node };
            } else { // key instanceof MethodElement
                return new Node [] { new MEN((Method) key) };
            }
        }

        // ---- PropertyChangeListener implementation
        
        public void propertyChange(PropertyChangeEvent evt) {
            update();
        }
        
        // ---- ActionListener implementation
        
        public void actionPerformed(java.awt.event.ActionEvent e) {
            if (e.getSource() == chkAbstractOnly && chkShowClasses.isSelected()) {
                return;
            }
            
            update();
        }
        
        // ---- private implementation

        private void update() {
            if (support.isFinished()) {
                panel.getExplorerManager().removePropertyChangeListener(OverridePanel2.this);
                // hot fix, workaround #40491, unselect nodes to avoid IAE (An explored context must be within the root context)
                try {
                    panel.getExplorerManager ().setSelectedNodes (new Node[0]);
                } catch (PropertyVetoException pve) {
                    ErrorManager.getDefault ().notify (ErrorManager.WARNING, pve);
                }

                setKeys(chkShowClasses.isSelected() ? 
                    computeClasses() :
                    computeMethods(support.getRootClass(), chkAbstractOnly.isSelected(), true));
        
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        updateSelection();
                    }
                });
            } else {
                setKeys(new Object [] { WAIT_NODE });
            }
        }
    } // End of Ch class

    private final class ClassElementCh extends Children.Keys implements ActionListener {
        
        private ClassDefinition cle;
        
        public ClassElementCh(ClassDefinition cle) {
            this.cle = cle;
        }

        protected void addNotify() {
            update();
            chkAbstractOnly.addActionListener(this);
        }

        protected void removeNotify() {
            chkAbstractOnly.removeActionListener(this);
            setKeys(Collections.EMPTY_LIST);
        }
        
        protected Node[] createNodes(Object key) {
            // key instanceof MethodElement
            MethodNode node = new MethodNode((Method) key, false);
            node.setElementFormat(METHOD_ELEMENT_FORMAT);
            return new Node [] { node };
        }
        
        // ---- ActionListener
        
        public void actionPerformed(java.awt.event.ActionEvent e) {
            update();
        }
        
        // ---- private implementation
        
        private void update() {
            setKeys(computeMethods(cle, chkAbstractOnly.isSelected(), false));
        }
    } // End of ClassElementCh

    private static class ClassElementsComparator implements Comparator {
        public int compare(Object value1, Object value2) {
            ClassDefinition v1 = (ClassDefinition)value1;
            ClassDefinition v2 = (ClassDefinition)value2;
            
            boolean v1_interf = v1 instanceof JavaClass && ((JavaClass) v1).isInterface();
            boolean v2_interf = v2 instanceof JavaClass && ((JavaClass) v2).isInterface();
            
            if (v1_interf != v2_interf) {
                return v1_interf ? 1 : -1;
            }
            return v1.getName().compareTo(v2.getName());
        }
        
        public boolean equals(Object o) {
            return o instanceof ClassElementsComparator;
        }
    } // End of ClassElementsComparator class

    /** Comparator that orders methods as follows:
     *  1. sorts them in ascending alphabetical order
     *  2. methods with the same name, but less arguments are preceding methods with more arguments
     *  3. methods with the same number of arguments are sorted by their argument declarations
     */
    private static final class MethodElementsComparator implements Comparator {
        public int compare(Object a,Object b) {
            MDRepository repos = JavaMetamodel.getDefaultRepository();
            repos.beginTrans(false);
            try {
                Method ma = (Method)a;
                Method mb = (Method)b;
                int result;

                if (ma == mb)
                    return 0;
                result = ma.getName().compareTo(mb.getName());
                if (result != 0)
                    return result;
                result = ma.getParameters().size() - mb.getParameters().size();
                if (result != 0)
                    return result;
                // compare parameter names/types.
                Iterator iterA = ma.getParameters().iterator();
                Iterator iterB = mb.getParameters().iterator();
                while (iterA.hasNext()) {
                    Parameter parA = (Parameter) iterA.next();
                    Parameter parB = (Parameter) iterB.next();
                    String parAName = parA.getName();
                    String parBName = parB.getName();
                    String sA = parA.getType().getName() + (parAName != null ? " " + parAName : ""); // NOI18N
                    String sB = parB.getType().getName() + (parBName != null ? " " + parBName : ""); // NOI18N
                    result = sB.compareTo(sB);
                    if (result != 0)
                        return result;
                }
                return 0;
            } finally {
                repos.endTrans(false);
            }
        }

        public boolean equals(Object o) {
            return o instanceof MethodElementsComparator;
        }
    } // End of MethodElementsComparator class
    
    public static final class MEN extends MethodNode {
        public MEN(Method m) {
            super(m, false);
            setElementFormat(METHOD_ELEMENT_FORMAT);
        }
        
        public String getShortDescription() {
            StringBuffer buff = new StringBuffer();
            
            METHOD_ELEMENT_TOOLTIP1_FORMAT.format(element, buff, new FieldPosition(0));
            buff.append(" "); //NOI18N
            buff.append(((Method)element).getDeclaringClass().getName());
            buff.append("."); //NOI18N
            METHOD_ELEMENT_TOOLTIP2_FORMAT.format(element, buff, new FieldPosition(0));
            
            return buff.toString();
        }
    } // End of MEN class
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.