package com.towel.swing.table.headerpopup;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JToggleButton;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.EventListenerList;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
/**
* @author Vinicius Godoy
*/
public class TableHeaderPopup
{
protected EventListenerList listenerList = new EventListenerList();
private JTableHeader header = null;
protected List<HeaderPopup> popups = null;
private TableModel model = null;
private int selected = -1;
private Map<Integer, Boolean> modified;
public TableHeaderPopup(JTableHeader header, TableModel model)
{
this.header = header;
this.model = model;
this.modified = new HashMap<Integer, Boolean>();
createPopups();
modifyHeader();
}
private void createPopups()
{
popups = new ArrayList<HeaderPopup>();
for (int i = 0; i < model.getColumnCount(); i++)
{
HeaderPopup headerPopup = new HeaderPopup(header, i);
headerPopup.addPopupMenuListener(new PopupMenuListener()
{
public void popupMenuCanceled(PopupMenuEvent e)
{
selected = -1;
header.invalidate();
header.repaint();
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
{
selected = -1;
header.invalidate();
header.repaint();
}
public void popupMenuWillBecomeVisible(PopupMenuEvent e)
{
header.invalidate();
header.repaint();
}
});
popups.add(headerPopup);
}
}
public void modifyHeader()
{
if (header.getDefaultRenderer() instanceof FilteredHeaderRenderer)
{
header.setDefaultRenderer(new FilteredHeaderRenderer(
((FilteredHeaderRenderer)header.getDefaultRenderer()).getRenderer()));
}
else
{
header.setDefaultRenderer(new FilteredHeaderRenderer(
header.getDefaultRenderer()));
}
header.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
if (e.getButton() == MouseEvent.BUTTON1)
{
int columnIndex = header.columnAtPoint(e.getPoint());
if (columnIndex == -1)
return;
int modelIndex = header.getColumnModel().getColumn(
columnIndex).getModelIndex();
if (popups.get(modelIndex).isEmpty())
return;
Rectangle rect = header.getHeaderRect(columnIndex);
rect.x = rect.x + rect.width - 17;
rect.width = 16;
rect.y = rect.y + rect.height - 17;
rect.height = 16;
if (!rect.contains(e.getPoint()))
return;
fireHeaderButtonClicked(modelIndex);
popups.get(modelIndex).show(columnIndex);
selected = columnIndex;
}
}
});
}
private class FilteredHeaderRenderer implements TableCellRenderer
{
private TableCellRenderer renderer;
public FilteredHeaderRenderer(TableCellRenderer renderer)
{
this.renderer = renderer;
}
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column)
{
Component c = renderer.getTableCellRendererComponent(table, value,
isSelected, hasFocus, row, column);
if (!(c instanceof JLabel))
return c;
int modelIndex = header.getColumnModel().getColumn(column).getModelIndex();
if (popups.get(modelIndex).isEmpty())
return c;
JLabel label = (JLabel) c;
GridBagConstraints gridBagConstraints = new GridBagConstraints();
gridBagConstraints.weightx = 1.0;
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
panel.add(c, gridBagConstraints);
JToggleButton button = new JToggleButton();
if (modified.get(modelIndex) == null || !modified.get(modelIndex))
button.setIcon(new ImageIcon(getClass().getResource(
"/res/gui/down.gif")));
else
button.setIcon(new ImageIcon(getClass().getResource(
"/res/gui/down_red.gif")));
button.setPreferredSize(new Dimension(16, 16));
button.setMaximumSize(new Dimension(16, 16));
button.setMinimumSize(new Dimension(16, 16));
button.setFocusable(false);
button.setSelected(column == selected);
panel.add(button, new GridBagConstraints());
Border border = UIManager.getBorder("TableHeader.cellBorder");
border.getBorderInsets(null).set(0, 2, 1, 1);
panel.setBorder(label.getBorder());
label.setBorder(null);
return panel;
}
public TableCellRenderer getRenderer()
{
return renderer;
}
}
public HeaderPopup getPopup(int modelIndex)
{
return popups.get(modelIndex);
}
public void setModified(int modelIndex, boolean value)
{
modified.put(modelIndex, value);
}
public void addButtonListener(HeaderButtonListener l)
{
listenerList.add(HeaderButtonListener.class, l);
}
protected void fireHeaderButtonClicked(int modelIndex) {
Object[] listeners = listenerList.getListenerList();
HeaderPopupEvent e=null;
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==HeaderButtonListener.class) {
if (e == null)
e = new HeaderPopupEvent(this, modelIndex);
((HeaderButtonListener)listeners[i+1]).buttonClicked(e);
}
}
}
}