package org.chesmapper.view.gui.table;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.net.URI;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
import org.chesmapper.map.dataInterface.CompoundProperty;
import org.chesmapper.map.main.Settings;
import org.chesmapper.view.cluster.ClusterController;
import org.chesmapper.view.cluster.Clustering;
import org.chesmapper.view.gui.ViewControler;
import org.chesmapper.view.gui.swing.ComponentFactory;
import org.mg.javalib.gui.BlockableFrame;
import org.mg.javalib.gui.LinkButton;
import com.jgoodies.forms.factories.ButtonBarFactory;
public abstract class DataTable extends BlockableFrame
{
protected ViewControler viewControler;
protected ClusterController clusterControler;
protected Clustering clustering;
protected List<CompoundProperty> props;
protected JTable table;
protected DefaultTableModel tableModel;
protected TableRowSorter<DefaultTableModel> sorter;
protected boolean selfUpdate;
public DataTable(ViewControler viewControler, ClusterController clusterControler, Clustering clustering)
{
this(viewControler, clusterControler, clustering, null);
}
public DataTable(ViewControler viewControler, ClusterController clusterControler, Clustering clustering,
List<CompoundProperty> props)
{
super(true);
this.viewControler = viewControler;
this.clustering = clustering;
this.clusterControler = clusterControler;
this.props = props;
tableModel = createTableModel();
table = createTable();
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
int width = 0;
for (int i = 0; i < table.getColumnCount(); i++)
width += Math.min(300, ComponentFactory.packColumn(table, i, 5, 150));
JScrollPane scroll = new JScrollPane(table);
setTitle(Settings.text(getShortName() + ".title"));
JPanel p = new JPanel(new BorderLayout(10, 10));
JPanel pp = new JPanel(new BorderLayout());
pp.add(new JLabel("<html>" + Settings.text(getShortName() + ".info") + "</html>"), BorderLayout.NORTH);
if (addSpecificityInfo())
{
LinkButton l = new LinkButton("Next to each feature value, the specificity of the " + getItemName()
+ " feature values is given in brackets.");
l.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
try
{
Desktop.getDesktop().browse(new URI(Settings.HOMEPAGE_SPECIFICITY));
}
catch (Exception ex)
{
Settings.LOGGER.error(ex);
}
}
});
l.setForegroundFont(l.getFont().deriveFont(Font.PLAIN));
l.setSelectedForegroundFont(l.getFont().deriveFont(Font.PLAIN));
l.setSelectedForegroundColor(Color.BLUE);
pp.add(l, BorderLayout.SOUTH);
}
// String additional = "";
// if (addSpecificityInfo())
// additional = "<br>In brackets: the specificity of the " + getItemName() + " feature value <a href=\""
// + Settings.HOMEPAGE_SPECIFICITY + "\">more</a>";
p.add(pp, BorderLayout.NORTH);
p.add(scroll);
JButton close = new JButton("Close");
close.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
DataTable.this.setVisible(false);
}
});
JButton copy = new JButton("Copy table to clipboard");
copy.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
StringBuffer sbf = new StringBuffer();
for (int j = 0; j < table.getColumnCount(); j++)
{
sbf.append("\"");
sbf.append(table.getColumnName(j));
sbf.append("\"");
if (j < table.getColumnCount() - 1)
sbf.append(";");
}
sbf.append("\n");
for (int i = 0; i < table.getRowCount(); i++)
{
for (int j = 0; j < table.getColumnCount(); j++)
{
sbf.append("\"");
sbf.append(table.getValueAt(i, j));
sbf.append("\"");
if (j < table.getColumnCount() - 1)
sbf.append(";");
}
sbf.append("\n");
}
StringSelection s = new StringSelection(sbf.toString());
Clipboard system = Toolkit.getDefaultToolkit().getSystemClipboard();
system.setContents(s, s);
}
});
JPanel buttons = ButtonBarFactory.buildOKHelpBar(close, copy);
p.add(buttons, BorderLayout.SOUTH);
p.setBorder(new EmptyBorder(10, 10, 10, 10));
getContentPane().add(p);
pack();
pack();
int scrollBarSize = ((Integer) UIManager.get("ScrollBar.width")).intValue();
setSize(new Dimension(Math.max(buttons.getPreferredSize().width + 20,
Math.min(Settings.TOP_LEVEL_FRAME.getWidth() * 3 / 4, width + 20 + scrollBarSize + 2)), getHeight()));
setLocationRelativeTo(Settings.TOP_LEVEL_FRAME);
setVisible(true);
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
table.requestFocus();
}
});
}
protected abstract String getItemName();
protected abstract boolean addSpecificityInfo();
protected abstract DefaultTableModel createTableModel();
protected abstract JTable createTable();
protected abstract String getShortName();
private void addListeners()
{
((BlockableFrame) Settings.TOP_LEVEL_FRAME).addPropertyChangeListener(new PropertyChangeListener()
{
@Override
public void propertyChange(PropertyChangeEvent evt)
{
if (!isVisible())
return;
if (BlockableFrame.BLOCKED.equals(evt.getPropertyName()))
block(evt.getNewValue().toString());
else if (BlockableFrame.UN_BLOCKED.equals(evt.getPropertyName()))
unblock(evt.getNewValue().toString());
}
});
Settings.TOP_LEVEL_FRAME.addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent e)
{
if (!isVisible())
return;
setVisible(false);
}
});
clustering.addListener(new PropertyChangeListener()
{
@Override
public void propertyChange(PropertyChangeEvent evt)
{
if (!isVisible())
return;
setVisible(false);
}
});
}
}