| /* |
| * Copyright (c) 2009, Tony Kohar. All Rights Reserved. |
| * |
| * 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 org.apache.zest.envisage.tree; |
| |
| import java.awt.BorderLayout; |
| import java.awt.CardLayout; |
| import java.awt.GridBagConstraints; |
| import java.awt.Insets; |
| import java.awt.event.ItemEvent; |
| import java.awt.event.ItemListener; |
| import java.util.ResourceBundle; |
| import javax.swing.BorderFactory; |
| import javax.swing.DefaultComboBoxModel; |
| import javax.swing.JComboBox; |
| import javax.swing.JLabel; |
| import javax.swing.JPanel; |
| import javax.swing.JScrollPane; |
| import javax.swing.JTree; |
| import javax.swing.event.TreeSelectionEvent; |
| import javax.swing.event.TreeSelectionListener; |
| import javax.swing.tree.*; |
| import org.apache.zest.tools.model.descriptor.ApplicationDetailDescriptor; |
| |
| /** |
| * Application Model View as Swing Component. |
| * It support 2 view: |
| * <pre><code> |
| * - by Structure |
| * - by Type |
| * </code></pre> |
| */ |
| public final class TreeModelPane |
| extends JPanel |
| { |
| private static final String STRUCTURE_VIEW = "Structure"; |
| private static final String TYPE_VIEW = "Type"; |
| |
| private static final ResourceBundle BUNDLE = ResourceBundle.getBundle( TreeModelPane.class.getName() ); |
| |
| private JPanel mainPane; |
| private CardLayout cardLayout; |
| private JTree structureTree; |
| private JTree typeTree; |
| private JComboBox viewAsCombo; |
| |
| private boolean selectionInProgress; |
| |
| public TreeModelPane() |
| { |
| setLayout( new BorderLayout() ); |
| |
| // init mainPane |
| structureTree = new JTree(); |
| structureTree.setRootVisible( false ); |
| structureTree.setShowsRootHandles( true ); |
| structureTree.setExpandsSelectedPaths( true ); |
| structureTree.setScrollsOnExpand( true ); |
| structureTree.setName( STRUCTURE_VIEW ); |
| structureTree.setCellRenderer( new TreeModelCellRenderer() ); |
| |
| typeTree = new JTree(); |
| typeTree.setRootVisible( false ); |
| typeTree.setShowsRootHandles( true ); |
| typeTree.setExpandsSelectedPaths( true ); |
| typeTree.setScrollsOnExpand( true ); |
| typeTree.setName( TYPE_VIEW ); |
| typeTree.setCellRenderer( new TreeModelCellRenderer() ); |
| |
| mainPane = new JPanel(); |
| cardLayout = new CardLayout(); |
| mainPane.setLayout( cardLayout ); |
| mainPane.add( new JScrollPane( structureTree ), STRUCTURE_VIEW ); |
| mainPane.add( new JScrollPane( typeTree ), TYPE_VIEW ); |
| add( mainPane, BorderLayout.CENTER ); |
| |
| // init viewAsCombo |
| JPanel viewAsPane = new JPanel(); |
| viewAsPane.setBorder( BorderFactory.createEmptyBorder( 3, 6, 3, 0 ) ); |
| viewAsPane.setLayout( new java.awt.GridBagLayout() ); |
| |
| GridBagConstraints gridBagConstraints; |
| JLabel viewAsLabel = new JLabel( BUNDLE.getString( "CTL_ViewAs.Text" ) ); |
| gridBagConstraints = new GridBagConstraints(); |
| gridBagConstraints.anchor = GridBagConstraints.WEST; |
| gridBagConstraints.insets = new Insets( 0, 0, 0, 6 ); |
| viewAsPane.add( viewAsLabel, gridBagConstraints ); |
| |
| viewAsCombo = new JComboBox( new DefaultComboBoxModel( new String[] |
| { |
| STRUCTURE_VIEW, TYPE_VIEW |
| } ) ); |
| gridBagConstraints = new GridBagConstraints(); |
| gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; |
| gridBagConstraints.weightx = 1.0; |
| viewAsPane.add( viewAsCombo, gridBagConstraints ); |
| |
| viewAsCombo.addItemListener( new ItemListener() |
| { |
| @Override |
| public void itemStateChanged( ItemEvent evt ) |
| { |
| if( evt.getStateChange() == ItemEvent.DESELECTED ) |
| { |
| return; |
| } |
| cardLayout.show( mainPane, evt.getItem().toString() ); |
| repaint(); |
| } |
| } ); |
| |
| add( viewAsPane, BorderLayout.PAGE_START ); |
| } |
| |
| /** |
| * Initialize Qi4J for this component |
| * |
| * @param descriptor the Application descriptor |
| */ |
| public void initQi4J( ApplicationDetailDescriptor descriptor ) |
| { |
| // traverse the model and build JTree representation |
| MutableTreeNode rootNode1 = StructureModelBuilder.build( descriptor ); |
| MutableTreeNode rootNode2 = TypeModelBuilder.build( descriptor ); |
| |
| structureTree.setModel( new DefaultTreeModel( rootNode1 ) ); |
| typeTree.setModel( new DefaultTreeModel( rootNode2 ) ); |
| |
| structureTree.addTreeSelectionListener( new TreeSelectionListener() |
| { |
| @Override |
| public void valueChanged( TreeSelectionEvent evt ) |
| { |
| structureTreeValueChanged(); |
| } |
| } ); |
| |
| typeTree.addTreeSelectionListener( new TreeSelectionListener() |
| { |
| @Override |
| public void valueChanged( TreeSelectionEvent evt ) |
| { |
| typeTreeValueChanged(); |
| } |
| } ); |
| } |
| |
| public Object getLastSelected() |
| { |
| Object obj = structureTree.getLastSelectedPathComponent(); |
| if( obj != null ) |
| { |
| return ( (DefaultMutableTreeNode) obj ).getUserObject(); |
| } |
| return null; |
| } |
| |
| public void setSelectedValue( Object obj ) |
| { |
| if( obj == null ) |
| { |
| return; |
| } |
| |
| TreeNode node = findNode( structureTree, obj ); |
| if( node != null ) |
| { |
| DefaultTreeModel treeModel = (DefaultTreeModel) structureTree.getModel(); |
| TreePath treePath = new TreePath( treeModel.getPathToRoot( node ) ); |
| structureTree.setSelectionPath( treePath ); |
| structureTree.scrollPathToVisible( treePath ); |
| } |
| else |
| { |
| structureTree.clearSelection(); |
| } |
| } |
| |
| /** |
| * Just a helper method to find the node which contains the userObject |
| * |
| * @param tree the JTree to search into |
| * @param object the user object |
| * |
| * @return TreeNode or null |
| */ |
| protected TreeNode findNode( JTree tree, Object object ) |
| { |
| DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getModel().getRoot(); |
| return findNode( node, object ); |
| } |
| |
| /** |
| * Recurvice search or find node that contains the obj |
| * |
| * @param node DefaultMutableTreeNode |
| * @param obj userObject |
| * |
| * @return TreeNode or null if could not find |
| */ |
| private TreeNode findNode( DefaultMutableTreeNode node, Object obj ) |
| { |
| if( obj instanceof String ) |
| { |
| if( node.getUserObject().toString().equals( obj.toString() ) ) |
| { |
| return node; |
| } |
| } |
| else if( node.getUserObject().equals( obj ) ) |
| { |
| return node; |
| } |
| |
| TreeNode foundNode = null; |
| for( int i = 0; i < node.getChildCount(); i++ ) |
| { |
| DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) node.getChildAt( i ); |
| foundNode = findNode( childNode, obj ); |
| if( foundNode != null ) |
| { |
| break; |
| } |
| } |
| |
| return foundNode; |
| } |
| |
| public final void addTreeSelectionListener( TreeSelectionListener listener ) |
| { |
| structureTree.addTreeSelectionListener( listener ); |
| } |
| |
| public final void removeTreeSelectionListener( TreeSelectionListener listener ) |
| { |
| structureTree.removeTreeSelectionListener( listener ); |
| } |
| |
| protected void structureTreeValueChanged() |
| { |
| if( selectionInProgress ) |
| { |
| return; |
| } |
| |
| Object userObject = getLastSelected(); |
| if( userObject == null ) |
| { |
| return; |
| } |
| TreeNode node = findNode( typeTree, userObject ); |
| if( node != null ) |
| { |
| DefaultTreeModel treeModel = (DefaultTreeModel) typeTree.getModel(); |
| TreePath treePath = new TreePath( treeModel.getPathToRoot( node ) ); |
| typeTree.setSelectionPath( treePath ); |
| typeTree.scrollPathToVisible( treePath ); |
| } |
| } |
| |
| protected void typeTreeValueChanged() |
| { |
| Object obj = typeTree.getLastSelectedPathComponent(); |
| if( obj == null ) |
| { |
| return; |
| } |
| Object userObject = ( (DefaultMutableTreeNode) obj ).getUserObject(); |
| TreeNode node = findNode( structureTree, userObject ); |
| if( node != null ) |
| { |
| DefaultTreeModel treeModel = (DefaultTreeModel) structureTree.getModel(); |
| TreePath treePath = new TreePath( treeModel.getPathToRoot( node ) ); |
| |
| selectionInProgress = true; |
| try |
| { |
| structureTree.setSelectionPath( treePath ); |
| } |
| finally |
| { |
| selectionInProgress = false; |
| } |
| structureTree.scrollPathToVisible( treePath ); |
| } |
| } |
| } |