/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.bearsoft.gui.grid.rows;
import com.bearsoft.gui.grid.events.insets.InsetAfterLastChangedEvent;
import com.bearsoft.gui.grid.events.insets.InsetChangeListener;
import com.bearsoft.gui.grid.events.insets.InsetPreFirstChangedEvent;
import com.bearsoft.gui.grid.insets.InsetPart;
import com.bearsoft.gui.grid.insets.LinearInset;
import javax.swing.RowSorter;
import javax.swing.event.RowSorterEvent;
import javax.swing.event.RowSorterListener;
import javax.swing.table.TableModel;
/**
*
* @author mg
* @param <M>
*/
public class InsettedRowSorter<M extends TableModel> extends DelegatingRowSorter<M> {
protected class DelegateListener implements RowSorterListener {
@Override
public void sorterChanged(RowSorterEvent e) {
fireRowSorterChanged(null);
}
}
protected class InsetListener implements InsetChangeListener {
@Override
public void insetPreFirstChanged(InsetPreFirstChangedEvent anEvent) {
fireRowSorterChanged(null);
}
@Override
public void insetAfterLastChanged(InsetAfterLastChangedEvent anEvent) {
fireRowSorterChanged(null);
}
}
protected LinearInset inset;
protected InsettedRowSorter(M aModel, RowSorter<M> aDelegate, LinearInset aInset) {
super(aDelegate, aModel);
inset = aInset;
if (delegate != null) {
delegate.addRowSorterListener(new DelegateListener());
}
assert inset != null : "Inset is required for constructing InsettedRowSorter.";
inset.addInsetChangeListener(new InsetListener());
}
public InsettedRowSorter(RowSorter<M> aDelegate, LinearInset aInset) {
this(null, aDelegate, aInset);
}
public InsettedRowSorter(M aModel, LinearInset aInset) {
this(aModel, null, aInset);
}
/**
* Returns the location of <code>index</code> in terms of the
* underlying model. That is, for the row <code>index</code> in
* the coordinates of the view this returns the row index in terms
* of the underlying model.
* Inset within this row sorter works like this:
* 1. <code>index</code> is in the InsetPart.PartKind.BEFORE section of the inset space. In this case index is reverted. For example inset is 3 and view index is 2, model index will be -1.
* 2. <code>index</code> is in the InsetPart.PartKind.CONTENT section of the inset space. In this case index will be converted in standard way.
* 3. <code>index</code> is in the InsetPart.PartKind.AFTER section of the inset space. In this case index is biased with very big value (<code>InsetPart.AFTER_INSET_BIAS</code>).
* @param aViewIndex the row index in terms of the underlying view
* @return row index in terms of the view
* @throws IndexOutOfBoundsException if <code>index</code> is outside the
* range of the view
* @see InsetPart
* @see LinearInset#toInnerSpace(int, int)
*/
@Override
public int convertRowIndexToModel(int aViewIndex) {
if (delegate != null) {
InsetPart insetPart = inset.toInnerSpace(aViewIndex, delegate.getViewRowCount());
if (insetPart.getKind() == InsetPart.PartKind.CONTENT) {
return delegate.convertRowIndexToModel(insetPart.getValue());
} else if (insetPart.getKind() == InsetPart.PartKind.BEFORE) {
return insetPart.getValue()-inset.getPreFirst();
} else {
assert insetPart.getKind() == InsetPart.PartKind.AFTER;
return insetPart.getValue() + InsetPart.AFTER_INSET_BIAS;
}
} else {
assert model != null;
InsetPart insetPart = inset.toInnerSpace(aViewIndex, model.getRowCount());
if (insetPart.getKind() == InsetPart.PartKind.CONTENT) {
return insetPart.getValue();
} else if (insetPart.getKind() == InsetPart.PartKind.BEFORE) {
return insetPart.getValue()-inset.getPreFirst();
} else {
assert insetPart.getKind() == InsetPart.PartKind.AFTER;
return insetPart.getValue() + InsetPart.AFTER_INSET_BIAS;
}
}
}
@Override
public int convertRowIndexToView(int aModelIndex) {
if (delegate != null) {
return inset.toOuterSpace(new InsetPart(InsetPart.PartKind.CONTENT, delegate.convertRowIndexToView(aModelIndex)), LinearInset.EMPTY_CONTENT);
} else {
return inset.toOuterSpace(new InsetPart(InsetPart.PartKind.CONTENT, aModelIndex), LinearInset.EMPTY_CONTENT);
}
}
@Override
public int getViewRowCount() {
int viewRowCount = inset.getPreFirst() + inset.getAfterLast();
if (delegate != null) {
viewRowCount += delegate.getViewRowCount();
} else {
assert model != null;
viewRowCount += model.getRowCount();
}
return viewRowCount;
}
}