I am having problems getting your SmartBeanContainer to work.
I suspect the problem is an infinite loop here:
while (newIds != null)
i++;
Here is a simple example app I built to try it, “TrySmartBeanContainer” app.
Just copy-paste the 3 classes into a new Vaadin project. Ready to run.
Symptom: When I click any of the 4 buttons, I get Vaadin’s red spinning wheel in the upper right corner. Never ends.
Three simple classes:
- Vaadin app
- Your
SmartBeanContainer
- A
Person
class to populate the table with rows.
Using: Vaadin 6.8.0, Eclipse Indigo, Tomcat 7.0.28, Mac OS X 10.7.4, Java 7 Update 5 (I think, not sure).
package com.example.trysmartbeancontainer;
import java.util.Set;
import com.vaadin.Application;
import com.vaadin.data.Property;
import com.vaadin.ui.*;
import com.vaadin.ui.Button.ClickEvent;
/**
* <p>
* My attempt to use the SmartBeanContainer posted in <a href='https://vaadin.com/forum/-/message_boards/view_message/1505114#_19_message_1505114'>this thread of the Vaadin</a> forum.
* </p>
*
* <p>
* © 2012 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
* </p>
*
* @author Basil Bourque.
*
*/
public class TrysmartbeancontainerApplication extends Application {
@SuppressWarnings ( "serial" )
@Override
public void init() {
// Window *****************************************************
Window mainWindow = new Window( "Trysmartbeancontainer Application" );
Label label = new Label( "Hello Vaadin user. Now is: " + new java.util.Date() );
mainWindow.addComponent( label );
// Container *****************************************************
SmartBeanContainer container = new SmartBeanContainer( Person.class );
container.addItem( java.util.UUID.randomUUID(), new Person( "Franco", "Graziosi", "206.555.1234" ) );
container.addItem( java.util.UUID.randomUUID(), new Person( "Basil", "Bourque", "425.555.5678" ) );
container.addItem( java.util.UUID.randomUUID(), new Person( "Wendy", "Melvoin", "360.555.7777" ) );
container.addItem( java.util.UUID.randomUUID(), new Person( "Lisa", "Coleman", "808.555.6655" ) );
container.addItem( java.util.UUID.randomUUID(), new Person( "Jesse", "Johnson", "707.555.4455" ) );
// Table *****************************************************
final Table table = new Table( "People", container );
table.setImmediate( true );
table.setSelectable( true );
table.setMultiSelect( true );
// Tell selection change.
table.addListener( new Property.ValueChangeListener() {
public void valueChange( Property.ValueChangeEvent event ) {
System.out.println( "Selected: " + table.getValue() + " " + new java.util.Date() );
System.out.println( "Selection itself is type: " + table.getValue().getClass().getName() );
}
} );
mainWindow.addComponent( table );
// Move To The Top button *****************************************************
Button moveToTopButton = new Button( "Move to top" );
moveToTopButton.addListener( new Button.ClickListener() {
@Override
public void buttonClick( ClickEvent event ) {
System.out.println( "DEBUG - moveToTopButton button clicked. " + new java.util.Date() );
// moving selected rows 1 position up
SmartBeanContainer bc = (SmartBeanContainer)table.getContainerDataSource();
Set set = (Set)table.getValue();
int offset = bc.getMoveSpans( set )[0]
;
bc.move( set, offset );
}
} );
mainWindow.addComponent( moveToTopButton );
// Up button *****************************************************
Button moveUpButton = new Button( "↑" );
moveUpButton.addListener( new Button.ClickListener() {
@Override
public void buttonClick( ClickEvent event ) {
System.out.println( "DEBUG - Up button clicked. " + new java.util.Date() );
// moving selected rows 1 position up
SmartBeanContainer bc = (SmartBeanContainer)table.getContainerDataSource();
Set set = (Set)table.getValue();
bc.move( set, -1 ); // -1 = up. +1 = Down.
}
} );
mainWindow.addComponent( moveUpButton );
// Down button *****************************************************
Button moveDownButton = new Button( "↓" );
moveDownButton.addListener( new Button.ClickListener() {
@Override
public void buttonClick( ClickEvent event ) {
System.out.println( "DEBUG - Down button clicked. " + new java.util.Date() );
// moving selected rows 1 position down
SmartBeanContainer bc = (SmartBeanContainer)table.getContainerDataSource();
Set set = (Set)table.getValue();
bc.move( set, 1 ); // -1 = up. +1 = Down.
}
} );
mainWindow.addComponent( moveDownButton );
// Move To The Bottom button *****************************************************
Button moveToBottomButton = new Button( "Move to bottom" );
moveToBottomButton.addListener( new Button.ClickListener() {
@Override
public void buttonClick( ClickEvent event ) {
System.out.println( "DEBUG - moveToBottomButton button clicked. " + new java.util.Date() );
// moving selected rows 1 position up
SmartBeanContainer bc = (SmartBeanContainer)table.getContainerDataSource();
Set set = (Set)table.getValue();
int offset = bc.getMoveSpans( set )[1]
;
bc.move( set, offset );
}
} );
mainWindow.addComponent( moveToBottomButton );
setMainWindow( mainWindow );
}
}
package com.example.trysmartbeancontainer;
import com.vaadin.data.util.BeanContainer;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @author Franco Graziosi
*
* @param <K>
* @param <V>
*/
@SuppressWarnings ( "serial" )
public class SmartBeanContainer< K, V > extends BeanContainer< K, V > {
public SmartBeanContainer( Class< ? super V > type ) {
super( type );
}
/**
* Move (up or down) a set of items.
*
* @param toMove
* The IDs of rows to be moved.
* @param offset
* The offset to be moved: -1 = 1 row up, +5 = 5 rows down and
* so on.
*/
public void move( Set< Object > toMove, int offset ) {
System.out.println( "move>>>" + offset );
List< K > ids = getAllItemIds();
List< K > pending = new ArrayList< K >( ids );
Object[] newIds = new Object[ids.size()]
;
for ( Object id : toMove ) {
int index = indexOfId( id ) + offset;
if ( index >= 0 && index < ids.size() ) {
newIds[index]
= id;
pending.remove( (K)id );
}
}
int i = 0;
for ( K id : pending ) {
while ( newIds != null )
i++;
newIds[i++]
= id;
}
ids.clear();
for ( Object id : newIds )
ids.add( (K)id );
if ( isFiltered() ) {
filterAll();
} else {
fireItemSetChange();
}
}
/**
* Compute maximum move span. This can be used to enable and disable move
* buttons and to compute the offset needed to move first selected item
* to top or last selected item to bottom.
*
* @param toMove
* toMove The IDs of rows to be moved.
* @return A 2-elements array indicating the maximum negative and positive
* move without exceeding table boundaries. Foe example [-5, +2]
indicates
*/
public int[] getMoveSpans( Set< Object > toMove ) {
int l = getAllItemIds().size();
if ( l == 0 || toMove.isEmpty() )
return new int[] { 0, 0 };
int first = l - 1;
int last = 0;
for ( Object o : toMove ) {
int i = indexOfId( o );
first = Math.min( first, i );
last = Math.max( last, i );
}
return new int[] { -first, l - 1 - last };
}
}
package com.example.trysmartbeancontainer;
/**
* <p>
* © 2012 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
* </p>
*
* @author basilbourque
*
*/
public class Person {
private String firstName;
private String lastName;
private String phoneNumber;
/**
* @return the firstName
*/
public String getFirstName() {
return firstName;
}
/**
* @param firstName
* the firstName to set
*/
public void setFirstName( String firstName ) {
this.firstName = firstName;
}
/**
* @return the lastName
*/
public String getLastName() {
return lastName;
}
/**
* @param lastName
* the lastName to set
*/
public void setLastName( String lastName ) {
this.lastName = lastName;
}
/**
* @return the phoneNumber
*/
public String getPhoneNumber() {
return phoneNumber;
}
/**
* @param firstName
* @param lastName
* @param phoneNumber
*/
public Person( String firstName, String lastName, String phoneNumber ) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.phoneNumber = phoneNumber;
}
}
–Basil Bourque