blob: 131fd461f1ff5cf972be94b49b91870c22eb2e9b [file] [log] [blame]
/*
* Copyright 2006 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.sample.dynatable.client;
import com.google.gwt.sample.dynatable.client.DynaTableDataProvider.RowDataAcceptor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Widget;
/**
* A composite Widget that implements the main interface for the dynamic table,
* including the data table, status indicators, and paging buttons.
*/
public class DynaTableWidget extends Composite {
private class NavBar extends Composite implements ClickListener {
public final DockPanel bar = new DockPanel();
public final Button gotoFirst = new Button("<<", this);
public final Button gotoNext = new Button(">", this);
public final Button gotoPrev = new Button("<", this);
public final HTML status = new HTML();
public NavBar() {
initWidget(bar);
bar.setStyleName("navbar");
status.setStyleName("status");
HorizontalPanel buttons = new HorizontalPanel();
buttons.add(gotoFirst);
buttons.add(gotoPrev);
buttons.add(gotoNext);
bar.add(buttons, DockPanel.EAST);
bar.setCellHorizontalAlignment(buttons, DockPanel.ALIGN_RIGHT);
bar.add(status, DockPanel.CENTER);
bar.setVerticalAlignment(DockPanel.ALIGN_MIDDLE);
bar.setCellHorizontalAlignment(status, HasAlignment.ALIGN_RIGHT);
bar.setCellVerticalAlignment(status, HasAlignment.ALIGN_MIDDLE);
bar.setCellWidth(status, "100%");
// Initialize prev & first button to disabled.
//
gotoPrev.setEnabled(false);
gotoFirst.setEnabled(false);
}
public void onClick(Widget sender) {
if (sender == gotoNext) {
startRow += getDataRowCount();
refresh();
} else if (sender == gotoPrev) {
startRow -= getDataRowCount();
if (startRow < 0) {
startRow = 0;
}
refresh();
} else if (sender == gotoFirst) {
startRow = 0;
refresh();
}
}
}
private class RowDataAcceptorImpl implements RowDataAcceptor {
public void accept(int startRow, String[][] data) {
int destRowCount = getDataRowCount();
int destColCount = grid.getCellCount(0);
assert (data.length <= destRowCount) : "Too many rows";
int srcRowIndex = 0;
int srcRowCount = data.length;
int destRowIndex = 1; // skip navbar row
for (; srcRowIndex < srcRowCount; ++srcRowIndex, ++destRowIndex) {
String[] srcRowData = data[srcRowIndex];
assert (srcRowData.length == destColCount) : " Column count mismatch";
for (int srcColIndex = 0; srcColIndex < destColCount; ++srcColIndex) {
String cellHTML = srcRowData[srcColIndex];
grid.setText(destRowIndex, srcColIndex, cellHTML);
}
}
// Clear remaining table rows.
//
boolean isLastPage = false;
for (; destRowIndex < destRowCount + 1; ++destRowIndex) {
isLastPage = true;
for (int destColIndex = 0; destColIndex < destColCount; ++destColIndex) {
grid.clearCell(destRowIndex, destColIndex);
}
}
// Synchronize the nav buttons.
//
navbar.gotoNext.setEnabled(!isLastPage);
navbar.gotoFirst.setEnabled(startRow > 0);
navbar.gotoPrev.setEnabled(startRow > 0);
// Update the status message.
//
setStatusText((startRow + 1) + " - " + (startRow + srcRowCount));
}
public void failed(Throwable caught) {
String msg = "Failed to access data";
if (caught != null) {
msg += ": " + caught.getMessage();
}
setStatusText(msg);
}
}
private final RowDataAcceptor acceptor = new RowDataAcceptorImpl();
private final NavBar navbar = new NavBar();
private final DockPanel outer = new DockPanel();
private final DynaTableDataProvider provider;
private int startRow = 0;
private final Grid grid = new Grid();
public DynaTableWidget(DynaTableDataProvider provider, String[] columns,
String[] columnStyles, int rowCount) {
if (columns.length == 0) {
throw new IllegalArgumentException(
"expecting a positive number of columns");
}
if (columnStyles != null && columns.length != columnStyles.length) {
throw new IllegalArgumentException("expecting as many styles as columns");
}
this.provider = provider;
initWidget(outer);
grid.setStyleName("table");
outer.add(navbar, DockPanel.NORTH);
outer.add(grid, DockPanel.CENTER);
initTable(columns, columnStyles, rowCount);
setStyleName("DynaTable-DynaTableWidget");
}
public void clearStatusText() {
navbar.status.setHTML("&nbsp;");
}
public void refresh() {
// Disable buttons temporarily to stop the user from running off the end.
//
navbar.gotoFirst.setEnabled(false);
navbar.gotoPrev.setEnabled(false);
navbar.gotoNext.setEnabled(false);
setStatusText("Please wait...");
provider.updateRowData(startRow, grid.getRowCount() - 1, acceptor);
}
public void setRowCount(int rows) {
grid.resizeRows(rows);
}
public void setStatusText(String text) {
navbar.status.setText(text);
}
private int getDataRowCount() {
return grid.getRowCount() - 1;
}
private void initTable(String[] columns, String[] columnStyles, int rowCount) {
// Set up the header row. It's one greater than the number of visible rows.
//
grid.resize(rowCount + 1, columns.length);
for (int i = 0, n = columns.length; i < n; i++) {
grid.setText(0, i, columns[i]);
if (columnStyles != null) {
grid.getCellFormatter().setStyleName(0, i, columnStyles[i] + " header");
}
}
}
}