svn changeset:2629/svn branch:trunktags/6.7.0.beta1
@@ -1,16 +1,9 @@ | |||
package com.itmill.toolkit.demo; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import com.itmill.toolkit.data.Item; | |||
import com.itmill.toolkit.ui.OrderedLayout; | |||
import com.itmill.toolkit.ui.Panel; | |||
import com.itmill.toolkit.ui.Select; | |||
import com.itmill.toolkit.ui.Window; | |||
import com.itmill.toolkit.ui.select.ContainsFilter; | |||
import com.itmill.toolkit.ui.select.OptionFilter; | |||
/** | |||
* The classic "hello, world!" example for IT Mill Toolkit. The class simply | |||
@@ -50,33 +43,33 @@ public class FilterSelect extends com.itmill.toolkit.Application { | |||
// default filter | |||
Select s1 = new Select(); | |||
for (int i = 0; i < 105; i++) | |||
for (int i = 0; i < 105; i++) { | |||
s1 | |||
.addItem(firstnames[(int) (Math.random() * (firstnames.length - 1))] | |||
+ " " | |||
+ lastnames[(int) (Math.random() * (lastnames.length - 1))]); | |||
s1.setLazyLoading(true); | |||
} | |||
s1.setImmediate(true); | |||
// contains filter | |||
Select s2 = new Select(); | |||
for (int i = 0; i < 500; i++) | |||
for (int i = 0; i < 500; i++) { | |||
s2 | |||
.addItem(firstnames[(int) (Math.random() * (firstnames.length - 1))] | |||
+ " " | |||
+ lastnames[(int) (Math.random() * (lastnames.length - 1))]); | |||
s2.setLazyLoading(true); | |||
s2.setOptionFilter(new ContainsFilter(s2)); | |||
} | |||
s2.setFilteringMode(Select.FILTERINGMODE_CONTAINS); | |||
// custom filter | |||
// startswith filter | |||
Select s3 = new Select(); | |||
for (int i = 0; i < 500; i++) | |||
for (int i = 0; i < 500; i++) { | |||
s3 | |||
.addItem(firstnames[(int) (Math.random() * (firstnames.length - 1))] | |||
+ " " | |||
+ lastnames[(int) (Math.random() * (lastnames.length - 1))]); | |||
s3.setLazyLoading(true); | |||
s3.setOptionFilter(new FilterSelect.EndsWithFilter(s3)); | |||
} | |||
s3.setFilteringMode(Select.FILTERINGMODE_STARTSWITH); | |||
// Add selects to UI using ordered layout and panels | |||
OrderedLayout orderedLayout = new OrderedLayout( | |||
@@ -97,54 +90,4 @@ public class FilterSelect extends com.itmill.toolkit.Application { | |||
} | |||
/** | |||
* Custom filter that implements "ends with" functionality. | |||
* | |||
* @author IT Mill Ltd. | |||
* | |||
*/ | |||
public class EndsWithFilter implements OptionFilter { | |||
private Select s; | |||
private ArrayList filteredItemsBuffer; | |||
public EndsWithFilter(Select s) { | |||
this.s = s; | |||
} | |||
public List filter(String filterstring, int pagelength, int page) { | |||
// prefix MUST be in lowercase | |||
if (filterstring == null || "".equals(filterstring)) { | |||
this.filteredItemsBuffer = new ArrayList(s.getItemIds()); | |||
return this.filteredItemsBuffer; | |||
} else if (s.getContainerDataSource() != null) { | |||
// all items will be iterated and tested. | |||
// SLOW when there are lot of items. | |||
this.filteredItemsBuffer = new ArrayList(); | |||
for (Iterator iter = s.getItemIds().iterator(); iter.hasNext();) { | |||
Object id = iter.next(); | |||
Item item = s.getItem(id); | |||
String test = ""; | |||
if (s.getItemCaptionMode() == Select.ITEM_CAPTION_MODE_PROPERTY) | |||
test = item.getItemProperty( | |||
s.getItemCaptionPropertyId()).getValue() | |||
.toString().trim(); | |||
else | |||
test = String.valueOf(id); | |||
if (test.toLowerCase().endsWith(filterstring)) { | |||
this.filteredItemsBuffer.add(id); | |||
} | |||
} | |||
} | |||
return this.filteredItemsBuffer; | |||
} | |||
public int getMatchCount() { | |||
return filteredItemsBuffer.size(); | |||
} | |||
} | |||
} |
@@ -1,9 +1,13 @@ | |||
package com.itmill.toolkit.demo; | |||
import java.sql.SQLException; | |||
import com.itmill.toolkit.data.util.QueryContainer; | |||
import com.itmill.toolkit.demo.util.SampleDatabase; | |||
import com.itmill.toolkit.ui.*; | |||
import com.itmill.toolkit.ui.Label; | |||
import com.itmill.toolkit.ui.Panel; | |||
import com.itmill.toolkit.ui.Select; | |||
import com.itmill.toolkit.ui.Window; | |||
/** | |||
* This example demonstrates what is lazy loading feature on Select component. | |||
@@ -16,9 +20,9 @@ import com.itmill.toolkit.ui.*; | |||
public class SelectDemo extends com.itmill.toolkit.Application { | |||
// Select component where SQL rows are attached (using QueryContainer) | |||
private Select select = new Select(); | |||
private final Select select = new Select(); | |||
private Select lazySelect = new Select(); | |||
private final Select lazySelect = new Select(); | |||
// Database provided with sample data | |||
private SampleDatabase sampleDatabase; | |||
@@ -32,40 +36,41 @@ public class SelectDemo extends com.itmill.toolkit.Application { | |||
// Main window contains heading, table, select and tree | |||
Panel panel = new Panel("Select demo (a.k.a Google Suggests)"); | |||
panel.addComponent(lazySelect); | |||
panel.addComponent(this.lazySelect); | |||
panel.addComponent(new Label("<hr />", Label.CONTENT_XHTML)); | |||
panel.addComponent(select); | |||
panel.addComponent(this.select); | |||
main.addComponent(panel); | |||
// create demo database | |||
sampleDatabase = new SampleDatabase(); | |||
this.sampleDatabase = new SampleDatabase(); | |||
initSelects(); | |||
} | |||
private void initSelects() { | |||
// init select | |||
select.setCaption("All employees default functionality."); | |||
select.setItemCaptionPropertyId("WORKER"); | |||
this.select.setCaption("All employees default functionality."); | |||
this.select.setItemCaptionPropertyId("WORKER"); | |||
// populate Toolkit select component with test SQL table rows | |||
try { | |||
QueryContainer qc = new QueryContainer( | |||
"SELECT ID, UNIT||', '||LASTNAME||' '||FIRSTNAME" | |||
+ " AS WORKER FROM employee ORDER BY WORKER", | |||
sampleDatabase.getConnection()); | |||
select.setContainerDataSource(qc); | |||
this.sampleDatabase.getConnection()); | |||
this.select.setContainerDataSource(qc); | |||
} catch (SQLException e) { | |||
e.printStackTrace(); | |||
} | |||
// init lazySelect | |||
lazySelect.setCaption("All employees with lazy loading " | |||
this.lazySelect.setCaption("All employees with lazy loading " | |||
+ "(a.k.a Google Suggests) activated."); | |||
lazySelect.setItemCaptionPropertyId("WORKER"); | |||
// use lazy loading (a.k.a Google Suggest) | |||
lazySelect.setLazyLoading(true); | |||
this.lazySelect.setItemCaptionPropertyId("WORKER"); | |||
this.lazySelect.setFilteringMode(Select.FILTERINGMODE_CONTAINS); | |||
// use same datasource as select object uses | |||
lazySelect.setContainerDataSource(select.getContainerDataSource()); | |||
this.lazySelect.setContainerDataSource(this.select | |||
.getContainerDataSource()); | |||
} | |||
} |
@@ -7,81 +7,78 @@ import java.util.Iterator; | |||
import com.itmill.toolkit.data.Property.ValueChangeEvent; | |||
import com.itmill.toolkit.data.Property.ValueChangeListener; | |||
import com.itmill.toolkit.data.util.IndexedContainer; | |||
import com.itmill.toolkit.ui.Button; | |||
import com.itmill.toolkit.ui.CustomComponent; | |||
import com.itmill.toolkit.ui.Label; | |||
import com.itmill.toolkit.ui.OrderedLayout; | |||
import com.itmill.toolkit.ui.RichTextArea; | |||
import com.itmill.toolkit.ui.Select; | |||
import com.itmill.toolkit.ui.TwinColSelect; | |||
/** | |||
* | |||
* @author IT Mill Ltd. | |||
*/ | |||
public class TestForMultipleStyleNames extends CustomComponent implements ValueChangeListener { | |||
public class TestForMultipleStyleNames extends CustomComponent implements | |||
ValueChangeListener { | |||
private final OrderedLayout main = new OrderedLayout(); | |||
private OrderedLayout main = new OrderedLayout(); | |||
private Label l; | |||
private Select s = new TwinColSelect(); | |||
private final TwinColSelect s = new TwinColSelect(); | |||
private ArrayList styleNames2; | |||
public TestForMultipleStyleNames() { | |||
setCompositionRoot(main); | |||
setCompositionRoot(this.main); | |||
createNewView(); | |||
} | |||
public void createNewView() { | |||
main.removeAllComponents(); | |||
main | |||
.addComponent(new Label( | |||
"TK5 supports multiple stylenames for components.")); | |||
styleNames2 = new ArrayList(); | |||
styleNames2.add("red"); | |||
styleNames2.add("bold"); | |||
styleNames2.add("italic"); | |||
s.setContainerDataSource(new IndexedContainer(styleNames2)); | |||
s.addListener(this); | |||
s.setImmediate(true); | |||
main.addComponent(s); | |||
l = new Label("Test labele"); | |||
main.addComponent(l); | |||
this.main.removeAllComponents(); | |||
this.main.addComponent(new Label( | |||
"TK5 supports multiple stylenames for components.")); | |||
this.styleNames2 = new ArrayList(); | |||
this.styleNames2.add("red"); | |||
this.styleNames2.add("bold"); | |||
this.styleNames2.add("italic"); | |||
this.s.setContainerDataSource(new IndexedContainer(this.styleNames2)); | |||
this.s.addListener(this); | |||
this.s.setImmediate(true); | |||
this.main.addComponent(this.s); | |||
this.l = new Label("Test labele"); | |||
this.main.addComponent(this.l); | |||
} | |||
public void valueChange(ValueChangeEvent event) { | |||
String currentStyle = l.getStyle(); | |||
String currentStyle = this.l.getStyle(); | |||
String[] tmp = currentStyle.split(" "); | |||
ArrayList curStyles = new ArrayList(); | |||
for (int i = 0; i < tmp.length; i++) { | |||
if(tmp[i] != "") | |||
if (tmp[i] != "") { | |||
curStyles.add(tmp[i]); | |||
} | |||
} | |||
Collection styles = (Collection) s.getValue(); | |||
Collection styles = (Collection) this.s.getValue(); | |||
for (Iterator iterator = styles.iterator(); iterator.hasNext();) { | |||
String styleName = (String) iterator.next(); | |||
if(curStyles.contains(styleName)) { | |||
if (curStyles.contains(styleName)) { | |||
// already added | |||
curStyles.remove(styleName); | |||
} else { | |||
l.addStyleName(styleName); | |||
this.l.addStyleName(styleName); | |||
} | |||
} | |||
for (Iterator iterator2 = curStyles.iterator(); iterator2.hasNext();) { | |||
String object = (String) iterator2.next(); | |||
l.removeStyleName(object); | |||
this.l.removeStyleName(object); | |||
} | |||
} | |||
} |
@@ -2,6 +2,7 @@ package com.itmill.toolkit.tests; | |||
import com.itmill.toolkit.event.Action; | |||
import com.itmill.toolkit.event.Action.Handler; | |||
import com.itmill.toolkit.ui.AbstractSelect; | |||
import com.itmill.toolkit.ui.Button; | |||
import com.itmill.toolkit.ui.CheckBox; | |||
import com.itmill.toolkit.ui.Component; | |||
@@ -11,7 +12,6 @@ import com.itmill.toolkit.ui.NativeSelect; | |||
import com.itmill.toolkit.ui.OptionGroup; | |||
import com.itmill.toolkit.ui.OrderedLayout; | |||
import com.itmill.toolkit.ui.Panel; | |||
import com.itmill.toolkit.ui.Select; | |||
import com.itmill.toolkit.ui.Tree; | |||
import com.itmill.toolkit.ui.TwinColSelect; | |||
import com.itmill.toolkit.ui.Button.ClickEvent; | |||
@@ -32,9 +32,9 @@ public class TestForPreconfiguredComponents extends CustomComponent implements | |||
"Smith", "Jones", "Beck", "Sheridan", "Picard", "Hill", "Fielding", | |||
"Einstein" }; | |||
private OrderedLayout main = new OrderedLayout(); | |||
private final OrderedLayout main = new OrderedLayout(); | |||
private Action[] actions = new Action[] { new Action("edit"), | |||
private final Action[] actions = new Action[] { new Action("edit"), | |||
new Action("delete") }; | |||
private Panel al; | |||
@@ -43,73 +43,73 @@ public class TestForPreconfiguredComponents extends CustomComponent implements | |||
public TestForPreconfiguredComponents() { | |||
setCompositionRoot(main); | |||
setCompositionRoot(this.main); | |||
createNewView(); | |||
} | |||
public void createNewView() { | |||
main.removeAllComponents(); | |||
main | |||
this.main.removeAllComponents(); | |||
this.main | |||
.addComponent(new Label( | |||
"In TK5 we introduce some \"new\" componens. Earlier one" + | |||
" usually used setStyle or some other methods on possibly " + | |||
"multiple steps to configure component for ones needs. These new " + | |||
"server side components are mostly just classes that in constructor " + | |||
"set base class to state that programmer wants. This ought to help " + | |||
"newcomers and make code more readable.")); | |||
"In TK5 we introduce some \"new\" componens. Earlier one" | |||
+ " usually used setStyle or some other methods on possibly " | |||
+ "multiple steps to configure component for ones needs. These new " | |||
+ "server side components are mostly just classes that in constructor " | |||
+ "set base class to state that programmer wants. This ought to help " | |||
+ "newcomers and make code more readable.")); | |||
main.addComponent(new Button("commit")); | |||
this.main.addComponent(new Button("commit")); | |||
Panel test = createTestBench(new CheckBox()); | |||
test.setCaption("CheckBox (configured from button)"); | |||
main.addComponent(test); | |||
this.main.addComponent(test); | |||
Select s = new TwinColSelect(); | |||
AbstractSelect s = new TwinColSelect(); | |||
fillSelect(s, 20); | |||
test = createTestBench(s); | |||
test.setCaption("TwinColSelect (configured from select)"); | |||
main.addComponent(test); | |||
this.main.addComponent(test); | |||
s = new NativeSelect(); | |||
fillSelect(s, 20); | |||
test = createTestBench(s); | |||
test.setCaption("Native (configured from select)"); | |||
main.addComponent(test); | |||
this.main.addComponent(test); | |||
s = new OptionGroup(); | |||
fillSelect(s, 20); | |||
test = createTestBench(s); | |||
test.setCaption("OptionGroup (configured from select)"); | |||
main.addComponent(test); | |||
this.main.addComponent(test); | |||
s = new OptionGroup(); | |||
fillSelect(s, 20); | |||
s.setMultiSelect(true); | |||
test = createTestBench(s); | |||
test.setCaption("OptionGroup + multiselect manually (configured from select)"); | |||
main.addComponent(test); | |||
// Tree t = createTestTree(); | |||
// t.setCaption("with actions"); | |||
// t.setImmediate(true); | |||
// t.addActionHandler(this); | |||
// Panel ol = (Panel) createTestBench(t); | |||
// al = new Panel("action log"); | |||
// ol.addComponent(al); | |||
// main.addComponent(ol); | |||
// contextTree = t; | |||
test | |||
.setCaption("OptionGroup + multiselect manually (configured from select)"); | |||
this.main.addComponent(test); | |||
// Tree t = createTestTree(); | |||
// t.setCaption("with actions"); | |||
// t.setImmediate(true); | |||
// t.addActionHandler(this); | |||
// Panel ol = (Panel) createTestBench(t); | |||
// al = new Panel("action log"); | |||
// ol.addComponent(al); | |||
// main.addComponent(ol); | |||
// contextTree = t; | |||
Button b = new Button("refresh view", this, "createNewView"); | |||
main.addComponent(b); | |||
this.main.addComponent(b); | |||
} | |||
public static void fillSelect(Select s, int items) { | |||
public static void fillSelect(AbstractSelect s, int items) { | |||
for (int i = 0; i < items; i++) { | |||
String name = firstnames[(int) (Math.random() * (firstnames.length - 1))] | |||
+ " " | |||
+ lastnames[(int) (Math.random() * (lastnames.length - 1))]; | |||
+ " " | |||
+ lastnames[(int) (Math.random() * (lastnames.length - 1))]; | |||
s.addItem(name); | |||
} | |||
} | |||
@@ -117,24 +117,28 @@ public class TestForPreconfiguredComponents extends CustomComponent implements | |||
public Tree createTestTree() { | |||
Tree t = new Tree("Tree"); | |||
String[] names = new String[100]; | |||
for (int i = 0; i < names.length; i++) | |||
for (int i = 0; i < names.length; i++) { | |||
names[i] = firstnames[(int) (Math.random() * (firstnames.length - 1))] | |||
+ " " | |||
+ lastnames[(int) (Math.random() * (lastnames.length - 1))]; | |||
} | |||
// Create tree | |||
t = new Tree("Organization Structure"); | |||
for (int i = 0; i < 100; i++) { | |||
t.addItem(names[i]); | |||
String parent = names[(int) (Math.random() * (names.length - 1))]; | |||
if (t.containsId(parent)) | |||
if (t.containsId(parent)) { | |||
t.setParent(names[i], parent); | |||
} | |||
} | |||
// Forbid childless people to have children (makes them leaves) | |||
for (int i = 0; i < 100; i++) | |||
if (!t.hasChildren(names[i])) | |||
for (int i = 0; i < 100; i++) { | |||
if (!t.hasChildren(names[i])) { | |||
t.setChildrenAllowed(names[i], false); | |||
} | |||
} | |||
return t; | |||
} | |||
@@ -144,7 +148,8 @@ public class TestForPreconfiguredComponents extends CustomComponent implements | |||
ol.addComponent(t); | |||
final OrderedLayout ol2 = new OrderedLayout(OrderedLayout.ORIENTATION_HORIZONTAL); | |||
final OrderedLayout ol2 = new OrderedLayout( | |||
OrderedLayout.ORIENTATION_HORIZONTAL); | |||
final Panel status = new Panel("Events"); | |||
final Button clear = new Button("clear event log"); | |||
clear.addListener(new ClickListener() { | |||
@@ -165,9 +170,7 @@ public class TestForPreconfiguredComponents extends CustomComponent implements | |||
t.addListener(new Listener() { | |||
public void componentEvent(Event event) { | |||
status | |||
.addComponent(new Label(event.getClass() | |||
.getName())); | |||
status.addComponent(new Label(event.getClass().getName())); | |||
status.addComponent(new Label("selected: " | |||
+ event.getSource().toString())); | |||
} | |||
@@ -177,16 +180,16 @@ public class TestForPreconfiguredComponents extends CustomComponent implements | |||
} | |||
public Action[] getActions(Object target, Object sender) { | |||
return actions; | |||
return this.actions; | |||
} | |||
public void handleAction(Action action, Object sender, Object target) { | |||
if (action == actions[1]) { | |||
al.addComponent(new Label("Delete selected on " + target)); | |||
contextTree.removeItem(target); | |||
if (action == this.actions[1]) { | |||
this.al.addComponent(new Label("Delete selected on " + target)); | |||
this.contextTree.removeItem(target); | |||
} else { | |||
al.addComponent(new Label("Edit selected on " + target)); | |||
this.al.addComponent(new Label("Edit selected on " + target)); | |||
} | |||
} | |||
} |
@@ -86,7 +86,6 @@ public class TestForUpload extends CustomComponent implements | |||
this.main.addComponent(c); | |||
this.uploadBufferSelector = new Select("Receiver type"); | |||
this.uploadBufferSelector.setColumns(6); | |||
this.uploadBufferSelector.setImmediate(true); | |||
this.uploadBufferSelector.addItem("memory"); | |||
this.uploadBufferSelector.setValue("memory"); |
@@ -2,6 +2,7 @@ package com.itmill.toolkit.tests; | |||
import com.itmill.toolkit.data.Property.ValueChangeEvent; | |||
import com.itmill.toolkit.data.Property.ValueChangeListener; | |||
import com.itmill.toolkit.ui.AbstractSelect; | |||
import com.itmill.toolkit.ui.Button; | |||
import com.itmill.toolkit.ui.CustomComponent; | |||
import com.itmill.toolkit.ui.Label; | |||
@@ -12,60 +13,60 @@ import com.itmill.toolkit.ui.Window; | |||
import com.itmill.toolkit.ui.Button.ClickEvent; | |||
import com.itmill.toolkit.ui.Button.ClickListener; | |||
public class TestForWindowing extends CustomComponent { | |||
public class TestForWindowing extends CustomComponent { | |||
private Select s2; | |||
public TestForWindowing() { | |||
OrderedLayout main = new OrderedLayout(); | |||
main.addComponent(new Label("Click the button to create a new inline window.")); | |||
main.addComponent(new Label( | |||
"Click the button to create a new inline window.")); | |||
Button create = new Button("Create a new window", new ClickListener() { | |||
public void buttonClick(ClickEvent event) { | |||
Window w = new Window("Testing Window"); | |||
Select s1 = new OptionGroup(); | |||
AbstractSelect s1 = new OptionGroup(); | |||
s1.setCaption("1. Select output format"); | |||
s1.addItem("Excel sheet"); | |||
s1.addItem("CSV plain text"); | |||
s1.setValue("Excel sheet"); | |||
s2 = new Select(); | |||
s2.addItem("Separate by comma (,)"); | |||
s2.addItem("Separate by colon (:)"); | |||
s2.addItem("Separate by semicolon (;)"); | |||
s2.setColumns(14); | |||
s2.setEnabled(false); | |||
TestForWindowing.this.s2 = new Select(); | |||
TestForWindowing.this.s2.addItem("Separate by comma (,)"); | |||
TestForWindowing.this.s2.addItem("Separate by colon (:)"); | |||
TestForWindowing.this.s2.addItem("Separate by semicolon (;)"); | |||
TestForWindowing.this.s2.setEnabled(false); | |||
s1.addListener(new ValueChangeListener() { | |||
public void valueChange(ValueChangeEvent event) { | |||
String v = (String) event.getProperty().getValue(); | |||
if(v.equals("CSV plain text")) | |||
s2.setEnabled(true); | |||
else | |||
s2.setEnabled(false); | |||
String v = (String) event.getProperty().getValue(); | |||
if (v.equals("CSV plain text")) { | |||
TestForWindowing.this.s2.setEnabled(true); | |||
} else { | |||
TestForWindowing.this.s2.setEnabled(false); | |||
} | |||
} | |||
}); | |||
w.addComponent(s1); | |||
w.addComponent(s2); | |||
w.addComponent(TestForWindowing.this.s2); | |||
getApplication().getMainWindow().addWindow(w); | |||
} | |||
}); | |||
main.addComponent(create); | |||
setCompositionRoot(main); | |||
} | |||
} | |||
} |
@@ -10,17 +10,17 @@ import com.itmill.toolkit.terminal.PaintException; | |||
import com.itmill.toolkit.terminal.PaintTarget; | |||
/** | |||
* Since TK5 default select is customized component with mane advanced features | |||
* Since TK5 default select is customized component with many advanced features | |||
* over terminals native select components. Sometimes "native" select may still | |||
* be the best option. Terminal renders this select with its native select | |||
* widget. | |||
*/ | |||
public class NativeSelect extends Select { | |||
public class NativeSelect extends AbstractSelect { | |||
public NativeSelect() { | |||
super(); | |||
} | |||
public NativeSelect(String caption, Collection options) { | |||
super(caption, options); | |||
} |
@@ -12,7 +12,7 @@ import com.itmill.toolkit.terminal.PaintTarget; | |||
/** | |||
* Configures select to be used as an option group. | |||
*/ | |||
public class OptionGroup extends Select { | |||
public class OptionGroup extends AbstractSelect { | |||
public OptionGroup() { | |||
super(); |
@@ -57,7 +57,7 @@ import com.itmill.toolkit.terminal.Resource; | |||
* @VERSION@ | |||
* @since 3.0 | |||
*/ | |||
public class Tree extends Select implements Container.Hierarchical, | |||
public class Tree extends AbstractSelect implements Container.Hierarchical, | |||
Action.Container { | |||
/* Static members ***************************************************** */ | |||
@@ -85,7 +85,7 @@ public class Tree extends Select implements Container.Hierarchical, | |||
/** | |||
* Set of expanded nodes. | |||
*/ | |||
private HashSet expanded = new HashSet(); | |||
private final HashSet expanded = new HashSet(); | |||
/** | |||
* List of action handlers. | |||
@@ -156,7 +156,7 @@ public class Tree extends Select implements Container.Hierarchical, | |||
* @return true iff the item is expanded. | |||
*/ | |||
public boolean isExpanded(Object itemId) { | |||
return expanded.contains(itemId); | |||
return this.expanded.contains(itemId); | |||
} | |||
/** | |||
@@ -169,21 +169,24 @@ public class Tree extends Select implements Container.Hierarchical, | |||
public boolean expandItem(Object itemId) { | |||
// Succeeds if the node is already expanded | |||
if (isExpanded(itemId)) | |||
if (isExpanded(itemId)) { | |||
return true; | |||
} | |||
// Nodes that can not have children are not expandable | |||
if (!areChildrenAllowed(itemId)) | |||
if (!areChildrenAllowed(itemId)) { | |||
return false; | |||
} | |||
// Expands | |||
expanded.add(itemId); | |||
this.expanded.add(itemId); | |||
expandedItemId = itemId; | |||
if (initialPaint) | |||
this.expandedItemId = itemId; | |||
if (this.initialPaint) { | |||
requestRepaint(); | |||
else | |||
} else { | |||
requestPartialRepaint(); | |||
} | |||
fireExpandEvent(itemId); | |||
return true; | |||
@@ -191,12 +194,12 @@ public class Tree extends Select implements Container.Hierarchical, | |||
public void requestRepaint() { | |||
super.requestRepaint(); | |||
partialUpdate = false; | |||
this.partialUpdate = false; | |||
} | |||
private void requestPartialRepaint() { | |||
super.requestRepaint(); | |||
partialUpdate = true; | |||
this.partialUpdate = true; | |||
} | |||
/** | |||
@@ -240,11 +243,12 @@ public class Tree extends Select implements Container.Hierarchical, | |||
public boolean collapseItem(Object itemId) { | |||
// Succeeds if the node is already collapsed | |||
if (!isExpanded(itemId)) | |||
if (!isExpanded(itemId)) { | |||
return true; | |||
} | |||
// Collapse | |||
expanded.remove(itemId); | |||
this.expanded.remove(itemId); | |||
requestRepaint(); | |||
fireCollapseEvent(itemId); | |||
@@ -336,9 +340,9 @@ public class Tree extends Select implements Container.Hierarchical, | |||
if (variables.containsKey("collapse")) { | |||
String[] keys = (String[]) variables.get("collapse"); | |||
for (int i = 0; i < keys.length; i++) { | |||
Object id = itemIdMapper.get(keys[i]); | |||
Object id = this.itemIdMapper.get(keys[i]); | |||
if (id != null && isExpanded(id)) { | |||
expanded.remove(id); | |||
this.expanded.remove(id); | |||
fireCollapseEvent(id); | |||
} | |||
} | |||
@@ -348,9 +352,10 @@ public class Tree extends Select implements Container.Hierarchical, | |||
if (variables.containsKey("expand")) { | |||
String[] keys = (String[]) variables.get("expand"); | |||
for (int i = 0; i < keys.length; i++) { | |||
Object id = itemIdMapper.get(keys[i]); | |||
if (id != null) | |||
Object id = this.itemIdMapper.get(keys[i]); | |||
if (id != null) { | |||
expandItem(id); | |||
} | |||
} | |||
} | |||
@@ -363,13 +368,16 @@ public class Tree extends Select implements Container.Hierarchical, | |||
StringTokenizer st = new StringTokenizer((String) variables | |||
.get("action"), ","); | |||
if (st.countTokens() == 2) { | |||
Object itemId = itemIdMapper.get(st.nextToken()); | |||
Action action = (Action) actionMapper.get(st.nextToken()); | |||
Object itemId = this.itemIdMapper.get(st.nextToken()); | |||
Action action = (Action) this.actionMapper.get(st.nextToken()); | |||
if (action != null && containsId(itemId) | |||
&& actionHandlers != null) | |||
for (Iterator i = actionHandlers.iterator(); i.hasNext();) | |||
&& this.actionHandlers != null) { | |||
for (Iterator i = this.actionHandlers.iterator(); i | |||
.hasNext();) { | |||
((Action.Handler) i.next()).handleAction(action, this, | |||
itemId); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
@@ -380,53 +388,60 @@ public class Tree extends Select implements Container.Hierarchical, | |||
* @see com.itmill.toolkit.ui.AbstractComponent#paintContent(PaintTarget) | |||
*/ | |||
public void paintContent(PaintTarget target) throws PaintException { | |||
initialPaint = false; | |||
this.initialPaint = false; | |||
if (partialUpdate) { | |||
if (this.partialUpdate) { | |||
target.addAttribute("partialUpdate", true); | |||
target.addAttribute("rootKey", itemIdMapper.key(expandedItemId)); | |||
target.addAttribute("rootKey", this.itemIdMapper | |||
.key(this.expandedItemId)); | |||
} else { | |||
// Focus control id | |||
if (this.getFocusableId() > 0) { | |||
target.addAttribute("focusid", this.getFocusableId()); | |||
if (getFocusableId() > 0) { | |||
target.addAttribute("focusid", getFocusableId()); | |||
} | |||
// The tab ordering number | |||
if (this.getTabIndex() > 0) | |||
target.addAttribute("tabindex", this.getTabIndex()); | |||
if (getTabIndex() > 0) { | |||
target.addAttribute("tabindex", getTabIndex()); | |||
} | |||
// Paint tree attributes | |||
if (isSelectable()) | |||
if (isSelectable()) { | |||
target.addAttribute("selectmode", (isMultiSelect() ? "multi" | |||
: "single")); | |||
else | |||
} else { | |||
target.addAttribute("selectmode", "none"); | |||
if (isNewItemsAllowed()) | |||
} | |||
if (isNewItemsAllowed()) { | |||
target.addAttribute("allownewitem", true); | |||
} | |||
} | |||
// Initialize variables | |||
Set actionSet = new LinkedHashSet(); | |||
String[] selectedKeys; | |||
if (isMultiSelect()) | |||
if (isMultiSelect()) { | |||
selectedKeys = new String[((Set) getValue()).size()]; | |||
else | |||
} else { | |||
selectedKeys = new String[(getValue() == null ? 0 : 1)]; | |||
} | |||
int keyIndex = 0; | |||
LinkedList expandedKeys = new LinkedList(); | |||
// Iterates through hierarchical tree using a stack of iterators | |||
Stack iteratorStack = new Stack(); | |||
Collection ids; | |||
if (partialUpdate) | |||
ids = getChildren(expandedItemId); | |||
else | |||
if (this.partialUpdate) { | |||
ids = getChildren(this.expandedItemId); | |||
} else { | |||
ids = rootItemIds(); | |||
} | |||
if (ids != null) | |||
if (ids != null) { | |||
iteratorStack.push(ids.iterator()); | |||
} | |||
while (!iteratorStack.isEmpty()) { | |||
@@ -440,8 +455,9 @@ public class Tree extends Select implements Container.Hierarchical, | |||
iteratorStack.pop(); | |||
// Closes node | |||
if (!iteratorStack.isEmpty()) | |||
if (!iteratorStack.isEmpty()) { | |||
target.endTag("node"); | |||
} | |||
} | |||
// Adds the item on current level | |||
@@ -451,17 +467,19 @@ public class Tree extends Select implements Container.Hierarchical, | |||
// Starts the item / node | |||
boolean isNode = areChildrenAllowed(itemId) | |||
&& hasChildren(itemId); | |||
if (isNode) | |||
if (isNode) { | |||
target.startTag("node"); | |||
else | |||
} else { | |||
target.startTag("leaf"); | |||
} | |||
// Adds the attributes | |||
target.addAttribute("caption", getItemCaption(itemId)); | |||
Resource icon = getItemIcon(itemId); | |||
if (icon != null) | |||
if (icon != null) { | |||
target.addAttribute("icon", getItemIcon(itemId)); | |||
String key = itemIdMapper.key(itemId); | |||
} | |||
String key = this.itemIdMapper.key(itemId); | |||
target.addAttribute("key", key); | |||
if (isSelected(itemId)) { | |||
target.addAttribute("selected", true); | |||
@@ -473,18 +491,19 @@ public class Tree extends Select implements Container.Hierarchical, | |||
} | |||
// Actions | |||
if (actionHandlers != null) { | |||
if (this.actionHandlers != null) { | |||
ArrayList keys = new ArrayList(); | |||
for (Iterator ahi = actionHandlers.iterator(); ahi | |||
for (Iterator ahi = this.actionHandlers.iterator(); ahi | |||
.hasNext();) { | |||
Action[] aa = ((Action.Handler) ahi.next()).getActions( | |||
itemId, this); | |||
if (aa != null) | |||
if (aa != null) { | |||
for (int ai = 0; ai < aa.length; ai++) { | |||
String akey = actionMapper.key(aa[ai]); | |||
String akey = this.actionMapper.key(aa[ai]); | |||
actionSet.add(aa[ai]); | |||
keys.add(akey); | |||
} | |||
} | |||
} | |||
target.addAttribute("al", keys.toArray()); | |||
} | |||
@@ -494,10 +513,11 @@ public class Tree extends Select implements Container.Hierarchical, | |||
&& areChildrenAllowed(itemId)) { | |||
iteratorStack.push(getChildren(itemId).iterator()); | |||
} else { | |||
if (isNode) | |||
if (isNode) { | |||
target.endTag("node"); | |||
else | |||
} else { | |||
target.endTag("leaf"); | |||
} | |||
} | |||
} | |||
} | |||
@@ -509,18 +529,20 @@ public class Tree extends Select implements Container.Hierarchical, | |||
for (Iterator i = actionSet.iterator(); i.hasNext();) { | |||
Action a = (Action) i.next(); | |||
target.startTag("action"); | |||
if (a.getCaption() != null) | |||
if (a.getCaption() != null) { | |||
target.addAttribute("caption", a.getCaption()); | |||
if (a.getIcon() != null) | |||
} | |||
if (a.getIcon() != null) { | |||
target.addAttribute("icon", a.getIcon()); | |||
target.addAttribute("key", actionMapper.key(a)); | |||
} | |||
target.addAttribute("key", this.actionMapper.key(a)); | |||
target.endTag("action"); | |||
} | |||
target.endTag("actions"); | |||
} | |||
if (partialUpdate) { | |||
partialUpdate = false; | |||
if (this.partialUpdate) { | |||
this.partialUpdate = false; | |||
} else { | |||
// Selected | |||
target.addVariable(this, "selected", selectedKeys); | |||
@@ -542,7 +564,7 @@ public class Tree extends Select implements Container.Hierarchical, | |||
* @see com.itmill.toolkit.data.Container.Hierarchical#areChildrenAllowed(Object) | |||
*/ | |||
public boolean areChildrenAllowed(Object itemId) { | |||
return ((Container.Hierarchical) items).areChildrenAllowed(itemId); | |||
return ((Container.Hierarchical) this.items).areChildrenAllowed(itemId); | |||
} | |||
/** | |||
@@ -551,7 +573,7 @@ public class Tree extends Select implements Container.Hierarchical, | |||
* @see com.itmill.toolkit.data.Container.Hierarchical#getChildren(Object) | |||
*/ | |||
public Collection getChildren(Object itemId) { | |||
return ((Container.Hierarchical) items).getChildren(itemId); | |||
return ((Container.Hierarchical) this.items).getChildren(itemId); | |||
} | |||
/** | |||
@@ -560,7 +582,7 @@ public class Tree extends Select implements Container.Hierarchical, | |||
* @see com.itmill.toolkit.data.Container.Hierarchical#getParent(Object) | |||
*/ | |||
public Object getParent(Object itemId) { | |||
return ((Container.Hierarchical) items).getParent(itemId); | |||
return ((Container.Hierarchical) this.items).getParent(itemId); | |||
} | |||
/** | |||
@@ -570,7 +592,7 @@ public class Tree extends Select implements Container.Hierarchical, | |||
* @see com.itmill.toolkit.data.Container.Hierarchical#hasChildren(Object) | |||
*/ | |||
public boolean hasChildren(Object itemId) { | |||
return ((Container.Hierarchical) items).hasChildren(itemId); | |||
return ((Container.Hierarchical) this.items).hasChildren(itemId); | |||
} | |||
/** | |||
@@ -579,7 +601,7 @@ public class Tree extends Select implements Container.Hierarchical, | |||
* @see com.itmill.toolkit.data.Container.Hierarchical#isRoot(Object) | |||
*/ | |||
public boolean isRoot(Object itemId) { | |||
return ((Container.Hierarchical) items).isRoot(itemId); | |||
return ((Container.Hierarchical) this.items).isRoot(itemId); | |||
} | |||
/** | |||
@@ -588,7 +610,7 @@ public class Tree extends Select implements Container.Hierarchical, | |||
* @see com.itmill.toolkit.data.Container.Hierarchical#rootItemIds() | |||
*/ | |||
public Collection rootItemIds() { | |||
return ((Container.Hierarchical) items).rootItemIds(); | |||
return ((Container.Hierarchical) this.items).rootItemIds(); | |||
} | |||
/** | |||
@@ -598,10 +620,11 @@ public class Tree extends Select implements Container.Hierarchical, | |||
* boolean) | |||
*/ | |||
public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed) { | |||
boolean success = ((Container.Hierarchical) items).setChildrenAllowed( | |||
itemId, areChildrenAllowed); | |||
if (success) | |||
boolean success = ((Container.Hierarchical) this.items) | |||
.setChildrenAllowed(itemId, areChildrenAllowed); | |||
if (success) { | |||
fireValueChange(false); | |||
} | |||
return success; | |||
} | |||
@@ -612,10 +635,11 @@ public class Tree extends Select implements Container.Hierarchical, | |||
* Object) | |||
*/ | |||
public boolean setParent(Object itemId, Object newParentId) { | |||
boolean success = ((Container.Hierarchical) items).setParent(itemId, | |||
newParentId); | |||
if (success) | |||
boolean success = ((Container.Hierarchical) this.items).setParent( | |||
itemId, newParentId); | |||
if (success) { | |||
requestRepaint(); | |||
} | |||
return success; | |||
} | |||
@@ -631,11 +655,12 @@ public class Tree extends Select implements Container.Hierarchical, | |||
// Assure that the data source is ordered by making unordered | |||
// containers ordered by wrapping them | |||
if (Container.Hierarchical.class.isAssignableFrom(newDataSource | |||
.getClass())) | |||
.getClass())) { | |||
super.setContainerDataSource(newDataSource); | |||
else | |||
} else { | |||
super.setContainerDataSource(new ContainerHierarchicalWrapper( | |||
newDataSource)); | |||
} | |||
} | |||
/* Expand event and listener ****************************************** */ | |||
@@ -657,7 +682,7 @@ public class Tree extends Select implements Container.Hierarchical, | |||
*/ | |||
private static final long serialVersionUID = 3832624001804481075L; | |||
private Object expandedItemId; | |||
private final Object expandedItemId; | |||
/** | |||
* New instance of options change event | |||
@@ -747,7 +772,7 @@ public class Tree extends Select implements Container.Hierarchical, | |||
*/ | |||
private static final long serialVersionUID = 3257009834783290160L; | |||
private Object collapsedItemId; | |||
private final Object collapsedItemId; | |||
/** | |||
* New instance of options change event. | |||
@@ -767,7 +792,7 @@ public class Tree extends Select implements Container.Hierarchical, | |||
* @return the collapsed item id. | |||
*/ | |||
public Object getItemId() { | |||
return collapsedItemId; | |||
return this.collapsedItemId; | |||
} | |||
} | |||
@@ -831,13 +856,13 @@ public class Tree extends Select implements Container.Hierarchical, | |||
if (actionHandler != null) { | |||
if (actionHandlers == null) { | |||
actionHandlers = new LinkedList(); | |||
actionMapper = new KeyMapper(); | |||
if (this.actionHandlers == null) { | |||
this.actionHandlers = new LinkedList(); | |||
this.actionMapper = new KeyMapper(); | |||
} | |||
if (!actionHandlers.contains(actionHandler)) { | |||
actionHandlers.add(actionHandler); | |||
if (!this.actionHandlers.contains(actionHandler)) { | |||
this.actionHandlers.add(actionHandler); | |||
requestRepaint(); | |||
} | |||
} | |||
@@ -850,13 +875,14 @@ public class Tree extends Select implements Container.Hierarchical, | |||
*/ | |||
public void removeActionHandler(Action.Handler actionHandler) { | |||
if (actionHandlers != null && actionHandlers.contains(actionHandler)) { | |||
if (this.actionHandlers != null | |||
&& this.actionHandlers.contains(actionHandler)) { | |||
actionHandlers.remove(actionHandler); | |||
this.actionHandlers.remove(actionHandler); | |||
if (actionHandlers.isEmpty()) { | |||
actionHandlers = null; | |||
actionMapper = null; | |||
if (this.actionHandlers.isEmpty()) { | |||
this.actionHandlers = null; | |||
this.actionMapper = null; | |||
} | |||
requestRepaint(); | |||
@@ -875,8 +901,9 @@ public class Tree extends Select implements Container.Hierarchical, | |||
// Iterates trough hierarchical tree using a stack of iterators | |||
Stack iteratorStack = new Stack(); | |||
Collection ids = rootItemIds(); | |||
if (ids != null) | |||
if (ids != null) { | |||
iteratorStack.push(ids.iterator()); | |||
} | |||
while (!iteratorStack.isEmpty()) { | |||
// Gets the iterator for current tree level | |||
@@ -914,8 +941,9 @@ public class Tree extends Select implements Container.Hierarchical, | |||
*/ | |||
public void setNewItemsAllowed(boolean allowNewOptions) | |||
throws UnsupportedOperationException { | |||
if (allowNewOptions) | |||
if (allowNewOptions) { | |||
throw new UnsupportedOperationException(); | |||
} | |||
} | |||
/** | |||
@@ -936,9 +964,10 @@ public class Tree extends Select implements Container.Hierarchical, | |||
* @see com.itmill.toolkit.ui.Select#setLazyLoading(boolean) | |||
*/ | |||
public void setLazyLoading(boolean useLazyLoading) { | |||
if (useLazyLoading) | |||
if (useLazyLoading) { | |||
throw new UnsupportedOperationException( | |||
"Lazy options loading is not supported by Tree."); | |||
} | |||
} | |||
} |
@@ -10,10 +10,10 @@ import com.itmill.toolkit.terminal.PaintException; | |||
import com.itmill.toolkit.terminal.PaintTarget; | |||
/** | |||
* Multiselect component with two lists: left side for available items and right side for | |||
* selected items. | |||
* Multiselect component with two lists: left side for available items and right | |||
* side for selected items. | |||
*/ | |||
public class TwinColSelect extends Select { | |||
public class TwinColSelect extends AbstractSelect { | |||
/** | |||
* |
@@ -1,71 +0,0 @@ | |||
package com.itmill.toolkit.ui.select; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import com.itmill.toolkit.data.Item; | |||
import com.itmill.toolkit.ui.Select; | |||
public class ContainsFilter implements OptionFilter { | |||
private Select s; | |||
private ArrayList filteredItemsBuffer; | |||
private String prevFilter; | |||
public ContainsFilter(Select s) { | |||
this.s = s; | |||
} | |||
public List filter(String filterstring, int pageLength, int page) { | |||
if (filterstring == null) { | |||
filterstring = ""; | |||
} | |||
if (this.prevFilter != filterstring || filteredItemsBuffer == null) { | |||
if ("".equals(filterstring)) { | |||
this.filteredItemsBuffer = new ArrayList(s.getItemIds()); | |||
} else if (s.getContainerDataSource() != null) { | |||
// prefix MUST be in lowercase | |||
filterstring = filterstring.toLowerCase(); | |||
// all items will be iterated and tested. | |||
// SLOW when there are lot of items. | |||
this.filteredItemsBuffer = new ArrayList(); | |||
for (Iterator iter = s.getItemIds().iterator(); iter.hasNext();) { | |||
Object id = iter.next(); | |||
Item item = s.getItem(id); | |||
String test = ""; | |||
if (s.getItemCaptionMode() == Select.ITEM_CAPTION_MODE_PROPERTY) | |||
test = item.getItemProperty( | |||
s.getItemCaptionPropertyId()).getValue() | |||
.toString().trim(); | |||
else | |||
test = String.valueOf(id); | |||
if (test.toLowerCase().indexOf(filterstring) > -1) { | |||
this.filteredItemsBuffer.add(id); | |||
} | |||
} | |||
} | |||
} | |||
prevFilter = filterstring; | |||
if (filteredItemsBuffer.size() > pageLength) { | |||
int first = page * pageLength; | |||
int last = first + pageLength; | |||
if (filteredItemsBuffer.size() < last) { | |||
last = filteredItemsBuffer.size(); | |||
} | |||
return filteredItemsBuffer.subList(first, last); | |||
} else { | |||
return filteredItemsBuffer; | |||
} | |||
} | |||
public int getMatchCount() { | |||
return filteredItemsBuffer.size(); | |||
} | |||
} |
@@ -1,20 +0,0 @@ | |||
package com.itmill.toolkit.ui.select; | |||
import java.util.List; | |||
public interface OptionFilter { | |||
/** | |||
* | |||
* @param filterstring | |||
* string to use in filtering | |||
* @return List of filtered item id's | |||
*/ | |||
public List filter(String filterstring, int pageLength, int page); | |||
/** | |||
* Returns total matches in last filtering process | |||
* | |||
* @return | |||
*/ | |||
public int getMatchCount(); | |||
} |
@@ -1,71 +0,0 @@ | |||
package com.itmill.toolkit.ui.select; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import com.itmill.toolkit.data.Item; | |||
import com.itmill.toolkit.ui.Select; | |||
public class StartsWithFilter implements OptionFilter { | |||
private Select s; | |||
public StartsWithFilter(Select s) { | |||
this.s = s; | |||
} | |||
ArrayList filteredItemsBuffer; | |||
private String prevFilter; | |||
public List filter(String filterstring, int pageLength, int page) { | |||
if (filterstring == null) { | |||
filterstring = ""; | |||
} | |||
if (this.prevFilter != filterstring || filteredItemsBuffer == null) { | |||
if ("".equals(filterstring)) { | |||
this.filteredItemsBuffer = new ArrayList(s.getItemIds()); | |||
} else if (s.getContainerDataSource() != null) { | |||
// prefix MUST be in lowercase | |||
filterstring = filterstring.toLowerCase(); | |||
// all items will be iterated and tested. | |||
// SLOW when there are lot of items. | |||
this.filteredItemsBuffer = new ArrayList(); | |||
for (Iterator iter = s.getItemIds().iterator(); iter.hasNext();) { | |||
Object id = iter.next(); | |||
Item item = s.getItem(id); | |||
String test = ""; | |||
if (s.getItemCaptionMode() == Select.ITEM_CAPTION_MODE_PROPERTY) | |||
test = item.getItemProperty( | |||
s.getItemCaptionPropertyId()).getValue() | |||
.toString().trim(); | |||
else | |||
test = String.valueOf(id); | |||
if (test.toLowerCase().startsWith(filterstring)) { | |||
this.filteredItemsBuffer.add(id); | |||
} | |||
} | |||
} | |||
} | |||
prevFilter = filterstring; | |||
if (filteredItemsBuffer.size() > pageLength) { | |||
int first = page * pageLength; | |||
int last = first + pageLength; | |||
if (filteredItemsBuffer.size() < last) { | |||
last = filteredItemsBuffer.size(); | |||
} | |||
return filteredItemsBuffer.subList(first, last); | |||
} else { | |||
return filteredItemsBuffer; | |||
} | |||
} | |||
public int getMatchCount() { | |||
return filteredItemsBuffer.size(); | |||
} | |||
} |