Java tutorial
/* * Copyright (C) 2009 Paul Stoellberger * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package org.pentaho.pat.client.ui.panels.windows; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.gwt.mosaic.ui.client.ComboBox; import org.gwt.mosaic.ui.client.LayoutComposite; import org.gwt.mosaic.ui.client.ListBox; import org.gwt.mosaic.ui.client.MessageBox; import org.gwt.mosaic.ui.client.ScrollLayoutPanel; import org.gwt.mosaic.ui.client.TabLayoutPanel; import org.gwt.mosaic.ui.client.ListBox.CellRenderer; import org.gwt.mosaic.ui.client.layout.BoxLayout; import org.gwt.mosaic.ui.client.layout.BoxLayoutData; import org.gwt.mosaic.ui.client.layout.LayoutPanel; import org.gwt.mosaic.ui.client.layout.BoxLayout.Orientation; import org.gwt.mosaic.ui.client.layout.BoxLayoutData.FillStyle; import org.gwt.mosaic.ui.client.list.DefaultComboBoxModel; import org.gwt.mosaic.ui.client.list.DefaultListModel; import org.gwt.mosaic.ui.client.list.Filter; import org.gwt.mosaic.ui.client.list.FilterProxyListModel; import org.pentaho.pat.client.Pat; import org.pentaho.pat.client.Application.ApplicationImages; import org.pentaho.pat.client.ui.widgets.MemberSelectionLabel; import org.pentaho.pat.client.util.factory.MessageFactory; import org.pentaho.pat.client.util.factory.ServiceFactory; import org.pentaho.pat.rpc.dto.StringTree; import org.pentaho.pat.rpc.dto.query.IAxis; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.KeyPressEvent; import com.google.gwt.event.dom.client.KeyPressHandler; import com.google.gwt.event.logical.shared.SelectionEvent; import com.google.gwt.event.logical.shared.SelectionHandler; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.Tree; import com.google.gwt.user.client.ui.TreeItem; /** * Tree list of connections and cubes. * * @created Aug 18, 2009 * @since 0.5.0 * @author Paul Stoellberger * */ public class DimensionMenu extends LayoutComposite { /** The main menu. */ private final Tree dimensionTree; private final ComboBox<String> sortComboBox = new ComboBox<String>(); private final DefaultComboBoxModel<String> sortModeModel = (DefaultComboBoxModel<String>) sortComboBox .getModel(); // private final ComboBox<String> hierarchyComboBox = new ComboBox<String>(); // private final DefaultComboBoxModel<String> hierarchyModeModel = (DefaultComboBoxModel<String>) // hierarchyComboBox.getModel(); private final DefaultListModel<MemberSelectionLabel> memberListBoxModel = new DefaultListModel<MemberSelectionLabel>(); private final ListBox<MemberSelectionLabel> memberListBox = new ListBox<MemberSelectionLabel>( new String[] { Pat.CONSTANTS.member(), Pat.CONSTANTS.path() }); private FilterProxyListModel<MemberSelectionLabel, String> filterModel; private final TextBox filterbox = new TextBox(); private final static String DIMENSION_MENU = "pat-DimensionMenu"; //$NON-NLS-1$ private final Timer filterTimer = new Timer() { @Override public void run() { filterModel.filter(filterbox.getText()); } }; // final DefaultComboBoxModel<String> model2 = (DefaultComboBoxModel<String>) hierarchyComboBox.getModel(); /** * * DimensionMenu Constructor. * */ public DimensionMenu() { super(); this.setStyleName(DIMENSION_MENU); final LayoutPanel baseLayoutPanel = getLayoutPanel(); baseLayoutPanel.setLayout(new BoxLayout(Orientation.VERTICAL)); final ApplicationImages treeImages = GWT.create(ApplicationImages.class); dimensionTree = new Tree(treeImages); dimensionTree.setAnimationEnabled(false); // dimensionTree.setWidth("300px"); //$NON-NLS-1$ memberListBox.setColumnTruncatable(0, false); memberListBox.setColumnTruncatable(1, false); // memberListBox.setWidth("500px"); //$NON-NLS-1$ memberListBox.setCellRenderer(new CellRenderer<MemberSelectionLabel>() { public void renderCell(final ListBox<MemberSelectionLabel> listBox, final int row, final int column, final MemberSelectionLabel item) { switch (column) { case 0: listBox.setWidget(row, column, item); break; case 1: final StringBuffer buf = new StringBuffer(); for (int i = 0; i < item.getFullPath().length; i++) { buf.append(item.getFullPath()[i]); if ((i + 1) < item.getFullPath().length) { buf.append("->"); //$NON-NLS-1$ } } final String path = buf.toString(); listBox.setText(row, column, path); break; default: throw new RuntimeException(MessageFactory.getInstance().unexpectedError()); } } }); //dimensionTree.addStyleName(Pat.DEF_STYLE_NAME + "-cubemenu"); //$NON-NLS-1$ final LayoutPanel filterPanel = new LayoutPanel(new BoxLayout(Orientation.HORIZONTAL)); filterbox.addKeyPressHandler(new KeyPressHandler() { public void onKeyPress(final KeyPressEvent event) { filterTimer.schedule(300); } }); final Label filterText = new Label(Pat.CONSTANTS.filter() + ":"); //$NON-NLS-1$ filterPanel.add(filterText, new BoxLayoutData(FillStyle.VERTICAL)); filterPanel.add(filterbox, new BoxLayoutData(FillStyle.BOTH)); sortModeModel.add(Pat.CONSTANTS.sortAscending()); sortModeModel.add(Pat.CONSTANTS.sortDescending()); sortModeModel.add(Pat.CONSTANTS.sortBreakAscending()); sortModeModel.add(Pat.CONSTANTS.sortBreakDescending()); sortComboBox.addChangeHandler(new ChangeHandler() { public void onChange(final ChangeEvent arg0) { String scb; switch (sortComboBox.getSelectedIndex()) { case 0: scb = "ASC"; //$NON-NLS-1$ break; case 1: scb = "DESC"; //$NON-NLS-1$ break; case 2: scb = "BASC"; //$NON-NLS-1$ break; case 3: scb = "BDESC"; //$NON-NLS-1$ break; default: throw new RuntimeException(MessageFactory.getInstance().unexpectedError()); } for (int k = 0; k < dimensionTree.getItemCount(); k++) { ServiceFactory.getQueryInstance().setSortOrder(Pat.getSessionID(), Pat.getCurrQuery(), dimensionTree.getItem(k).getText(), scb, new AsyncCallback<Object>() { public void onFailure(final Throwable arg0) { MessageBox.error(Pat.CONSTANTS.error(), Pat.CONSTANTS.sortFailed()); } public void onSuccess(final Object arg0) { /** * On Success do nothing */ } }); } } }); /* * hierarchyModeModel.add(Pat.CONSTANTS.pre()); * hierarchyModeModel.add(Pat.CONSTANTS.post()); * * hierarchyComboBox.addChangeHandler(new ChangeHandler() { public void onChange(final ChangeEvent arg0) { * String hcb = new String(); switch (hierarchyComboBox.getSelectedIndex()){ case 0: hcb = "PRE"; //$NON-NLS-1$ * break; case 1: hcb = "POST"; //$NON-NLS-1$ break; default: throw new * RuntimeException(MessageFactory.getInstance().unexpectedError()); } * ServiceFactory.getQueryInstance().setHierarchizeMode(Pat.getSessionID(), Pat.getCurrQuery(), * dimensionLabel.getText(), hcb, new AsyncCallback<Object>() { * * public void onFailure(final Throwable arg0) { MessageBox.error(Pat.CONSTANTS.error(), * Pat.CONSTANTS.hierarchizeFailed()); } * * public void onSuccess(final Object arg0) { * * } * * }); * * } * * }); */ final LayoutPanel sortLayout = new LayoutPanel(new BoxLayout(Orientation.HORIZONTAL)); sortLayout.add(new Label(Pat.CONSTANTS.sort())); sortLayout.add(sortComboBox, new BoxLayoutData(FillStyle.HORIZONTAL)); baseLayoutPanel.add(sortLayout); // baseLayoutPanel.add(hierarchyComboBox, new BoxLayoutData(FillStyle.HORIZONTAL)); final ScrollLayoutPanel dimTreeScrollPanel = new ScrollLayoutPanel(new BoxLayout(Orientation.HORIZONTAL)); dimTreeScrollPanel.setAnimationEnabled(true); // TODO this needs a proper fix, it just means that the scrollpanel and the dimensiontree will // have the same background (if you expand it will look weird otherwise) dimTreeScrollPanel.setStyleName(dimensionTree.getStyleName()); dimTreeScrollPanel.add(dimensionTree, new BoxLayoutData(FillStyle.BOTH)); dimensionTree.addSelectionHandler(new SelectionHandler<TreeItem>() { public void onSelection(final SelectionEvent<TreeItem> arg0) { dimensionTree.ensureSelectedItemVisible(); } }); final LayoutPanel groupPanel = new LayoutPanel(new BoxLayout(Orientation.VERTICAL)); groupPanel.add(filterPanel, new BoxLayoutData(FillStyle.HORIZONTAL)); groupPanel.add(memberListBox, new BoxLayoutData(FillStyle.BOTH)); TabLayoutPanel tabPanel = new TabLayoutPanel(); tabPanel.add(groupPanel, Pat.CONSTANTS.flat()); tabPanel.add(dimTreeScrollPanel, Pat.CONSTANTS.hierarchical()); tabPanel.selectTab(0); // groupPanel.add(dimTreeScrollPanel, new BoxLayoutData(FillStyle.BOTH, true)); baseLayoutPanel.add(tabPanel, new BoxLayoutData(FillStyle.BOTH)); } /** * Empties filter textbox when being attached */ @Override protected void onAttach() { super.onAttach(); filterbox.setText(""); //$NON-NLS-1$ }; public Tree getDimensionTree() { return dimensionTree; } /** * Loads all Members * * @param queryId * - Query to use to discover dimension members */ public final void loadAllMembers(final String queryId) { dimensionTree.clear(); memberListBoxModel.clear(); filterModel = new FilterProxyListModel<MemberSelectionLabel, String>(memberListBoxModel); memberListBox.setModel(filterModel); loadAxisMembers(queryId, IAxis.COLUMNS, false); loadAxisMembers(queryId, IAxis.ROWS, false); loadAxisMembers(queryId, IAxis.FILTER, false); loadAxisMembers(queryId, IAxis.UNUSED, false); } /** * Loads all Members of a given axis and query * * @param queryId * - Query to use to discover dimension members * @param targetAxis * - Axis of interest * @param empty * - empty before populating */ public final void loadAxisMembers(final String queryId, final IAxis targetAxis, final Boolean empty) { if (empty) { dimensionTree.clear(); memberListBoxModel.clear(); filterModel = new FilterProxyListModel<MemberSelectionLabel, String>(memberListBoxModel); memberListBox.setModel(filterModel); } ServiceFactory.getDiscoveryInstance().getDimensions(Pat.getSessionID(), Pat.getCurrQuery(), targetAxis, new AsyncCallback<String[]>() { public void onFailure(Throwable arg0) { dimensionTree.clear(); MessageBox.error(Pat.CONSTANTS.error(), MessageFactory.getInstance().failedMemberFetch(arg0.getLocalizedMessage())); } public void onSuccess(String[] dimensionList) { for (int i = 0; i < dimensionList.length; i++) { loadMembers(Pat.getCurrQuery(), dimensionList[i], false); } } }); } /** * Loads all Members of a given dimension and query * * @param queryId * - Query to use to discover dimension members * @param dimensionId * - Dimension of interest * @param empty * - empty before populating */ public final void loadMembers(final String queryId, final String dimensionId, final Boolean empty) { if (empty) { dimensionTree.clear(); memberListBoxModel.clear(); filterModel = new FilterProxyListModel<MemberSelectionLabel, String>(memberListBoxModel); memberListBox.setModel(filterModel); } ServiceFactory.getDiscoveryInstance().getMembers(Pat.getSessionID(), queryId, dimensionId, new AsyncCallback<StringTree>() { public void onFailure(final Throwable arg0) { dimensionTree.clear(); MessageBox.error(Pat.CONSTANTS.error(), MessageFactory.getInstance().failedMemberFetch(arg0.getLocalizedMessage())); } public void onSuccess(final StringTree labels) { final Label dimensionLabel = new Label(labels.getValue()); final TreeItem parent = dimensionTree.addItem(dimensionLabel); ServiceFactory.getQueryInstance().getSelection(Pat.getSessionID(), Pat.getCurrQuery(), dimensionLabel.getText(), new AsyncCallback<String[][]>() { public void onFailure(final Throwable arg0) { MessageBox.error(Pat.CONSTANTS.error(), MessageFactory.getInstance() .failedMemberFetch(arg0.getLocalizedMessage())); } public void onSuccess(final String[][] selectionlist) { ServiceFactory.getQueryInstance().getSortOrder(Pat.getSessionID(), Pat.getCurrQuery(), dimensionId, new AsyncCallback<String>() { public void onFailure(final Throwable arg0) { MessageBox.error(Pat.CONSTANTS.error(), MessageFactory.getInstance().failedGetSort()); } public void onSuccess(final String arg0) { for (int i = 0; i < sortComboBox.getItemCount(); i++) if (arg0 == null) { DimensionMenu.this.sortModeModel .setSelectedItem(null); } else { if ("ASC".equals(arg0)) { //$NON-NLS-1$ DimensionMenu.this.sortModeModel .setSelectedItem( Pat.CONSTANTS.sortAscending()); break; } else if ("DESC".equals(arg0)) { //$NON-NLS-1$ DimensionMenu.this.sortModeModel .setSelectedItem( Pat.CONSTANTS.sortDescending()); break; } else if ("BASC".equals(arg0)) { //$NON-NLS-1$ DimensionMenu.this.sortModeModel .setSelectedItem(Pat.CONSTANTS .sortBreakAscending()); break; } else if ("BDESC".equals(arg0)) { //$NON-NLS-1$ DimensionMenu.this.sortModeModel .setSelectedItem(Pat.CONSTANTS .sortBreakDescending()); break; } } DimensionMenu.this.sortModeModel.getSelectedItem(); ServiceFactory.getQueryInstance().getHierarchizeMode( Pat.getSessionID(), Pat.getCurrQuery(), dimensionId, new AsyncCallback<String>() { public void onFailure(final Throwable arg0) { // TODO Auto-generated method stub } public void onSuccess(final String arg0) { /* * for (int i = 0; i < hierarchyComboBox * .getItemCount(); i++) if * (hierarchyComboBox * .getModel().getElementAt(i) * .equals(arg0)){ * DimensionMenu.this.hierarchyModeModel * .setSelectedItem(arg0); * DimensionMenu.this.hierarchyModeModel * .getSelectedItem(); break; } else * DimensionMenu * .this.hierarchyModeModel.setSelectedItem * (null); */ addDimensionTreeItem(labels, parent, selectionlist, dimensionLabel.getText()); // TODO why do i have to do it here and not // in // the constructor? filterModel = new FilterProxyListModel<MemberSelectionLabel, String>( memberListBoxModel); filterModel.setModelFilter( new Filter<MemberSelectionLabel, String>() { public boolean select( final MemberSelectionLabel element, final String filter) { if (filter == null || filter .length() == 0) { return true; } return element.getText() .toUpperCase() .contains(filter .toUpperCase()); } }); memberListBox.setModel(filterModel); } }); } }); } }); } }); } /** * Adds children {@link StringTree} to a given parent in the Tree * * @param childStringTree * - Children StringTree * @param parent * - Parent in the Tree * @param selectionlist * - List of selected members * @param dimension * - Currently processed dimension */ private final void addDimensionTreeItem(final StringTree childStringTree, final TreeItem parent, final String[][] selectionlist, final String dimension) { final List<StringTree> child = childStringTree.getChildren(); for (int i = 0; i < child.size(); i++) { // Need a copy of the memberLabel because of GWT's lack of clone support final MemberSelectionLabel memberLabel = new MemberSelectionLabel(child.get(i).getValue(), child.get(i).getCaption()); final MemberSelectionLabel memberLabelcopy = new MemberSelectionLabel(child.get(i).getValue(), child.get(i).getCaption()); memberLabel.setDimension(dimension); memberLabelcopy.setDimension(dimension); for (final String[] element2 : selectionlist) { if (memberLabel.getText().equals(element2[0])) { memberLabel.setSelectionMode(element2[1]); memberLabelcopy.setSelectionMode(element2[1]); } } final TreeItem newParent = parent.addItem(memberLabel); memberLabel.setFullPath(getFullPath(newParent)); memberLabelcopy.setFullPath(getFullPath(newParent)); memberListBoxModel.add(memberLabelcopy); addDimensionTreeItem(child.get(i), newParent, selectionlist, dimension); } } /** * Returns the full path of the member in the dimension tree * * @param currentTreeItem * - TreeItem of interest * @return String[] path */ public final String[] getFullPath(final TreeItem currentTreeItem) { TreeItem treeItem = currentTreeItem; final List<String> pathList = new ArrayList<String>(); pathList.add(treeItem.getText()); while (treeItem.getParentItem() != null && treeItem.getParentItem().getWidget() instanceof MemberSelectionLabel) { treeItem = treeItem.getParentItem(); pathList.add(0, ((MemberSelectionLabel) treeItem.getWidget()).getText()); } final String[] values = new String[pathList.size()]; return pathList.toArray(values); } public final void syncTreeAndList(final MemberSelectionLabel source, final int mode) { for (int i = 0; i < memberListBoxModel.getSize(); i++) { if (Arrays.equals(memberListBoxModel.getElementAt(i).getFullPath(), source.getFullPath())) { memberListBoxModel.getElementAt(i).setSelectionMode(mode); } } syncItem(source, mode); } private final void syncItem(final MemberSelectionLabel source, final int mode) { for (int i = 0; i < dimensionTree.getItemCount(); i++) { searchTreeItems(dimensionTree.getItem(i), source, mode); } } private final void searchTreeItems(final TreeItem item, final MemberSelectionLabel source, final int mode) { if (Arrays.equals(getFullPath(item), source.getFullPath())) { ((MemberSelectionLabel) item.getWidget()).setSelectionMode(mode); } for (int i = 0; i < item.getChildCount(); i++) { searchTreeItems(item.getChild(i), source, mode); } } }