/*
* Bibliothek - DockingFrames
* Library built on Java/Swing, allows the user to "drag and drop"
* panels containing any Swing-Component the developer likes to add.
*
* Copyright (C) 2012 Herve Guillaume, Benjamin Sigg
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Herve Guillaume
* rvguillaume@hotmail.com
* FR - France
*
* Benjamin Sigg
* benjamin_sigg@gmx.ch
* CH - Switzerland
*/
package bibliothek.gui.dock.toolbar;
import static org.junit.Assert.*;
import java.awt.Component;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import bibliothek.gui.DockStation;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.component.DockComponentRootHandler;
import bibliothek.gui.dock.dockable.AbstractDockable;
import bibliothek.gui.dock.station.support.ConvertedPlaceholderListItem;
import bibliothek.gui.dock.station.support.PlaceholderList;
import bibliothek.gui.dock.station.support.PlaceholderListItem;
import bibliothek.gui.dock.station.support.PlaceholderMap;
import bibliothek.gui.dock.station.support.PlaceholderStrategy;
import bibliothek.gui.dock.station.support.PlaceholderStrategyListener;
import bibliothek.gui.dock.station.toolbar.group.ToolbarColumn;
import bibliothek.gui.dock.station.toolbar.group.ToolbarColumnListener;
import bibliothek.gui.dock.station.toolbar.group.ToolbarColumnModel;
import bibliothek.gui.dock.station.toolbar.group.ToolbarColumnModelListener;
import bibliothek.gui.dock.station.toolbar.layout.DockablePlaceholderToolbarGrid;
import bibliothek.gui.dock.station.toolbar.layout.GridPlaceholderList;
import bibliothek.gui.dock.station.toolbar.layout.GridPlaceholderList.Column;
import bibliothek.gui.dock.station.toolbar.layout.PlaceholderToolbarGridConverter;
import bibliothek.gui.dock.util.PropertyKey;
import bibliothek.gui.dock.util.icon.DockIcon;
import bibliothek.util.Path;
/**
* This test checks {@link DockablePlaceholderToolbarGrid}. To be exact, the test checks these attributes:
* <ul>
* <li>Inserting and removing items with and without placeholders result in the expected layout.</li>
* <li>Writing and reading the grid does not change the grid.</li>
* <li>The model of the grid always remains correct, the events fired by the model match the actual changes.</li>
* </ul>
* @author Benjamin Sigg
*/
public class ToolbarGridTest {
private TestStory story;
@Before
public void setup(){
story = new TestStory();
}
@After
public void clear(){
story = null;
}
@Test
public void testOneColumn(){
story.insert( 0, 0, null );
story.insert( 0, 1, null );
story.insert( 0, 2, "a" );
story.assertCell( 0, 0, null );
story.assertCell( 0, 1, null );
story.assertCell( 0, 2, "a" );
}
@Test
public void testOneColumnAddRemove(){
story.insert( 0, 0, null );
story.insert( 0, 1, null );
story.insert( 0, 2, "a" );
story.remove( 0, 1 );
story.assertCell( 0, 0, null );
story.assertCell( 0, 1, "a" );
}
@Test
public void testOneColumnAddRemovePlaceholder(){
story.insert( 0, 0, null );
story.insert( 0, 1, "a" );
story.insert( 0, 2, null );
story.remove( 0, 1 );
story.insert( "a" );
story.assertCell( 0, 0, null );
story.assertCell( 0, 1, "a" );
story.assertCell( 0, 2, null );
}
@Test
public void testMultiColumn(){
story.insert( 0, 0, null );
story.insert( 0, 1, null );
story.insert( 0, 2, null );
story.insert( 1, 0, null );
story.insert( 1, 1, null );
story.assertCell( 0, 0, null );
story.assertCell( 0, 1, null );
story.assertCell( 0, 2, null );
story.assertCell( 1, 0, null );
story.assertCell( 1, 1, null );
}
@Test
public void testColumnAddRemovePlaceholder(){
story.insert( 0, 0, null );
story.insert( 0, 1, null );
story.insert( 0, 2, null );
story.insert( 1, 0, "a" );
story.insert( 1, 1, "b" );
story.insert( 2, 0, null );
story.insert( 2, 1, null );
story.remove( 1, 0 );
story.remove( 1, 0 );
story.insert( "b" );
story.insert( "a" );
story.assertCell( 0, 0, null );
story.assertCell( 0, 1, null );
story.assertCell( 0, 2, null );
story.assertCell( 1, 0, "a" );
story.assertCell( 1, 1, "b" );
story.assertCell( 2, 0, null );
story.assertCell( 2, 1, null );
}
@Test
public void testNewPosition(){
story.insert( 0, 0, "a" );
story.insert( 0, 1, "b" );
story.insert( 0, 2, "c" );
story.insert( 1, 0, "d" );
story.insert( 1, 1, "e" );
story.insert( 1, 2, "f" );
story.insert( 2, 0, "g" );
story.insert( 2, 1, "h" );
story.insert( 2, 2, "i" );
story.remove( 1, 1 );
story.insert( 2, 1, "e" );
story.remove( 2, 1 );
story.insert( "e" );
story.assertCell( 0, 0, "a" );
story.assertCell( 0, 1, "b" );
story.assertCell( 0, 2, "c" );
story.assertCell( 1, 0, "d" );
story.assertCell( 1, 1, "f" );
story.assertCell( 2, 0, "g" );
story.assertCell( 2, 1, "e" );
story.assertCell( 2, 2, "h" );
story.assertCell( 2, 3, "i" );
}
private TestGrid copyByReadWrite( TestGrid grid, Collection<Dockable> dockables ){
Map<Integer, Dockable> idToItem = new HashMap<Integer, Dockable>();
Map<Dockable, Integer> itemToId = new HashMap<Dockable, Integer>();
int index = 0;
for( Dockable item : dockables ) {
idToItem.put( index, item );
itemToId.put( item, index );
index++;
}
PlaceholderMap map = grid.toMap( itemToId );
TestGrid newGrid = new TestGrid();
newGrid.fromMap( map, idToItem, new PlaceholderToolbarGridConverter<Dockable, ToolbarGridTest.TestItem>(){
@Override
public TestItem convert( Dockable dockable, ConvertedPlaceholderListItem item ){
return new TestItem( (TestDockable) dockable );
}
@Override
public void added( TestItem item ){
// ignore
}
} );
return newGrid;
}
private void assertEqualsGrid( TestGrid gridA, TestGrid gridB ){
assertEquals( gridA.getColumnCount(), gridB.getColumnCount() );
GridPlaceholderList<Dockable, DockStation, TestItem> listA = gridA.getGrid();
GridPlaceholderList<Dockable, DockStation, TestItem> listB = gridB.getGrid();
assertEquals( listA.list().size(), listB.list().size() );
assertEquals( listA.dockables().size(), listB.dockables().size() );
Iterator<GridPlaceholderList<Dockable, DockStation, TestItem>.Item> itemsA = listA.list().iterator();
Iterator<GridPlaceholderList<Dockable, DockStation, TestItem>.Item> itemsB = listB.list().iterator();
while( itemsA.hasNext() && itemsB.hasNext() ) {
assertEqualsColumn( itemsA.next(), itemsB.next() );
}
assertEquals( itemsA.hasNext(), itemsB.hasNext() );
}
private void assertEqualsColumn( GridPlaceholderList<Dockable, DockStation, TestItem>.Item itemA, GridPlaceholderList<Dockable, DockStation, TestItem>.Item itemB ){
assertEquals( itemA.isPlaceholder(), itemB.isPlaceholder() );
assertEquals( itemA.getPlaceholderSet(), itemB.getPlaceholderSet() );
Column<Dockable, DockStation, TestItem> columnA = itemA.getDockable();
Column<Dockable, DockStation, TestItem> columnB = itemB.getDockable();
if( columnA != null && columnB != null ) {
PlaceholderList<Dockable, DockStation, TestItem> listA = columnA.getList();
PlaceholderList<Dockable, DockStation, TestItem> listB = columnB.getList();
assertEqualsList( listA, listB );
}
}
private void assertEqualsList( PlaceholderList<Dockable, DockStation, TestItem> listA, PlaceholderList<Dockable, DockStation, TestItem> listB ){
assertEquals( listA.list().size(), listB.list().size() );
assertEquals( listA.dockables().size(), listB.dockables().size() );
Iterator<PlaceholderList<Dockable, DockStation, TestItem>.Item> itemsA = listA.list().iterator();
Iterator<PlaceholderList<Dockable, DockStation, TestItem>.Item> itemsB = listB.list().iterator();
while( itemsA.hasNext() && itemsB.hasNext() ) {
PlaceholderList<Dockable, DockStation, TestItem>.Item itemA = itemsA.next();
PlaceholderList<Dockable, DockStation, TestItem>.Item itemB = itemsB.next();
assertEquals( itemA.getPlaceholderSet(), itemB.getPlaceholderSet() );
assertEquals( itemA.getDockable(), itemB.getDockable() );
}
assertEquals( itemsA.hasNext(), itemsB.hasNext() );
}
private class TestStory implements ToolbarColumnModelListener<Dockable,TestItem>, ToolbarColumnListener<Dockable,TestItem> {
private TestGrid grid = new TestGrid();
private List<Dockable> dockables = new ArrayList<Dockable>();
private List<ToolbarColumn<Dockable,TestItem>> columns = new ArrayList<ToolbarColumn<Dockable,TestItem>>();
private List<List<TestItem>> items = new ArrayList<List<TestItem>>();
public TestStory(){
grid.setStrategy( new TestPlaceholderStrategy() );
ToolbarColumnModel<Dockable,TestItem> model = grid.getModel();
model.addListener( this );
}
@Override
public void inserted( ToolbarColumnModel<Dockable,TestItem> model, ToolbarColumn<Dockable,TestItem> column, int index ){
column.addListener( this );
columns.add( index, column );
items.add( index, new ArrayList<TestItem>() );
}
@Override
public void removed( ToolbarColumnModel<Dockable,TestItem> model, ToolbarColumn<Dockable,TestItem> column, int index ){
column.removeListener( this );
columns.remove( index );
List<TestItem> list = items.remove( index );
assertEquals( 0, list.size() );
}
@Override
public void inserted( ToolbarColumn<Dockable,TestItem> column, TestItem item, Dockable dockable, int index ){
int columnIndex = columns.indexOf( column );
assertTrue( columnIndex >= 0 );
items.get( columnIndex ).add( index, item );
}
@Override
public void removed( ToolbarColumn<Dockable,TestItem> column, TestItem item, Dockable dockable, int index ){
int columnIndex = columns.indexOf( column );
assertTrue( columnIndex >= 0 );
assertSame( item, items.get( columnIndex ).remove( index ) );
}
public void insert( int column, int row, String placeholder ){
TestItem item = new TestItem( placeholder );
grid.insert( column, row, item );
if( placeholder != null ) {
grid.addPlaceholder( column, row, new Path( "test", placeholder ) );
}
dockables.add( item.asDockable() );
check();
}
public void insert( String placeholder ){
TestItem item = new TestItem( placeholder );
grid.put( new Path( "test", placeholder ), item );
}
public void remove( int column, int row ){
ToolbarColumnModel<Dockable,TestItem> model = grid.getModel();
TestItem item = model.getColumn( column ).getItem( row );
grid.remove( item );
check();
}
private void check(){
assertEqualsGrid( grid, copyByReadWrite( grid, dockables ) );
assertModel();
}
private void assertModel(){
ToolbarColumnModel<Dockable,TestItem> model = grid.getModel();
assertEquals( model.getColumnCount(), items.size() );
for( int i = 0, n = model.getColumnCount(); i < n; i++ ) {
ToolbarColumn<Dockable,TestItem> column = model.getColumn( i );
List<TestItem> list = items.get( i );
assertEquals( list.size(), column.getDockableCount() );
for( int j = 0, m = column.getDockableCount(); j < m; j++ ) {
assertSame( column.getItem( j ), list.get( j ) );
}
}
}
public void assertCell( int column, int row, String placeholder ){
ToolbarColumnModel<Dockable,TestItem> model = grid.getModel();
TestItem item = model.getColumn( column ).getItem( row );
TestDockable dockable = (TestDockable) item.asDockable();
assertNotNull( dockable );
if( placeholder == null ) {
assertNull( dockable.getId() );
}
else {
assertEquals( placeholder, dockable.getId() );
}
}
}
private static class TestPlaceholderStrategy implements PlaceholderStrategy {
@Override
public void install( DockStation station ){
// ignore
}
@Override
public void uninstall( DockStation station ){
// ignore
}
@Override
public void addListener( PlaceholderStrategyListener listener ){
// ignore
}
@Override
public void removeListener( PlaceholderStrategyListener listener ){
// ignore
}
@Override
public Path getPlaceholderFor( Dockable dockable ){
if( dockable instanceof TestDockable ) {
String id = ((TestDockable) dockable).getId();
if( id != null ) {
return new Path( "test", id );
}
}
return null;
}
@Override
public boolean isValidPlaceholder( Path placeholder ){
return true;
}
}
private static class TestDockable extends AbstractDockable {
private String id;
public TestDockable( String id ){
super( PropertyKey.DOCKABLE_TITLE, PropertyKey.DOCKABLE_TOOLTIP );
this.id = id;
}
@Override
public Component getComponent(){
return null;
}
@Override
public DockStation asDockStation(){
return null;
}
@Override
public String getFactoryID(){
return null;
}
@Override
protected DockIcon createTitleIcon(){
return null;
}
public String getId(){
return id;
}
@Override
protected DockComponentRootHandler createRootHandler() {
return new DockComponentRootHandler( this ){
@Override
protected TraverseResult shouldTraverse( Component component ) {
return TraverseResult.EXCLUDE;
}
};
}
}
private static class TestItem implements PlaceholderListItem<Dockable> {
private Dockable dockable;
public TestItem( String id ){
dockable = new TestDockable( id );
}
public TestItem( TestDockable dockable ){
this.dockable = dockable;
}
@Override
public Dockable asDockable(){
return dockable;
}
@Override
public boolean equals( Object obj ){
if( obj.getClass() != getClass() ) {
return false;
}
return ((TestItem) obj).dockable == dockable;
}
}
private static class TestGrid extends DockablePlaceholderToolbarGrid<TestItem> {
private GridPlaceholderList<Dockable, DockStation, TestItem> grid;
@Override
protected GridPlaceholderList<Dockable, DockStation, TestItem> createGrid(){
grid = super.createGrid();
return grid;
}
public GridPlaceholderList<Dockable, DockStation, TestItem> getGrid(){
return grid;
}
}
}