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) {}
}