Package DisplayProject.table

Source Code of DisplayProject.table.AlignedCellRenderer

/*
Copyright (c) 2003-2009 ITerative Consulting Pty Ltd. All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:

o Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
 
o 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.
   
o This jcTOOL Helper Class software, whether in binary or source form may not be used within,
or to derive, any other product without the specific prior written permission of the copyright holder

 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "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.


*/
package DisplayProject.table;


import java.awt.Component;
import java.awt.Insets;
import java.lang.reflect.Method;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JTable;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableModel;

import DisplayProject.AlphaBlendedIcon;
import DisplayProject.DisplayNode;
import DisplayProject.controls.ListViewTable;
import Framework.ImageData;

/**
* This class provides alignment for columns in a JTable.  Specifically, columns transformed from a ListView may be Left or Right aligned.
* @author Peter
*/
public class AlignedCellRenderer extends DefaultTableCellRenderer {

    private static final float BLENDED_ICON_TRANSPARENCY = 0.5f; // Selected icon blend transparency level [0.0f -> 1.0f]
    private String methodName = null;
    private boolean iconSupported = false;

    private static final int ICON_WIDTH = 16, ICON_HEIGHT = 16// icon dimensions
    // A 16x16 transparent GIF icon
    private static final byte[] transparentGIF16x16 = new byte[] {
        0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x10, 0x00, 0x10, 0x00, (byte)0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x21, (byte)0xf9, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00,
        0x10, 0x00, 0x10, 0x00, 0x00, 0x02, 0x0e, (byte)0x84, (byte)0x8f, (byte)0xa9, (byte)0xcb, (byte)0xed, (byte)0x0f, (byte)0xa3, (byte)0x9c, (byte)0xb4,
        (byte)0xda, (byte)0x8b, (byte)0xb3, 0x3e, 0x05, 0x00, 0x3b
    };
    private static final Icon invisibleIcon = new ImageIcon(transparentGIF16x16);

    /**
     * The insets is the amount of extra space to place around a particular cell
     */
    protected Insets insets = new Insets(0,0,0,0);

    /**
     *
     */
    private static final long serialVersionUID = -1170477221571516814L;

    public AlignedCellRenderer() {
        super();
    }

    public AlignedCellRenderer(int Alignment) {
        this();
        setHorizontalAlignment(Alignment);
    }

    /**
     * Use this contructor when displaying an icon.  The methodName parameter specifies the method to be called to get the text.
     */
    public AlignedCellRenderer(int Alignment, String methodName) {
        this(Alignment);
        this.methodName = methodName;
        iconSupported = true;
    }

    /**
     * Set the spacing around the cell renderer
     * @param insets
     */
    public void setInsets(Insets insets) {
        this.insets = insets;
    }

    /**
     * Set the spacing around the cell renderer
     */
    public void setInsets(int top, int left, int bottom, int right) {
        this.insets.top = top;
        this.insets.left = left;
        this.insets.bottom = bottom;
        this.insets.right = right;
    }

    /**
     * Scan the first column to see if it contains any icons.  This is done for alignment of rows that don't contain icon, that are mixed in with rows that do.
     * @param table
     * @return boolean indicating if the column has an icon
     */
    private boolean hasIconInColumn1(JTable table) {
        boolean _Result = false;
        TableModel model = table.getModel();
        int rows = model.getRowCount();

        for (int i=0; i<rows; i++) {
            Object item = model.getValueAt(i, 0);

            if (item != null && item instanceof DisplayNode) {
                if (((DisplayNode)item).getDVSmallIcon() != null || ((DisplayNode)item).getDVSelectedIcon() != null) {
                    _Result = true;
                    break;
                }
            }
        }

        return _Result;
    }

    protected static Class<?>[] emptyClassList = new Class[0];

    /**
     * Return a method that matches the passed property on the passed class. This includes private members. Note that
     * this method does not support nested properties, however, it does support either property names or full method
     * names (for getters only) being passed in.
     * @param pClass
     * @param pProperty
     * @return Returns {@link java.lang.reflect.Method}
     */
    protected static Method findMethod(Class<?> pClass, String pProperty) throws NoSuchMethodException {
        // First, correct the property into the correct method name
        String methodName = pProperty;
        if (!methodName.startsWith("get")) {
            if (Character.isUpperCase(pProperty.charAt(0))) {
                methodName = "get" +  pProperty;
            }
            else {
                methodName = "get" + Character.toUpperCase(pProperty.charAt(0)) + pProperty.substring(1);
            }
        }
        if (methodName.endsWith("()")) {
            methodName = methodName.substring(0, methodName.length() - 2);
        }
        try {
            return pClass.getDeclaredMethod(methodName, emptyClassList);
        }
        catch (NoSuchMethodException nsme) {
            return pClass.getMethod(methodName, emptyClassList);
        }
    }

    /**
     * Run pMethod on pObj which can be a series of methods seperated by pSeperator.
     * Eg: If  pObj = myObj
     *       pMethod = details__contact__name
     *       pSeperator = __
     * Then, this would return  myObj.getDetails().getContact().getName();
     *
     * @param pObj
     * @param pMethod
     * @param pSeperator
     * @throws Exception
     */
    public static Object expressionExecute(Object pObj, String pMethod, String pSeperator) throws Exception {
        String methodStr = pMethod;
        int index = methodStr.indexOf(pSeperator);
        Object currentObject = pObj;

        // If the method is actually a series of methods, go through them one by one.  CraigM. 23/05/2007
        while (index > 0) {
            String currentMethod = methodStr.substring(0, index);
            methodStr = methodStr.substring(index+pSeperator.length());
            Method method = findMethod(currentObject.getClass(), currentMethod);
            method.setAccessible(true);
            currentObject = method.invoke(currentObject, (Object [])null);
            index = methodStr.indexOf(pSeperator);
        }
        Method method = findMethod(currentObject.getClass(), methodStr);
        method.setAccessible(true);
        return method.invoke(currentObject, (Object [])null);
    }

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

        // Add whitespace to left and right of columns
        renderer.setBorder(new EmptyBorder(insets.top, insets.left + (iconSupported ? 0 : 8), insets.bottom, insets.right + 8));

        // Set the correct colours.  CraigM 27/11/2007
        // TF:05/05/2009:Corrected these dependent upon the hasRowHighlights property of a ListViewTable
        boolean ignoreSelection = (table instanceof ListViewTable) && (!((ListViewTable)table).getHasRowHighlights());
        if (isSelected && !ignoreSelection) {
            if (table.hasFocus()) {
                renderer.setBackground(table.getSelectionBackground());
                renderer.setForeground(table.getSelectionForeground());
            }
            else {
                renderer.setBackground(java.awt.Color.lightGray);
                renderer.setForeground(java.awt.Color.black);
            }
        }
        else {
            renderer.setBackground(table.getBackground());
            renderer.setForeground(table.getForeground());
        }

        // Display icon if defined for this column
        if(value instanceof DisplayNode) {
            try {
                // Get the real value via reflection. This will either be the text of
                // the object or an image data. The first case (text) will be when this
                // is column 0 in the array and we need to use the icon image with the
                // retrieved text, and the second case will be when there is an explicitly
                // mapped image associated with this column.
                //Object objValue = AlignedCellRenderer.expressionExecute(value, this.methodName, "().");
                Object objValue = AlignedCellRenderer.expressionExecute(value, this.methodName, ".");

                int iconHeight = 0;
                if (objValue != null && objValue instanceof ImageData) {
                    // This is a column defined as an image, it can contain no text
                    ImageData id = (ImageData)objValue;
                    renderer.setIcon(id.asScaledIconImage(ICON_WIDTH, ICON_HEIGHT));
                    iconHeight = ICON_HEIGHT;
                }
                else {
                    // display icon
                    // TF:24/7/07: In Forte, if there was no selected icon, the small icon would display, even if selected.
                    Icon icon = null;
                    ImageData image = ((DisplayNode)value).getDVSmallIcon();
                    // COLET 20/01/2009 : Check if the selected image is valid by checking isNull(). If its empty, use the small icon. This is what Forte did.
                    ImageData selectedImage = ((DisplayNode)value).getDVSelectedIcon();
                    if (isSelected && selectedImage != null && !selectedImage.isNull()) {
                        image = selectedImage;
                    }

                    // We have an icon
                    if(image != null) {
                        icon = image.asScaledIconImage(ICON_WIDTH, ICON_HEIGHT);
                        iconHeight = ICON_HEIGHT;
                    }

                    // We don't have an icon and we are the left column, however, some other row does, so pad the space with an invisible image.
                    else if (column == 0 && this.hasIconInColumn1(table)) {
                        icon = invisibleIcon;
                    }
                   
                    //COLET 20/01/2009 : Add some shading to the icon. Forte would have the icon painted like this.
                    //                   By default, Java wont paint the background colour over the icon. Lets mimic Forte.
                    if(icon != null && isSelected) {
                      icon = new AlphaBlendedIcon(icon, getBackground(), BLENDED_ICON_TRANSPARENCY);
                    }
                   
                    renderer.setIcon(icon);

                    if(objValue != null) {
                        renderer.setText(objValue.toString());

                        // If we don't have an icon and we are the left most column, pad the space.
                        if (icon == null && column == 0) {
                            renderer.setText(" " + renderer.getText());
                        }

                        // The column sorts by comparing DVNodeText on the display node,
                        // so this should be set using the displayed text
//                        DisplayNode node = (DisplayNode)value;
//                        TextData td = node.getDVNodeText();
//                        if(td == null || td.toString() == null || td.toString().length() == 0
//                            || !objValue.toString().equals(td.toString())) {
//                            node.setDVNodeText(objValue.toString());
//                        }
                    }
                }

                // set row height sufficient for icon
                int currentHeight = table.getRowHeight();
                int newHeight = Math.max(iconHeight, currentHeight);
                if(newHeight != currentHeight) {
                    table.setRowHeight(newHeight);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        else {
            renderer.setIcon(null);
        }

        // Don't have a completely blank cell, as this will cause the row highlighting to not work.  CraigM 14/09/2007.
        if (renderer.getIcon() == null && renderer.getText().length() == 0) {
            renderer.setText(" ");
        }
        return renderer;
    }

    public boolean isIconSupported() {
        return iconSupported;
    }

    public void setIconSupported(boolean iconSupported) {
        this.iconSupported = iconSupported;
    }
}
TOP

Related Classes of DisplayProject.table.AlignedCellRenderer

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.