Created
May 8, 2017 20:43
-
-
Save alump/21234dbc45a612ba00b200eef714c395 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.vaadin.alump.extendedtabsheet.demo; | |
import com.vaadin.icons.VaadinIcons; | |
import com.vaadin.server.Resource; | |
import com.vaadin.shared.ui.tabsheet.TabsheetClientRpc; | |
import com.vaadin.ui.Component; | |
import com.vaadin.ui.Label; | |
import com.vaadin.ui.TabSheet; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Objects; | |
import java.util.stream.Collectors; | |
/** | |
* Tab Sheet with plus tab for adding new tabs. Allows to close tabs if there are more than 1 open tab. Should not be | |
* used without any actual tabs. | |
*/ | |
public class TabSheetWithAdd extends TabSheet { | |
private Tab plusTab; | |
private boolean plusTabEnabled = true; | |
private AddTabHandler addTabHandler; | |
@FunctionalInterface | |
public interface AddTabHandler { | |
/** | |
* Method called when user has clicked "new tab" tab | |
* @param source TabSheet that was clicked | |
* @return Tab handler added to Tabsheet, receive this by calling addTab method | |
*/ | |
Tab newTabRequested(TabSheetWithAdd source); | |
} | |
public TabSheetWithAdd() { | |
super(); | |
addStyleName("tabsheet-with-add"); | |
super.setCloseHandler(this::onClose); | |
} | |
public TabSheetWithAdd(AddTabHandler addTabHandler) { | |
this(); | |
setAddTabHandler(Objects.requireNonNull(addTabHandler)); | |
} | |
@Override | |
public void attach() { | |
super.attach(); | |
} | |
@Override | |
public void beforeClientResponse(boolean initial) { | |
updateStateBeforeClientResponse(); | |
super.beforeClientResponse(initial); | |
} | |
private void onClose(TabSheet tabSheet, Component component) { | |
removeComponent(component); | |
if(getTabs().size() < 2) { | |
getTabs().stream().forEach(t -> t.setClosable(false)); | |
} | |
} | |
protected void updateStateBeforeClientResponse() { | |
List<Tab> tabs = getTabs(); | |
// Never allow to close the last tab | |
if(tabs.size() <= 1) { | |
tabs.stream().forEach(t -> t.setClosable(false)); | |
} else { | |
tabs.stream().forEach(t -> t.setClosable(true)); | |
} | |
// Never allow plus tab to be selected | |
if(plusTab != null && getSelectedTab() == plusTab.getComponent()) { | |
setSelectedTab(0); | |
} | |
} | |
@Override | |
public Tab addTab(Component c, String caption) { | |
removePlusTab(); | |
Tab tab = super.addTab(c, caption); | |
addPlusTab(); | |
return tab; | |
} | |
@Override | |
public Tab addTab(Component c, String caption, Resource icon) { | |
removePlusTab(); | |
Tab tab = super.addTab(c, caption, icon); | |
addPlusTab(); | |
return tab; | |
} | |
@Override | |
public Tab addTab(Component tabComponent, String caption, Resource icon, | |
int position) { | |
removePlusTab(); | |
Tab tab = super.addTab(tabComponent, caption, icon, position); | |
addPlusTab(); | |
return tab; | |
} | |
@Override | |
public Tab addTab(Component component) { | |
removePlusTab(); | |
Tab tab = super.addTab(component); | |
addPlusTab(); | |
return tab; | |
} | |
@Override | |
public Tab addTab(Component component, int position) { | |
removePlusTab(); | |
Tab tab = super.addTab(component, position); | |
addPlusTab(); | |
return tab; | |
} | |
@Override | |
public void setSelectedTab(Component c) { | |
if(plusTab != null && c == plusTab.getComponent()) { | |
if(addTabHandler != null) { | |
Tab tab = addTabHandler.newTabRequested(this); | |
if(tab != null) { | |
setSelectedTab(tab); | |
} else { | |
getRpcProxy(TabsheetClientRpc.class).revertToSharedStateSelection(); | |
} | |
} else { | |
removePlusTab(); | |
} | |
} else { | |
super.setSelectedTab(c); | |
} | |
} | |
protected void removePlusTab() { | |
if(plusTab != null) { | |
boolean wasPlusSelected = getSelectedTab() == plusTab.getComponent(); | |
super.removeTab(plusTab); | |
plusTab = null; | |
if(wasPlusSelected && getComponentCount() > 0) { | |
setSelectedTab(0); | |
} | |
} | |
} | |
protected void addPlusTab() { | |
removePlusTab(); | |
if(plusTabEnabled) { | |
plusTab = super.addTab(createPlusComponent(), null, VaadinIcons.PLUS, getComponentCount()); | |
} | |
} | |
/** | |
* Get tabs on TabSheet (plus tab is filtered out of this list) | |
* @return | |
*/ | |
public List<Tab> getTabs() { | |
List<Tab> tabs = new ArrayList<>(); | |
Tab tab = getTab(0); | |
for(int i = 1; tab != null; ++i) { | |
if(tab != plusTab) { | |
tabs.add(tab); | |
} | |
tab = getTab(i); | |
} | |
return tabs; | |
} | |
/** | |
* Get filtered list of children inside tabs | |
* @return | |
*/ | |
public List<Component> getTabChildren() { | |
return getTabs().stream().map(t -> t.getComponent()).collect(Collectors.toList()); | |
} | |
/** | |
* Add new handler for New tab requests | |
* @param addTabHandler Handler used to add new tabs | |
*/ | |
public void setAddTabHandler(AddTabHandler addTabHandler) { | |
this.addTabHandler = addTabHandler; | |
} | |
/** | |
* Component placed inside close tab, it should not be shown to user evernd | |
* @return | |
*/ | |
protected Component createPlusComponent() { | |
return new Label("User should not see this"); | |
} | |
public void setPlusTabEnabled(boolean enabled) { | |
plusTabEnabled = enabled; | |
addPlusTab(); | |
} | |
public boolean isPlusTabEnabled() { | |
return plusTabEnabled; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment