/*
* EuroCarbDB, a framework for carbohydrate bioinformatics
*
* Copyright (c) 2006-2009, Eurocarb project, or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
* A copy of this license accompanies this distribution in the file LICENSE.txt.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* Last commit: $Rev: 1210 $ by $Author: glycoslave $ on $Date:: 2009-06-12 #$
*/
/**
@author Alessio Ceroni (a.ceroni@imperial.ac.uk)
*/
package org.eurocarbdb.application.glycoworkbench.plugin;
import org.eurocarbdb.application.glycanbuilder.*;
import org.eurocarbdb.application.glycoworkbench.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.print.*;
import java.text.DecimalFormat;
import java.text.MessageFormat;
public class GlycanTable extends ResizingTable implements SVGUtils.Renderable, Printable, MouseListener {
protected JPopupMenu thePopupMenu;
protected GlycanRenderer theGlycanRenderer;
protected DecimalFormat df_fourdigits;
protected DecimalFormat df_twodigits;
protected double glycan_scale = 0.5;
protected double glycans_vector_scale = 0.4;
protected boolean use_styled_text = true;
protected boolean show_redend = true;
protected boolean is_printing;
protected HashSet<Glycan> magnified;
protected Vector<ActionListener> action_listeners = new Vector<ActionListener>();
// printing
Glycan header_structure = null;
Printable table_printable = null;
public GlycanTable() {
super();
// init members
thePopupMenu = null;
theGlycanRenderer = new GlycanRenderer();
df_fourdigits = new DecimalFormat("0.0000");
df_twodigits = new DecimalFormat("0.00");
is_printing = false;
magnified = new HashSet<Glycan>();
// set aspect
setRowSelectionAllowed(true);
setColumnSelectionAllowed(false);
setShowVerticalLines(false);
// set renderers
getTableHeader().setDefaultRenderer(new MultiLineHeaderRenderer(theGlycanRenderer));
setDefaultRenderer(Vector.class, new DefaultTableCellRenderer() {
private static final long serialVersionUID = 0L;
public void setValue(Object value) {
setIcon(new ImageIcon(theGlycanRenderer.getImage((Vector<Glycan>)value,false,false,show_redend,glycans_vector_scale)));
}
});
setDefaultRenderer(Glycan.class, new DefaultTableCellRenderer() {
private static final long serialVersionUID = 0L;
public void setValue(Object value) {
if( (magnified.contains((Glycan)value) && !is_printing) )
setIcon(new ImageIcon(theGlycanRenderer.getImage((Glycan)value,false,false,show_redend,1.)));
else
setIcon(new ImageIcon(theGlycanRenderer.getImage((Glycan)value,false,false,show_redend,glycan_scale)));
}
});
if( use_styled_text )
setDefaultRenderer(String.class, new StyledTextCellRenderer());
else
setDefaultRenderer(String.class, new DefaultTableCellRenderer());
setDefaultRenderer(Integer.class, new DefaultTableCellRenderer() {
private static final long serialVersionUID = 0L;
public void setValue(Object value) {
if( value!=null )
setText(((Integer)value).toString());
else
setText("");
}
});
setDefaultRenderer(Double.class, new DefaultTableCellRenderer() {
private static final long serialVersionUID = 0L;
public void setValue(Object value) {
if( value!=null )
setText(df_fourdigits.format(((Double)value).doubleValue()));
else
setText("");
}
});
// add listeners
addMouseListener( this );
}
public void setShowRedend(boolean f) {
show_redend = f;
}
public boolean getShowRedend() {
return show_redend;
}
public void setGlycanScale(double val) {
glycan_scale = val;
}
public double getGlycanScale() {
return glycan_scale;
}
public void setGlycansVectorScale(double val) {
glycans_vector_scale = val;
}
public double getGlycansVectorScale() {
return glycans_vector_scale;
}
public void setUseStyledText(boolean f) {
use_styled_text = f;
if( use_styled_text )
setDefaultRenderer(String.class, new StyledTextCellRenderer());
else
setDefaultRenderer(String.class, new DefaultTableCellRenderer());
}
public boolean getUseStyledText() {
return use_styled_text;
}
public void setPopupMenu(JPopupMenu menu) {
thePopupMenu = menu;
}
public JPopupMenu getPopupMenu() {
return thePopupMenu;
}
public void setGlycanRenderer(GlycanRenderer r) {
theGlycanRenderer = r;
getTableHeader().setDefaultRenderer(new MultiLineHeaderRenderer(theGlycanRenderer));
}
public GlycanRenderer getGlycanRenderer() {
return theGlycanRenderer;
}
public void beforeRendering() {
is_printing = true;
}
public void afterRendering() {
is_printing = false;
}
public Dimension getRenderableSize() {
return new Dimension(this.getWidth(),this.getHeight()+this.getTableHeader().getHeight());
}
public void paintRenderable(Graphics2D g2d) {
JTableHeader tableHeader = getTableHeader();
tableHeader.paint(g2d);
g2d.translate(0, tableHeader.getHeight());
super.paint(g2d);
}
public void print(PrinterJob pj) {
print(pj,null);
}
public void print(PrinterJob pj, Glycan _header_structure ) {
if( pj==null )
return;
try {
header_structure = _header_structure;
table_printable = getPrintable(JTable.PrintMode.FIT_WIDTH,null,new MessageFormat("{0}"));
pj.setPrintable(this);
if( pj.printDialog() ) {
is_printing = true;
pj.print();
is_printing = false;
}
}
catch(Exception e) {
LogUtils.report(e);
}
}
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
if( pageIndex==0 ) {
// print structure
Image struct_img = theGlycanRenderer.getImage(header_structure,false,true,true,1.);
Graphics2D g2d = (Graphics2D)graphics;
java.awt.geom.AffineTransform old_transform = g2d.getTransform();
g2d.setBackground(Color.white);
//Dimension td = theStructure.getPreferredSize();
Dimension td = new Dimension(struct_img.getWidth(null),struct_img.getHeight(null));
double s_width = td.width;
double s_height = td.height;
double sx = pageFormat.getImageableWidth()/td.width;
double sy = pageFormat.getImageableHeight()/td.height;
double s = Math.min(sx,sy);
if( s<1. ) {
s_width *= s;
s_height *= s;
struct_img = theGlycanRenderer.getImage(header_structure,false,true,true,s);
}
int left_margin = (int)((pageFormat.getImageableWidth() - s_width)/2);
g2d.translate(pageFormat.getImageableX()+left_margin, pageFormat.getImageableY());
g2d.drawImage(struct_img,null,null);
g2d.setTransform(old_transform);
// print table after structure
return table_printable.print(graphics,new OffsetPageFormat(pageFormat,(int)(s_height+20)),pageIndex);
}
else
return table_printable.print(graphics,pageFormat,pageIndex);
}
private void showPopup(MouseEvent e) {
if( thePopupMenu!=null ) {
int row = rowAtPoint(e.getPoint());
int column = columnAtPoint(e.getPoint());
if( !isRowSelected(row) )
setRowSelectionInterval(row,row);
else
addRowSelectionInterval(row,row);
addColumnSelectionInterval(column,column);
thePopupMenu.show(this, e.getX(), e.getY());
}
}
public void mousePressed(MouseEvent e) {
if( MouseUtils.isPopupTrigger(e) )
showPopup(e);
}
public void mouseReleased(MouseEvent e) {
if( MouseUtils.isPopupTrigger(e) )
showPopup(e);
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
if( MouseUtils.isActionTrigger(e) ) {
// zoom structure if any
int row = rowAtPoint(e.getPoint());
int col = columnAtPoint(e.getPoint());
Object value = getValueAt(row,col);
if( value instanceof Glycan ) {
// zoom toggle
if( magnified.contains((Glycan)value) )
magnified.remove((Glycan)value);
else
magnified.add((Glycan)value);
// update view
updateDimensions(row,row);
// reselect row
addRowSelectionInterval(row,row);
}
else {
for( ActionListener al : action_listeners )
al.actionPerformed(new ActionEvent(this,0,"tableaction"));
}
}
}
public void tableChanged(TableModelEvent e) {
super.tableChanged(e);
if( (e.getFirstRow()==TableModelEvent.HEADER_ROW || e.getLastRow()==Integer.MAX_VALUE) && magnified!=null)
magnified.clear();
if( e.getFirstRow()==TableModelEvent.HEADER_ROW ) {
// the renderer has to be set for each column otherwise
// the size is not correctly computed
Enumeration<TableColumn> columns = getColumnModel().getColumns();
while( columns.hasMoreElements() )
columns.nextElement().setHeaderRenderer(getTableHeader().getDefaultRenderer());
}
}
public void addActionListener(ActionListener al) {
if( al!=null )
action_listeners.add(al);
}
public void removeActionListener(ActionListener al) {
if( al!=null && action_listeners.contains(al) )
action_listeners.remove(al);
}
// -------
public Data getSelectedData() {
Data rows = new Data();
// set data header
for( int c = 0; c<getColumnCount(); c++ )
rows.add(getColumnName(c));
rows.newRow();
// set data rows
int[] sel_ind = getSelectedRows();
for( int i=0; i<sel_ind.length; i++ ) {
int r = sel_ind[i];
for( int c = 0; c<getColumnCount(); c++ ) {
Object o =getValueAt(r,c);
if( o instanceof Glycan )
rows.add(theGlycanRenderer.makeCompositionText((Glycan)o,false));
else if( o instanceof Vector ) {
StringBuilder sb = new StringBuilder();
for( Glycan g : (Vector<Glycan>)o ) {
if( sb.length()>0 )
sb.append(",");
sb.append(theGlycanRenderer.makeCompositionText(g,false));
}
rows.add(sb.toString());
}
else
rows.add(o);
}
rows.newRow();
}
return rows;
}
}
class OffsetPageFormat extends PageFormat {
protected int offset = 0;
protected PageFormat base_object = null;
public OffsetPageFormat(PageFormat bo, int off) {
base_object = bo;
offset = off;
}
public Object clone() {
return new OffsetPageFormat((PageFormat)base_object.clone(),offset);
}
public double getHeight() {
return base_object.getHeight();
}
public double getImageableHeight() {
return base_object.getImageableHeight()-offset;
}
public double getImageableWidth() {
return base_object.getImageableWidth();
}
public double getImageableX() {
return base_object.getImageableX();
}
public double getImageableY() {
return base_object.getImageableY() + offset;
}
public double[] getMatrix() {
return base_object.getMatrix();
}
public int getOrientation() {
return base_object.getOrientation();
}
public Paper getPaper() {
return base_object.getPaper();
}
public double getWidth() {
return base_object.getWidth();
}
public void setOrientation(int orientation) {
base_object.setOrientation(orientation);
}
public void setPaper(Paper paper) {
base_object.setPaper(paper);
}
}