/*
* Copyright 2011 Uwe Krueger.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mandelsoft.swing;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
/**
*
* @author Uwe Krüger
*/
public class TablePanel<T extends TableModel>
extends ActionPanel {
private JLabel label;
private JTable table;
private JScrollPane scrollpane;
private T model;
private String title;
private ModelListener modellistener;
private boolean showsize;
private TableSelection selection;
protected TablePanel()
{
setup(null,null,null);
}
public TablePanel(String header, T model)
{
setup(header, model, null);
}
public TablePanel(String header, T model, ActionListener action)
{
setup(header, model, action);
}
@Override
protected void panelUnbound()
{
super.panelUnbound();
if (modellistener!=null && model!=null && label!=null) {
model.removeTableModelListener(modellistener);
}
}
public void setModel(T model)
{
if (this.model==model) return;
if (this.model!=null && modellistener!=null) {
this.model.removeTableModelListener(modellistener);
}
this.model=model;
if (this.model!=null && label!=null) {
if (modellistener==null) modellistener=new ModelListener();
this.model.addTableModelListener(modellistener);
}
this.table.setModel(model);
table.getRowSorter().toggleSortOrder(0);
}
public void setTitle(String name)
{
title=name;
updateTitle();
}
public String getTitle()
{
return title;
}
protected void updateTitle()
{
if (label!=null) {
if (showsize) {
int c=getModel().getRowCount();
label.setText(title+"("+com.mandelsoft.util.Utils.sizeString(c,"entry")+")");
}
else {
label.setText(title);
}
}
}
public boolean isShowSize()
{
return showsize;
}
public void setShowSize(boolean showsize)
{
if (showsize==this.showsize) return;
this.showsize=showsize;
if (showsize) {
if (label!=null&&model!=null) {
if (modellistener==null) modellistener=new ModelListener();
model.addTableModelListener(modellistener);
}
}
else {
if (modellistener!=null&&model!=null) {
model.removeTableModelListener(modellistener);
}
modellistener=null;
}
updateTitle();
}
public void setFillsViewportHeight(boolean fillsViewportHeight)
{
table.setFillsViewportHeight(fillsViewportHeight);
}
private boolean busy;
private Cursor origcursor;
protected void setBusy(boolean b)
{
if (b!=busy) {
if (b) {
System.out.println("-------------------------------------------------");
System.out.println("set busy");
origcursor=getCursor();
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
}
else {
System.out.println("orig cursor");
setCursor(origcursor);
}
firePropertyChange("busy",!b,b);
}
busy=b;
}
private void setup(String header, T model, ActionListener action)
{
JLabel c;
showsize=true;
if (debug) System.out.println("*** creating "+this);
if (action!=null) addActionListener(action);
if (!com.mandelsoft.util.Utils.isEmpty(header)) {
label=c=new JLabel(header);
label.setHorizontalAlignment(JLabel.CENTER);
addContent(label, GBC(0, 0, GBC.HORIZONTAL).setAnchor(GBC.CENTER));
}
else {
c=new JLabel("height");
}
table=createTable();
selection=new TableSelection(table);
setupTable(table);
if (model!=null) setModel(model);
table.getSelectionModel().addListSelectionListener(
new TableListener());
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent event)
{ // check for double click
//System.out.println("mouse clicked");
if (event.getClickCount()<2)
return;
// // find column of click and
// int row=table.rowAtPoint(event.getPoint());
//
// // translate to table model index and sort
// int modelRow=table.convertRowIndexToModel(row);
// System.out.println("row index: "+row+"; model index: "+modelRow);
fireActionPerformed(ActionEvent.ACTION_PERFORMED, null);
}
@Override
public void mouseReleased(MouseEvent e)
{
handlePopup(e);
}
@Override
public void mousePressed(MouseEvent e)
{
handlePopup(e);
}
public void handlePopup(MouseEvent e)
{
//System.out.println("check table ctx popup event");
if (e.isPopupTrigger() && ctxmenu!=null) {
selection.setLeadSelection(e);
System.out.println("CTX POPUP at "+e.getPoint().getX()+","+
e.getPoint().getY()+" ("
+selection+")");
ctxmenu.handleContextMenu(table, e, selection);
}
}
});
FontMetrics m=c.getFontMetrics(c.getFont());
getTable().setPreferredScrollableViewportSize(new Dimension(
(int)(m.charWidth('W')*40), (int)(m.getHeight()*6)));
addContent(scrollpane=new JScrollPane(table), GBC(0, 1, GBC.BOTH));
}
protected JTable createTable()
{
return new IJTable();
}
protected void setupTable(JTable table)
{
table.setAutoCreateRowSorter(true);
//rastertable.setFillsViewportHeight(true);
table.setShowGrid(false);
//rastertable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setAutoCreateRowSorter(true);
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
}
protected void setSelection(TableSelection s)
{
// setSelection(row);
}
// protected void setSelection(int row)
// {
// }
public T getModel()
{
return model;
}
public JTable getTable()
{
return table;
}
public JScrollPane getScrollPane()
{
return scrollpane;
}
public int convertRowIndexToModel(int index)
{
return table.convertRowIndexToModel(index);
}
public int convertColumnIndexToModel(int index)
{
return table.convertColumnIndexToModel(index);
}
public int getSelectedIndex()
{
int index=table.getSelectedRow();
int ix2=table.getSelectionModel().getLeadSelectionIndex();
//System.out.println("sel idx="+index+", lead="+ix2);
index=ix2;
if (index>=0) {
index=convertRowIndexToModel(index);
}
return index;
}
public int getSelectedColumn()
{
int index=table.getSelectedColumn();
if (index>=0) {
index=convertColumnIndexToModel(index);
}
return index;
}
private class TableListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent e)
{
ListSelectionModel lsm=(ListSelectionModel)e.getSource();
if (e.getValueIsAdjusting()) return;
int col=table.getSelectedColumn();
int index=table.getSelectedRow();
int ix2=table.getSelectionModel().getLeadSelectionIndex();
// System.out.println("selected: "+index+"/"+ix2+" "+lsm.getMaxSelectionIndex()+
// "@"+col);
index=ix2;
if (index<0) return;
selection.setLeadSelection(index,col);
System.out.println("SELECTION: "+selection);
setSelection(selection);
}
}
private class ModelListener implements TableModelListener {
public void tableChanged(TableModelEvent e)
{
updateTitle();
}
}
////////////////////////////////////////////////////////////////
// mouselistener support
////////////////////////////////////////////////////////////////
public void addActionListener(ActionListener l)
{
listenerList.add(ActionListener.class, l);
}
public void removeActionListener(ActionListener l)
{
listenerList.remove(ActionListener.class, l);
}
public ActionListener[] getActionListeners()
{
return getListeners(ActionListener.class);
}
protected void fireActionPerformed(int id, String cmd)
{
// Guaranteed to return a non-null array
Object[] listeners=listenerList.getListenerList();
ActionEvent e=null;
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i=listeners.length-2; i>=0; i-=2) {
if (listeners[i]==ActionListener.class) {
// Lazily create the event:
if (e==null)
e=new ActionEvent(this, id, cmd);
((ActionListener)listeners[i+1]).actionPerformed(e);
}
}
}
///////////////////////////////////////////////////////////////////////
// Context Menu
///////////////////////////////////////////////////////////////////////
public interface ContextMenuHandler extends DnDJTable.ContextMenuHandler {
}
//////////////////////////////////////////////////////////////////////////
// Context Menu outside of list
private class Listener extends MouseAdapter {
@Override
public void mouseReleased(MouseEvent e)
{
handlePopup(e);
}
@Override
public void mousePressed(MouseEvent e)
{
handlePopup(e);
}
public void handlePopup(MouseEvent e)
{
if (e.isPopupTrigger()&&ctxmenu!=null) {
System.out.println("CTX POPUP at panel");
ctxmenu.handleContextMenu(TablePanel.this, e,
new TableSelection(table,-1, -1));
}
}
}
private DnDJTable.ContextMenuHandler ctxmenu;
private Listener mouselistener;
synchronized
public void setContextMenuHandler(DnDJTable.ContextMenuHandler h)
{
if (h==null) {
if (ctxmenu!=null) removeMouseListener(mouselistener);
}
else {
if (ctxmenu==null) {
if (mouselistener==null) mouselistener=new Listener();
addMouseListener(mouselistener);
scrollpane.getViewport().addMouseListener(mouselistener);
}
}
ctxmenu=h;
}
synchronized
public DnDJTable.ContextMenuHandler getContextMenuHandler()
{
return ctxmenu;
}
}