⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 checkablecellrenderer.java

📁 ktable 是一个由java开发的,对控制报表的项目,它最大的特点是使用独特的算法,能支持巨大的报表(千万以上?).
💻 JAVA
字号:
/*
 * Copyright (C) 2004 by Friederich Kupzog Elektronik & Software
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html

Authors: 
Lorenz Maierhofer, lorenz.maierhofer@logicmindguide.com

*/
package de.kupzog.ktable.renderers;

import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;

import de.kupzog.ktable.KTableModel;
import de.kupzog.ktable.SWTX;

/**
 * Cell renderer that expects a Boolean as content of a cell.
 * It then represents the value by a checked or unchecked box.
 * <p>
 * It accepts the following style bits:
 * <ul>
 * <li><b>INDICATION_CLICK</b> shows a visible feedback when the
 * user clicks the cell. This feedback resprects the checked state.</li>
 * <li><b>INDICATION_FOCUS</b> causes the cell that has focus to be 
 * drawn with another background color and a focus-style border.</li>
 * <li><b>INDICATION_FOCUS_ROW</b> causes the cell that has focus to be 
 * drawn in a dark color and its content bright.</li>
 * <li><b>INDICATION_COMMENT</b> makes the renderer paint a little
 * triangle in the upper right corner of the cell as a sign that 
 * additional information is available.</li>
 * <li><b>SIGN_IMAGE</b> forces the drawing of images that are defined in 
 * the icon folder. This makes the rendering of a cell 2-3 times slower. Overwrites
 * all other SIGN_* style bits.</li>
 * <li><b>SIGN_X</b> makes the 'true' symbol be an X. This is only valid if SIGN_IMAGE
 * is not given, and it overwrites SIGN_CHECK</li>
 * <li><b>SIGN_CHECK</b> makes the 'true' symbol a check. THIS IS DEFAULT.</li>
 * </ul>
 * 
 * @see de.kupzog.ktable.editors.KTableCellEditorCheckbox
 * @see de.kupzog.ktable.editors.KTableCellEditorCheckbox2
 * 
 * @author Lorenz Maierhofer <lorenz.maierhofer@logicmindguide.com>
 */
public class CheckableCellRenderer extends DefaultCellRenderer {
    
    /** 
     * Style bit that forces that the renderer paints images 
     * instead of directly painting. The images used for painting
     * can be found in the folder /icons/ and are named 
     * checked.gif, unchecked.gif, checked_clicked.gif and unchecked_clicked.gif.
     * <p>
     * Note that when using images, drawing is 2-3 times slower than when 
     * using direct painting. It might be visible if many cells should be 
     * rendered that way. So this is not default.
     */ 
    public static final int SIGN_IMAGE = 1<<31;
    
    /**
     * Makes the renderer draw an X as the symbol that signals the value
     * is true. This has only an effect if the style SIGN_IMAGE is not active.
     */
    public static final int SIGN_X = 1<<30;
    /**
     * Makes the renterer draw a check sign as the symbol that signals the value
     * true. THIS IS DEFAULT.
     */
    public static final int SIGN_CHECK = 1<<29;
    
    /** Indicator for a checked entry / true boolean decision */
    public static final Image IMAGE_CHECKED = SWTX.loadImageResource(
            Display.getCurrent(), 
    		"/icons/checked.gif");
    
    /** Indicator for an unchecked entry / false boolean decision */
    public static final Image IMAGE_UNCHECKED = SWTX.loadImageResource(
            Display.getCurrent(), 
    		"/icons/unchecked.gif");
    
    /** Indicator for an checked entry / true boolean decision that is currently clicked.*/
    public static final Image IMAGE_CHECKED_CLICKED = SWTX.loadImageResource(
            Display.getCurrent(), 
    		"/icons/checked_clicked.gif");
    
    /** Indicator for an unchecked entry / false boolean decision that is currently clicked.*/
    public static final Image IMAGE_UNCHECKED_CLICKED = SWTX.loadImageResource(
            Display.getCurrent(), 
    		"/icons/unchecked_clicked.gif");
    
    public static final Color COLOR_FILL = new Color(Display.getDefault(), 206, 206, 206);
    public static final Color BORDER_DARK = new Color(Display.getDefault(), 90, 90, 57);
    public static final Color BORDER_LIGHT = new Color(Display.getDefault(), 156, 156, 123);

    /**
     * Creates a cellrenderer that shows boolean values with the given style.<p>
     * @param style 
     * Honored style bits are:<br>
     * - INDICATION_CLICKED<br>
     * - INDICATION_FOCUS<br>
     * - INDICATION_FOCUS_ROW<br>
     * - INDICATION_COMMENT<p>
     * Styles that influence the sign painted when cell value is true:<br>
     * - SIGN_IMAGE<br>
     * - SIGN_X<br>
     * - SIGN_CHECK (default)<br>
     */
    public CheckableCellRenderer(int style) {
        super(style);
    }
    
    /* (non-Javadoc)
     * @see de.kupzog.ktable.KTableCellRenderer#getOptimalWidth(org.eclipse.swt.graphics.GC, int, int, java.lang.Object, boolean)
     */
    public int getOptimalWidth(GC gc, int col, int row, Object content, boolean fixed, KTableModel model) {
        return IMAGE_CHECKED.getBounds().x + 6;
    }
    
    /** 
     * Paint a box with or without a checked symbol.
     * 
     * @see de.kupzog.ktable.KTableCellRenderer#drawCell(GC, Rectangle, int, int, Object, boolean, boolean, boolean, KTableModel)
     */
    public void drawCell(GC gc, Rectangle rect, int col, int row, Object content, 
            boolean focus, boolean fixed, boolean clicked, KTableModel model) {
        
        // draw focus sign:
        if (focus && (m_Style & INDICATION_FOCUS)!=0) {
            rect = drawDefaultSolidCellLine(gc, rect, COLOR_LINE_LIGHTGRAY, COLOR_LINE_LIGHTGRAY);
            drawCheckableImage(gc, rect, content, COLOR_BGFOCUS, clicked);
            gc.drawFocus(rect.x, rect.y, rect.width, rect.height);
            
        } else if (focus && (m_Style & INDICATION_FOCUS_ROW)!=0) {
        
            rect = drawDefaultSolidCellLine(gc, rect, COLOR_BGROWFOCUS, COLOR_BGROWFOCUS);
            drawCheckableImage(gc, rect, content, COLOR_BGROWFOCUS, clicked);
            
        } else {
            rect = drawDefaultSolidCellLine(gc, rect, COLOR_LINE_LIGHTGRAY, COLOR_LINE_LIGHTGRAY);
            drawCheckableImage(gc, rect, content, getBackground(), clicked);
        }
        
        if ((m_Style & INDICATION_COMMENT)!=0)
            drawCommentSign(gc, rect);
    }
    
    /**
     * This method is responsible for calling the actual paint method.
     * Note that there currently exist two versions: 
     * One that uses the images defined in this renderer, and anotherone
     * painting directly.<p> 
     * NOTE: Default is drawing directly (no images used) because this seems
     * to be at least 2-3 times faster than painting an image! (tested: WinXP)
     */
    protected void drawCheckableImage(GC gc, Rectangle rect, Object content, Color bgColor, boolean clicked) {
        // draw content as image:
        if ((m_Style & SIGN_IMAGE)!=0) {
            if (!(content instanceof Boolean)) {
                if (content.toString().equalsIgnoreCase("true"))
                    content = new Boolean(true);
                else if (content.toString().equalsIgnoreCase("false"))
                    content = new Boolean(false);
            }
            if (!(content instanceof Boolean))
                drawCellContent(gc, rect, "?", null, getForeground(), bgColor);
            else {
                boolean checked = ((Boolean)content).booleanValue();
                if (checked) {
                    if (clicked && (m_Style & INDICATION_CLICKED)!=0)
                        drawImage(gc, rect, IMAGE_CHECKED_CLICKED, bgColor);
                    else
                        drawImage(gc, rect, IMAGE_CHECKED, bgColor);
                }
                else {
                    if (clicked && (m_Style & INDICATION_CLICKED)!=0)
                        drawImage(gc, rect, IMAGE_UNCHECKED_CLICKED, bgColor);
                    else
                        drawImage(gc, rect, IMAGE_UNCHECKED, bgColor);
                }
            }
        }
        else { // draw image directly:
            if (!(content instanceof Boolean)) {
                if (content.toString().equalsIgnoreCase("true"))
                    content = new Boolean(true);
                else if (content.toString().equalsIgnoreCase("false"))
                    content = new Boolean(false);
            }
            if (!(content instanceof Boolean))
                drawCellContent(gc, rect, "?", null, getForeground(), bgColor);
            else { 
                boolean checked = ((Boolean)content).booleanValue();
                if (clicked && (m_Style & INDICATION_CLICKED)!=0)
                    drawCheckedSymbol(gc, rect, checked, bgColor, COLOR_FILL);
                else
                    drawCheckedSymbol(gc, rect, checked, bgColor, bgColor);
            }
        }
    }
    
    /**
     * 
     * @param gc
     * @param rect
     * @param image
     * @param backgroundColor
     */
    protected void drawImage(GC gc, Rectangle rect, Image image, Color backgroundColor) {
        gc.setBackground(backgroundColor);
        gc.setForeground(backgroundColor);
        gc.fillRectangle(rect);
        SWTX.drawTextImage(gc, "", getAlignment(), 
                image, getAlignment(), rect.x + 3, rect.y,
                rect.width - 3, rect.height);
    }
    
    /**
     * @param value If true, the comment sign is painted. 
     * Else it is omitted.
     */
	public void setCommentIndication(boolean value) {
	    if (value)
	        m_Style = m_Style | INDICATION_COMMENT;
	    else 
	        m_Style = m_Style & ~INDICATION_COMMENT;
	}
	/**
	 * Manually paints the checked or unchecked symbol. This provides a fast replacement
	 * for the variant that paints the images defined in this class. <p>
	 * The reason for this is that painting manually is 2-3 times faster than painting the
	 * image - which is very notable if you have a completely filled table! (see example!)
	 * @param gc The GC to use when dawing
	 * @param rect The cell ara where the symbol should be painted into.
	 * @param checked Wether the symbol should be the checked or unchecked
	 * @param bgColor The background color of the cell.
	 * @param fillColor The color of the box drawn (with of without checked mark). Used
	 * when a click indication is desired.
	 */
	protected void drawCheckedSymbol(GC gc, Rectangle rect, boolean checked, Color bgColor, Color fillColor) {
	    // clear background:
	    gc.setBackground(bgColor);
	    gc.fillRectangle(rect);
	    
	    //paint rectangle: 
	    Rectangle bound = getAlignedLocation(rect, IMAGE_CHECKED);
	    
	    gc.setForeground(BORDER_LIGHT);
	    gc.drawLine(bound.x, bound.y, bound.x+bound.width, bound.y);
	    gc.drawLine(bound.x, bound.y, bound.x, bound.y+bound.height);
	    gc.setForeground(BORDER_DARK);
	    gc.drawLine(bound.x+bound.width, bound.y+1, bound.x+bound.width, bound.y+bound.height-1);
	    gc.drawLine(bound.x, bound.y+bound.height, bound.x+bound.width, bound.y+bound.height);
	    
	    if (!bgColor.equals(fillColor)) {
	        gc.setBackground(fillColor);
	        gc.fillRectangle(bound.x+1, bound.y+1, bound.width-1, bound.height-1);
	    }
	    
	    if (checked) // draw a check symbol:	        
	        drawCheckSymbol(gc, bound);
	}
	
	/**
	 * Draws a X as a sign that the cell value is true.
     * @param gc The gc to use when painting
     * @param bound
     */
    private void drawCheckSymbol(GC gc, Rectangle bound) {
        if ((m_Style & SIGN_X)!=0) { // Draw a X
            gc.setForeground(BORDER_LIGHT);
            
            gc.drawLine(bound.x+3, bound.y+2, bound.x-2+bound.width, bound.y-3+bound.height);
            gc.drawLine(bound.x+2, bound.y+3, bound.x-3+bound.width, bound.y-2+bound.height);
            
            gc.drawLine(bound.x+3, bound.y-2+bound.height, bound.x-2+bound.width, bound.y+3);
            gc.drawLine(bound.x+2, bound.y-3+bound.height, bound.x-3+bound.width, bound.y+2);
            
            gc.setForeground(COLOR_TEXT);
            
            gc.drawLine(bound.x+2, bound.y+2, bound.x-2+bound.width, bound.y-2+bound.height);
            gc.drawLine(bound.x+2, bound.y-2+bound.height, bound.x-2+bound.width, bound.y+2);
        } else { // Draw a check sign
            gc.setForeground(getForeground());
            
            gc.drawLine(bound.x+2, bound.y+bound.height-4, bound.x+4, bound.y+bound.height-2);
            gc.drawLine(bound.x+2, bound.y+bound.height-5, bound.x+5, bound.y+bound.height-3);
            gc.drawLine(bound.x+2, bound.y+bound.height-6, bound.x+4, bound.y+bound.height-4);
            
            for (int i=1; i<4; i++)
                gc.drawLine(bound.x+2+i, bound.y+bound.height-3, bound.x+bound.width-2, bound.y+1+i);
        }
    }

    /**
	 * Returns the location where the checked symbol should be painted.<p>
	 * Note that this is only a subarea of the area covered by an image, since
	 * the image contains a border area that is not needed here.
	 * @param rect The cell area
	 * @param img The image to take the size of the checked symbol from.
	 * @return Returns the area that should be filled with a checked/unchecked symbol.
	 */
	protected Rectangle getAlignedLocation(Rectangle rect, Image img) {
	    Rectangle bounds = img.getBounds();
	    bounds.x-=2;
	    bounds.y-=2;
	    bounds.height-=4;
	    bounds.width-=4;
	    
	    if ((getAlignment() & SWTX.ALIGN_HORIZONTAL_CENTER)!=0)
	        bounds.x = rect.x+(rect.width-bounds.width)/2;
	    else if ((getAlignment() & SWTX.ALIGN_HORIZONTAL_RIGHT)!=0)
	        bounds.x = rect.x+rect.width-bounds.width-2;
	    else
	        bounds.x = rect.x+2;
	    
	    if ((getAlignment() & SWTX.ALIGN_VERTICAL_CENTER)!=0)
	        bounds.y = rect.y+(rect.height-bounds.height)/2;
	    else if ((getAlignment() & SWTX.ALIGN_VERTICAL_BOTTOM)!=0)
	        bounds.y = rect.y+rect.height-bounds.height-2;
	    else
	        bounds.y = rect.y+2;
	    
	    return bounds;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -