content: package aliview.sequencelist;
  
  
  import javax.accessibility.AccessibleContext;
  import javax.swing.*;
  import javax.swing.event.*;
  import javax.swing.plaf.basic.BasicHTML;
  import javax.swing.plaf.basic.BasicLabelUI;
  import javax.swing.text.View;
  import javax.swing.border.*;
  
  import org.apache.log4j.Logger;
  
  import aliview.alignment.Alignment;
  
  import java.awt.Component;
  import java.awt.Color;
  import java.awt.Dimension;
  import java.awt.Font;
  import java.awt.FontMetrics;
  import java.awt.Graphics;
  import java.awt.Graphics2D;
  import java.awt.Rectangle;
  import java.awt.RenderingHints;
  import java.awt.Toolkit;
  import java.awt.image.BufferedImage;
  
  import java.io.Serializable;
  import java.util.Map;
  
  
  
  /**
   *
   *  Extended version of the DefaultCellRenderer
   *
   */
  public class FasterTextCellRenderer extends JLabel
  implements ListCellRenderer, Serializable
  {
  
  	private static final Logger logger = Logger.getLogger(FasterTextCellRenderer.class);
  
  	/**
  	 * An empty <code>Border</code>. This field might not be used. To change the
  	 * <code>Border</code> used by this renderer override the 
  	 * <code>getListCellRendererComponent</code> method and set the border
  	 * of the returned component directly.
  	 */
  	private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
  	private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
  	protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER;
  	private String text;
  	//private static BufferedImage buffImg;
  	private boolean selected;
  
  	private static final int LEFT_OFFSET = 2;
  
  
  	/**
  	 * Constructs a default renderer object for an item
  	 * in a list.
  	 */
  	public FasterTextCellRenderer(){
  		super();
  		/*
      		if(buffImg == null){
      			createStaticBuffImg();
      		}*/
  
  		setBorder(getNoFocusBorder());
  		setName("List.cellRenderer");
  	}
  
  	/*
      private void createStaticBuffImg() {
      	buffImg = new BufferedImage(200, 12, BufferedImage.TYPE_INT_ARGB);
  		Graphics2D g2 = buffImg.createGraphics();
  
  		g2.setColor(Color.green);
  		g2.fillRect(0, 0, 100, 10);
  		g2.setColor(Color.black);
  		g2.setFont(new Font("Monospace", Font.PLAIN, 11));
  		g2.drawString("BuffImgGraphics", 2, 10);
  		g2.dispose();
  	}
  	 */
  
  	private Border getNoFocusBorder() {
  
  		return DEFAULT_NO_FOCUS_BORDER;
  		/*
          Border border = DefaultLookup.getBorder(this, ui, "List.cellNoFocusBorder");
          if (System.getSecurityManager() != null) {
              if (border != null) return border;
              return SAFE_NO_FOCUS_BORDER;
          } else {
              if (border != null &&
                      (noFocusBorder == null ||
                      noFocusBorder == DEFAULT_NO_FOCUS_BORDER)) {
                  return border;
              }
              return noFocusBorder;
          }
  		 */
  	}
  
  	/** 
  	 * Return the renderers fixed size here.  
  	 */
  
  	public Dimension getPreferredSize() {
  		return new Dimension(10, 5);
  	}
  
  	/**
  	 * Completely bypass all of the standard JComponent painting machinery.
  	 * This is a special case: the renderer is guaranteed to be opaque,
  	 * it has no children, and it's only a child of the JList while
  	 * it's being used to rubber stamp cells.
  	 * <p>
  	 * Clear the background and then draw the text.
  	 */
  	public void paint(Graphics g) {
  
  		Graphics2D g2 = (Graphics2D) g;
  
  		//	g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
  		//	g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);	
  
  		if(this.getHeight() > 8){
  			setPlatformDefaultRenderingHints(g2);
  		}
  		else{
  			g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
  		}
  
  		// if not selected - default transp background
  		if(selected){
  			g2.setColor(getBackground());
  			g2.fillRect(0, 0, getWidth(), getHeight());
  		}
  
  		g2.setFont(this.getFont());
  		g2.setColor(getForeground());
  		//	logger.info(buffImg);
  		//	g2.drawImage(buffImg, 0,0, null);
  
  		// 	SwingUtilities2.drawString(this, g, text, 2, this.getHeight() - bottomCharOffset);
  
  		int bottomCharOffset = (int)(0.2 * this.getHeight());
  		g2.drawString(text, LEFT_OFFSET, getHeight() - bottomCharOffset);
  
  	}
  
  
  	private void setPlatformDefaultRenderingHints(Graphics2D g2){
  		try{
  			Map pdefaults =	(Map)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
  			Object aaHint  = pdefaults.get(RenderingHints.KEY_TEXT_ANTIALIASING);
  			if(aaHint != null){
  				g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, aaHint);
  			}else{
  				g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
  			}
  			Object lcdHint  = pdefaults.get(RenderingHints.KEY_TEXT_LCD_CONTRAST);
  			if(lcdHint != null){
  				g2.setRenderingHint(RenderingHints.KEY_TEXT_LCD_CONTRAST, lcdHint);
  			}
  
  		}catch(Exception exc){
  			exc.printStackTrace();
  		}	
  	}
  
  	/* This is is the ListCellRenderer method.  It just sets
  	 * the foreground and background properties and updates the
  	 * local text field.
  	 */
  	public Component getListCellRendererComponent(
  			JList list,
  			Object value,
  			int index,
  			boolean isSelected,
  			boolean cellHasFocus) 
  	{
  		if (isSelected) {
  			setBackground(list.getSelectionBackground());
  			setForeground(list.getSelectionForeground());
  		}
  		else {
  			setBackground(list.getBackground());
  			setForeground(list.getForeground());
  		}
  		this.selected = isSelected;
  		this.setFont(list.getFont());
  		this.text = value.toString();
  
  		return this;
  	}
  
  	public String getText() {
  		return this.text;
  	}
  
  	public void setText(String text) {
  
  		String oldAccessibleName = null;
  		if (accessibleContext != null) {
  			oldAccessibleName = accessibleContext.getAccessibleName();
  		}
  
  		String oldValue = this.text;
  		this.text = text;
  		firePropertyChange("text", oldValue, text);
  
  		//        setDisplayedMnemonicIndex(
  		//                      SwingUtilities.findDisplayedMnemonicIndex(
  		//                                          text, getDisplayedMnemonic()));
  
  		if ((accessibleContext != null) 
  				&& (accessibleContext.getAccessibleName() != oldAccessibleName)) {
  			accessibleContext.firePropertyChange(
  					AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, 
  					oldAccessibleName,
  					accessibleContext.getAccessibleName());
  		}
  		if (text == null || oldValue == null || !text.equals(oldValue)) {
  			revalidate();
  			repaint();
  		}
  	}
  
  	/**
  	 * Overridden for performance reasons.
  	 * See the <a href="#override">Implementation Note</a> 
  	 * for more information.
  	 *
  	 * @since 1.5
  	 * @return <code>true</code> if the background is completely opaque
  	 *         and differs from the JList's background;
  	 *         <code>false</code> otherwise
  	 */
  	@Override
  	public boolean isOpaque() {
  		return selected;
  
  		/*
  
  	Color back = getBackground();
  	Component p = getParent(); 
  	if (p != null) { 
  	    p = p.getParent(); 
  	}
  	// p should now be the JList. 
  	boolean colorMatch = (back != null) && (p != null) && 
  	    back.equals(p.getBackground()) && 
  			p.isOpaque();
  	return !colorMatch && super.isOpaque(); 
      }
  		 */
  
  	}
  
  	/**
  	 * Overridden for performance reasons.
  	 * See the <a href="#override">Implementation Note</a>
  	 * for more information.
  	 */
  	@Override
  	public void validate() {}
  
  	/**
  	 * Overridden for performance reasons.
  	 * See the <a href="#override">Implementation Note</a>
  	 * for more information.
  	 *
  	 * @since 1.5
  	 */
  	@Override
  	public void invalidate() {}
  
  	/**
  	 * Overridden for performance reasons.
  	 * See the <a href="#override">Implementation Note</a>
  	 * for more information.
  	 *
  	 * @since 1.5
  	 */
  	@Override
  	public void repaint() {}
  
  	/**
  	 * Overridden for performance reasons.
  	 * See the <a href="#override">Implementation Note</a>
  	 * for more information.
  	 */
  	@Override
  	public void revalidate() {}
  	/**
  	 * Overridden for performance reasons.
  	 * See the <a href="#override">Implementation Note</a>
  	 * for more information.
  	 */
  	@Override
  	public void repaint(long tm, int x, int y, int width, int height) {}
  
  	/**
  	 * Overridden for performance reasons.
  	 * See the <a href="#override">Implementation Note</a>
  	 * for more information.
  	 */
  	@Override
  	public void repaint(Rectangle r) {}
  
  	/**
  	 * Overridden for performance reasons.
  	 * See the <a href="#override">Implementation Note</a>
  	 * for more information.
  	 */
  	@Override
  	protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
  		// Strings get interned...
  		if (propertyName == "text"
  				|| ((propertyName == "font" || propertyName == "foreground")
  						&& oldValue != newValue
  						&& getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey) != null)) {
  
  			super.firePropertyChange(propertyName, oldValue, newValue);
  		}
  	}
  
  	/**
  	 * Overridden for performance reasons.
  	 * See the <a href="#override">Implementation Note</a>
  	 * for more information.
  	 */
  	@Override
  	public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {}
  
  	/**
  	 * Overridden for performance reasons.
  	 * See the <a href="#override">Implementation Note</a>
  	 * for more information.
  	 */
  	@Override
  	public void firePropertyChange(String propertyName, char oldValue, char newValue) {}
  
  	/**
  	 * Overridden for performance reasons.
  	 * See the <a href="#override">Implementation Note</a>
  	 * for more information.
  	 */
  	@Override
  	public void firePropertyChange(String propertyName, short oldValue, short newValue) {}
  
  	/**
  	 * Overridden for performance reasons.
  	 * See the <a href="#override">Implementation Note</a>
  	 * for more information.
  	 */
  	@Override
  	public void firePropertyChange(String propertyName, int oldValue, int newValue) {}
  
  	/**
  	 * Overridden for performance reasons.
  	 * See the <a href="#override">Implementation Note</a>
  	 * for more information.
  	 */
  	@Override
  	public void firePropertyChange(String propertyName, long oldValue, long newValue) {}
  
  	/**
  	 * Overridden for performance reasons.
  	 * See the <a href="#override">Implementation Note</a>
  	 * for more information.
  	 */
  	@Override
  	public void firePropertyChange(String propertyName, float oldValue, float newValue) {}
  
  	/**
  	 * Overridden for performance reasons.
  	 * See the <a href="#override">Implementation Note</a>
  	 * for more information.
  	 */
  	@Override
  	public void firePropertyChange(String propertyName, double oldValue, double newValue) {}
  
  	/**
  	 * Overridden for performance reasons.
  	 * See the <a href="#override">Implementation Note</a>
  	 * for more information.
  	 */
  	@Override
  	public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}
  
  }
  