/* Copyright 2009 Tonny Kohar. * * 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.qi4j.envisage.detail; import java.awt.*; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; import java.util.ResourceBundle; import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableColumnModel; import org.qi4j.api.util.Classes; import org.qi4j.envisage.util.TableRow; import org.qi4j.tools.model.descriptor.*; import org.qi4j.tools.model.util.DescriptorUtilities; import static org.qi4j.functional.Iterables.first; /** * Implementation of Composite Method Panel */ public class MethodPane extends DetailPane { protected ResourceBundle bundle = ResourceBundle.getBundle( this.getClass().getName() ); private JPanel contentPane; private JList methodList; private JTable methodDetailTable; private JSplitPane splitPane; private DefaultListModel methodListModel; private MethodDetailTableModel methodDetailTableModel; public MethodPane( DetailModelPane detailModelPane ) { super( detailModelPane ); this.setLayout( new BorderLayout() ); this.add( contentPane, BorderLayout.CENTER ); methodListModel = new DefaultListModel(); methodList.setModel( methodListModel ); methodList.setCellRenderer( new MethodListCellRenderer() ); methodList.setPrototypeCellValue( "12345678901234567890" ); methodList.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); methodDetailTableModel = new MethodDetailTableModel(); methodDetailTable.setModel( methodDetailTableModel ); TableColumnModel columnModel = methodDetailTable.getColumnModel(); columnModel.getColumn( 0 ).setPreferredWidth( 75 ); columnModel.getColumn( 1 ).setPreferredWidth( 400 ); //splitPane.setResizeWeight( .1 ); //splitPane.setDividerLocation( .3 ); methodList.addListSelectionListener( new ListSelectionListener() { @Override public void valueChanged( ListSelectionEvent evt ) { methodListValueChanged( evt ); } } ); } @Override public void setDescriptor( Object objectDesciptor ) { clear(); if( objectDesciptor instanceof CompositeDetailDescriptor ) { CompositeDetailDescriptor descriptor = ( (CompositeDetailDescriptor) objectDesciptor ); List<CompositeMethodDetailDescriptor> list = DescriptorUtilities.findMethod( descriptor ); for( CompositeMethodDetailDescriptor methodDescriptor : list ) { methodListModel.addElement( methodDescriptor ); } if( !methodListModel.isEmpty() ) { methodList.setSelectedIndex( 0 ); } } else if( objectDesciptor instanceof ObjectDetailDescriptor ) { // Object does not have methods } } protected void clear() { methodListModel.clear(); methodDetailTableModel.clear(); } private void methodListValueChanged( ListSelectionEvent evt ) { if( evt.getValueIsAdjusting() ) { return; } Object obj = methodList.getSelectedValue(); if( obj == null ) { methodDetailTableModel.clear(); return; } methodDetailTableModel.reload( (CompositeMethodDetailDescriptor) obj ); } { // GUI initializer generated by IntelliJ IDEA GUI Designer // >>> IMPORTANT!! <<< // DO NOT EDIT OR ADD ANY CODE HERE! $$$setupUI$$$(); } /** * Method generated by IntelliJ IDEA GUI Designer * >>> IMPORTANT!! <<< * DO NOT edit this method OR call it in your code! * */ private void $$$setupUI$$$() { contentPane = new JPanel(); contentPane.setLayout( new BorderLayout( 0, 0 ) ); splitPane = new JSplitPane(); contentPane.add( splitPane, BorderLayout.CENTER ); final JScrollPane scrollPane1 = new JScrollPane(); splitPane.setLeftComponent( scrollPane1 ); methodList = new JList(); scrollPane1.setViewportView( methodList ); final JScrollPane scrollPane2 = new JScrollPane(); splitPane.setRightComponent( scrollPane2 ); methodDetailTable = new JTable(); scrollPane2.setViewportView( methodDetailTable ); } public JComponent $$$getRootComponent$$$() { return contentPane; } class MethodDetailTableModel extends AbstractTableModel { /** * the column names for this model */ //protected String[] columnNames = { bundle.getString( "Name.Column" ), bundle.getString( "Value.Column" ) }; protected String[] columnNames = { "Name", "Value" }; protected ArrayList<TableRow> rows; public MethodDetailTableModel() { rows = new ArrayList<TableRow>(); } public void reload( CompositeMethodDetailDescriptor descriptor ) { Method method = descriptor.descriptor().method(); clear(); // mixin type rows.add( new TableRow( 2, new Object[]{ "return", Classes.simpleGenericNameOf( method.getGenericReturnType() ) } ) ); // method StringBuilder parameters = new StringBuilder(); for (int idx = 0; idx < method.getGenericParameterTypes().length; idx++) { Type type = method.getGenericParameterTypes()[idx]; Annotation[] annotations = method.getParameterAnnotations()[idx]; if (parameters.length() > 0) parameters.append(", "); for (Annotation annotation : annotations) { String ann = annotation.toString(); ann = "@"+ann.substring( ann.lastIndexOf('.' )+1); parameters.append( ann ).append( " " ); } parameters.append( Classes.simpleGenericNameOf( type )); } rows.add( new TableRow( 2, new Object[]{ "parameters", parameters.toString() } ) ); // concern boolean first = true; for( MethodConcernDetailDescriptor concern : descriptor.concerns().concerns() ) { if( first ) { rows.add( new TableRow( 2, new Object[]{ "concern", concern.descriptor().modifierClass().getSimpleName() } ) ); first = false; } else { rows.add( new TableRow( 2, new Object[]{ "", concern.descriptor().modifierClass().getSimpleName() } ) ); } } // sideEffect first = false; for( MethodSideEffectDetailDescriptor sideEffect : descriptor.sideEffects().sideEffects() ) { if( first ) { rows.add( new TableRow( 2, new Object[]{ "sideEffect", sideEffect.descriptor().modifierClass().getSimpleName() } ) ); first = false; } else { rows.add( new TableRow( 2, new Object[]{ "", sideEffect.descriptor().modifierClass().getSimpleName() } ) ); } } fireTableDataChanged(); } @Override public Object getValueAt( int rowIndex, int columnIndex ) { TableRow row = this.rows.get( rowIndex ); return row.get( columnIndex ); } public void clear() { rows.clear(); fireTableDataChanged(); } @Override public int getColumnCount() { return columnNames.length; } @Override public String getColumnName( int col ) { return columnNames[ col ]; } @Override public int getRowCount() { return rows.size(); } } class MethodListCellRenderer extends DefaultListCellRenderer { protected Icon publicIcon; protected Icon privateIcon; public MethodListCellRenderer() { try { publicIcon = new ImageIcon( getClass().getResource( bundle.getString( "ICON_Public" ) ) ); privateIcon = new ImageIcon( getClass().getResource( bundle.getString( "ICON_Private" ) ) ); } catch( Exception ex ) { throw new RuntimeException( ex ); } } @Override public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus ) { super.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus ); if( !( value instanceof CompositeMethodDetailDescriptor ) ) { return this; } Icon icon = null; CompositeMethodDetailDescriptor descriptor = (CompositeMethodDetailDescriptor) value; Class compositeClass = first( descriptor.composite().descriptor().types() ); Class mixinMethodClass = descriptor.descriptor().method().getDeclaringClass(); if( mixinMethodClass.isAssignableFrom( compositeClass ) ) { icon = publicIcon; } else { icon = privateIcon; } if( icon != null ) { setIcon( icon ); } return this; } } }