001/* 002 * #%L 003 * GwtMaterial 004 * %% 005 * Copyright (C) 2015 - 2017 GwtMaterialDesign 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package gwt.material.design.client.ui.table.cell; 021 022import com.google.gwt.cell.client.Cell; 023import com.google.gwt.cell.client.Cell.Context; 024import com.google.gwt.cell.client.FieldUpdater; 025import com.google.gwt.cell.client.HasCell; 026import com.google.gwt.cell.client.ValueUpdater; 027import com.google.gwt.dom.client.Element; 028import com.google.gwt.dom.client.NativeEvent; 029import com.google.gwt.dom.client.Style; 030import com.google.gwt.safehtml.shared.SafeHtmlBuilder; 031import gwt.material.design.client.base.HasHideOn; 032import gwt.material.design.client.base.HasTextAlign; 033import gwt.material.design.client.base.constants.StyleName; 034import gwt.material.design.client.constants.HideOn; 035import gwt.material.design.client.constants.TextAlign; 036import gwt.material.design.client.data.component.RowComponent; 037 038import java.util.Comparator; 039import java.util.HashMap; 040import java.util.Map; 041 042/** 043 * A representation of a column in a table. 044 * 045 * @param <T> the row type 046 * @param <C> the column type 047 * 048 * @author Ben Dol 049 */ 050public abstract class Column<T, C> implements HasCell<T, C>, HasHideOn, HasTextAlign { 051 052 /** 053 * The {@link Cell} responsible for rendering items in the column. 054 */ 055 private final Cell<C> cell; 056 057 /** 058 * The {@link FieldUpdater} used for updating values in the column. 059 */ 060 private FieldUpdater<T, C> fieldUpdater; 061 062 private boolean isDefaultSortAscending = true; 063 private boolean isNumeric = false; 064 private boolean autoSort = false; 065 private String name; 066 private String width; 067 private HideOn hideOn; 068 private TextAlign textAlign; 069 070 private Map<StyleName, String> styleProps; 071 072 private Comparator<? super RowComponent<T>> sortComparator; 073 074 /** 075 * Construct a new Column with a given {@link Cell}. 076 * 077 * @param cell the Cell used by this Column 078 */ 079 public Column(Cell<C> cell) { 080 this.cell = cell; 081 082 setFieldUpdater(fieldUpdater()); 083 setDefaultSortAscending(defaultSortAscending()); 084 setAutoSort(autoSort()); 085 setNumeric(numeric()); 086 setName(name()); 087 setWidth(width()); 088 setHideOn(hideOn()); 089 setTextAlign(textAlign()); 090 setStyleProperties(styleProperties()); 091 setSortComparator(sortComparator()); 092 } 093 094 /** 095 * Handle a browser event that took place within the column. 096 * 097 * @param context the cell context 098 * @param elem the parent Element 099 * @param object the base object to be updated 100 * @param event the native browser event 101 */ 102 public void onBrowserEvent(Context context, Element elem, final T object, NativeEvent event) { 103 final int index = context.getIndex(); 104 ValueUpdater<C> valueUpdater = (fieldUpdater == null) ? null : (ValueUpdater<C>) value -> { 105 fieldUpdater.update(index, object, value); 106 }; 107 cell.onBrowserEvent(context, elem, getValue(object), event, valueUpdater); 108 } 109 110 /** 111 * Returns the {@link Cell} responsible for rendering items in the column. 112 * 113 * @return a Cell 114 */ 115 @Override 116 public final Cell<C> getCell() { 117 return cell; 118 } 119 120 /** 121 * Returns the column value from within the underlying data object. 122 */ 123 @Override 124 public abstract C getValue(T object); 125 126 /** 127 * Render the object into the cell. 128 * 129 * @param object the object to render 130 * @param sb the buffer to render into 131 */ 132 public void render(Context context, T object, SafeHtmlBuilder sb) { 133 cell.render(context, getValue(object), sb); 134 } 135 136 /** 137 * Sets a string that identifies this column in a data query. 138 * 139 * @param name name of the column from the data store's perspective 140 */ 141 public final void setName(String name) { 142 this.name = name; 143 } 144 145 /** 146 * @return the database name of the column, or null if it's never been set 147 */ 148 public final String getName() { 149 return name; 150 } 151 152 /** 153 * @return the database name of the column, or null if it's never been set 154 */ 155 public String name() { return ""; } 156 157 /** 158 * Check if the default sort order of the column is ascending or descending. 159 * 160 * @return true if default sort is ascending, false if not 161 */ 162 public final boolean isDefaultSortAscending() { 163 return isDefaultSortAscending; 164 } 165 166 /** 167 * Set whether or not the default sort order is ascending. 168 * 169 * @param isAscending true to set the default order to ascending, false for 170 * descending 171 */ 172 public final void setDefaultSortAscending(boolean isAscending) { 173 this.isDefaultSortAscending = isAscending; 174 } 175 176 /** 177 * Check if the default sort order of the column is ascending or descending. 178 * 179 * @return true if default sort is ascending, false if not 180 */ 181 public boolean defaultSortAscending() { return true; } 182 183 /** 184 * Is this column auto sorting when rendered. 185 * @return true if this column is auto sorted. 186 */ 187 public final boolean isAutoSort() { 188 return autoSort; 189 } 190 191 /** 192 * Make this column auto sort on rendering, if multiple columns are auto 193 * sorting it will be based on the first one set to auto sort. 194 */ 195 public final void setAutoSort(boolean autoSort) { 196 this.autoSort = autoSort; 197 } 198 199 public boolean autoSort() { return false; } 200 201 /** 202 * Check if the column is sortable. 203 * 204 * @return true if sortable, false if not 205 */ 206 public boolean isSortable() { 207 return getSortComparator() != null; 208 } 209 210 public final void setSortComparator(Comparator<? super RowComponent<T>> sortComparator) { 211 this.sortComparator = sortComparator; 212 } 213 214 public final Comparator<? super RowComponent<T>> getSortComparator() { 215 return sortComparator; 216 } 217 218 public Comparator<? super RowComponent<T>> sortComparator() { return null; } 219 220 @Override 221 public final FieldUpdater<T, C> getFieldUpdater() { 222 return fieldUpdater; 223 } 224 225 public final void setFieldUpdater(FieldUpdater<T, C> fieldUpdater) { 226 this.fieldUpdater = fieldUpdater; 227 } 228 229 public FieldUpdater<T, C> fieldUpdater() { return null; } 230 231 public final boolean isNumeric() { 232 return isNumeric; 233 } 234 235 public final void setNumeric(boolean numeric) { 236 isNumeric = numeric; 237 } 238 239 public boolean numeric() { return false; } 240 241 @Override 242 public final void setHideOn(HideOn hideOn) { 243 this.hideOn = hideOn; 244 } 245 246 @Override 247 public final HideOn getHideOn() { 248 return hideOn; 249 } 250 251 public HideOn hideOn() { return null; } 252 253 @Override 254 public final void setTextAlign(TextAlign align) { 255 this.textAlign = align; 256 } 257 258 @Override 259 public final TextAlign getTextAlign() { 260 return textAlign; 261 } 262 263 public TextAlign textAlign() { return null; } 264 265 /** 266 * Set a style property using its name as the key. Please ensure the style name and value 267 * are appropriately configured or it may result in unexpected behavior. 268 * 269 * @param styleName the style name as seen here {@link Style#STYLE_Z_INDEX} for example. 270 * @param value the string value required for the given style property. 271 */ 272 public final void setStyleProperty(StyleName styleName, String value) { 273 if(styleProps == null) { 274 styleProps = new HashMap<>(); 275 } 276 styleProps.put(styleName, value); 277 } 278 279 /** 280 * Get a styles property. 281 * @param styleName the styles name as represented in a {@link Style} class. 282 * @return null if the style property is not set. 283 */ 284 public final String getStyleProperty(StyleName styleName) { 285 return styleProps!=null ? styleProps.get(styleName) : null; 286 } 287 288 /** 289 * Return the registered style properties. 290 * @return null if no styles are added. 291 */ 292 public final Map<StyleName, String> getStyleProperties() { 293 return styleProps; 294 } 295 296 /** 297 * Set the style properties map. 298 */ 299 public final void setStyleProperties(Map<StyleName, String> styleProps) { 300 this.styleProps = styleProps; 301 } 302 303 public Map<StyleName, String> styleProperties() { return null;} 304 305 /** 306 * Set the columns header width. 307 */ 308 public final void setWidth(String width) { 309 this.width = width; 310 } 311 312 /** 313 * Get the columns header width. 314 * @return null if not defined. 315 */ 316 public final String getWidth() { 317 return width; 318 } 319 320 public String width() { return null; } 321 322 @Override 323 public String toString() { 324 return "Column{" + 325 "cell=" + cell + 326 ", fieldUpdater=" + fieldUpdater + 327 ", isDefaultSortAscending=" + isDefaultSortAscending + 328 ", isNumeric=" + isNumeric + 329 ", name='" + name + '\'' + 330 ", width='" + width + '\'' + 331 ", hideOn=" + hideOn + 332 ", textAlign=" + textAlign + 333 ", styleProps=" + styleProps + 334 ", sortComparator=" + sortComparator + 335 '}'; 336 } 337}