📄 datagrid.java
字号:
/*
* Copyright 2006-2007 Queplix Corp.
*
* Licensed under the Queplix Public License, Version 1.1.1 (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.queplix.com/solutions/commercial-open-source/queplix-public-license/
*
* 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.queplix.core.client.common.ui.grid;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusListener;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.ScrollListener;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.queplix.core.client.common.StringUtil;
import com.queplix.core.client.common.event.Event;
import com.queplix.core.client.common.event.EventListener;
import com.queplix.core.client.common.event.EventSource;
import com.queplix.core.client.common.ui.CrossBrowsersAbsolutePanel;
import com.queplix.core.client.common.ui.resizable.Resizable;
import com.queplix.core.client.common.ui.resizable.ResizableScrollPanel;
import java.util.ArrayList;
/**
* DataGrid, that is able to display data in columns and provides
* interactivity.
* @author Sergey Kozmin, Vasily Mikhailitchenko
* @since <?>
*/
public class DataGrid extends Composite implements Resizable, SourcesGridSortEvents,
EventListener {
private static final int SPACE_BEFORE = 7;
public static final int HEADER_FONT_WIDTH = 7;
public static final int HEADER_SORT_ICON_WIDTH = 28;
private GridElementsStrategy strategy = (GridElementsStrategyImpl) GWT.create(GridElementsStrategyImpl.class);
private GridModel model;
private boolean inPopup;
private HeaderGrid headerGrid;
private BaseInternalDataGrid dataGrid;
private VerticalPanel panel;
private FocusPanel mainPanel;
private CrossBrowsersAbsolutePanel headerPanel;
private ResizableScrollPanel dataGridScrollPanel;//todo move it to internal data grid
private ArrayList gridListeners = new ArrayList();
private GridSortListenerCollection sortListeners = new GridSortListenerCollection();
/**
* Constructor
* @param model grid's model
* @param view grid's view
* @param inPopup if client code is going to put the grid in a popup or dialog;
* @param sendConfirmationEvent should selection be done by internal logic,
* or should to_be_selected event be send instead.
*/
public DataGrid(GridModel model, GridView view, boolean inPopup,
boolean sendConfirmationEvent) {
this.model = model;
dataGrid = InternalGridFactory.createInternalGrid(view, strategy,
gridListeners, true, sendConfirmationEvent);
headerGrid = new HeaderGrid(model, view, this, strategy, sortListeners);
dataGrid.getEventSource().addEventListener(this);
headerGrid.getEventSource().addEventListener(this);
dataGrid.setHeaderGrid(headerGrid);
headerGrid.setInternalDataGrid(dataGrid);
headerGrid.setStyleName(view.getMainGridStyleName());
dataGrid.setStyleName(view.getMainGridStyleName());
panel = new VerticalPanel();
mainPanel = new FocusPanel();
headerPanel = new CrossBrowsersAbsolutePanel();
headerPanel.add(headerGrid);
this.inPopup = inPopup;
ScrollListener inPopupScrollListener = new ScrollListener() {
public void onScroll(Widget widget, int scrollLeft, int scrollTop) {
headerPanel.setWidgetPosition(headerGrid, 0, scrollTop);
}
};
ScrollListener standaloneScrollListener = new ScrollListener() {
public void onScroll(Widget widget, int scrollLeft, int scrollTop) {
headerPanel.setWidgetPosition(headerGrid, -scrollLeft, 0);
}
};
if (this.inPopup) {
headerPanel.add(dataGrid);
dataGridScrollPanel = new ResizableScrollPanel(headerPanel);
dataGridScrollPanel.addScrollListener(inPopupScrollListener);
} else {
dataGridScrollPanel = new ResizableScrollPanel(dataGrid);
dataGridScrollPanel.addScrollListener(standaloneScrollListener);
panel.add(headerPanel);
}
panel.add(dataGridScrollPanel);
mainPanel.setWidget(panel);
initWidget(mainPanel);
headerGrid.setupWidgets(model.getDataGridMeta());
dataGrid.setupWidgets(model);
subscribeEvents();
mainPanel.addClickListener(new ClickListener(){
public void onClick(Widget sender){
// Have to set focus explicitly (IE workaround)
mainPanel.setFocus(true);
}
});
mainPanel.addFocusListener(new FocusListener(){
public void onFocus(Widget sender){
dataGrid.setFocus(true);
}
public void onLostFocus(Widget sender){
dataGrid.setFocus(false);
}
});
}
public void setModel(GridModel model) {
this.model = model;
dataGrid.setupWidgets(model);
headerGrid.setupWidgets(model.getDataGridMeta());
subscribeEvents();
}
public void adjustHeaderPosition(){
headerPanel.setWidgetPosition(headerGrid, -dataGridScrollPanel.getHorizontalScrollPosition(), 0);
}
/**
* Scroll the scrollPanel up to the specified row
* @param row to scroll up to
*/
public void scrollGridToRow(int row){
int rowHeight = dataGrid.getOffsetHeight() / dataGrid.getRowCount();
int firstVisibleRow = dataGridScrollPanel.getScrollPosition()/rowHeight;
int numOfRowsVisible = dataGridScrollPanel.getOffsetHeight()/rowHeight;
int lastVisibleRow = firstVisibleRow + numOfRowsVisible;
int scrollDiff = 0;
if(lastVisibleRow < (row + 1)) {
scrollDiff = row - lastVisibleRow + 1;
} else if(firstVisibleRow > (row - 1)) {
scrollDiff = row - firstVisibleRow - 1;
}
if(scrollDiff != 0) {
dataGridScrollPanel.setScrollPosition(
dataGridScrollPanel.getScrollPosition()
+ scrollDiff * rowHeight);
}
}
private void subscribeEvents() {
model.addGridModelListener(new GridModelListener() {
public void gridStructureChanged() {
headerGrid.setupWidgets(model.getDataGridMeta());
dataGrid.setupWidgets(model);
}
public void gridDataChanged() {
headerGrid.setupWidgets(model.getDataGridMeta());
dataGrid.setupWidgets(model);
}
public void gridRowDataChanged(int row) {
dataGrid.setupRow(model, row);
}
public void gridRowsWereInserted() {
int oldRowCount = dataGrid.getRowCount();
int newRowCount = model.getModelRowCount();
if(newRowCount > oldRowCount) {
dataGrid.setupWidgets(model);
}
}
});
}
/**
* Selected column. If at least one column selected, then value will be positive, otherwise negative.
* @return selected column.
*/
public int getSelectedColumn() {
return headerGrid.getSelectedColumn();
}
public SelectionController getSelectionController() {
return dataGrid;
}
/**
* Set the column selected. Deselect column
* @param column the column
*/
public void setSelectedColumn(int column) {
headerGrid.setSelectedColumn(column);
}
public int getRowCount(){
return dataGrid.getRowCount();
}
public void addGridListener(GridSelectionListener listener) {
gridListeners.add(listener);
}
public void removeGridListener(GridSelectionListener listener) {
gridListeners.remove(listener);
}
public void addGridSortListener(GridSortListener listener) {
sortListeners.add(listener);
}
public void removeGridSortListener(GridSortListener listener) {
sortListeners.remove(listener);
}
public static int calcColumnWidth(int dataLength){
double length = (double)dataLength;
if(dataLength < 17){
return (int)Math.round(length * (HEADER_FONT_WIDTH + 2*(length/100)));
}
return (int)Math.round(length * (HEADER_FONT_WIDTH - 0.4*(length/100)));
}
public static int calcHeaderColumnWidth(int captionLength){
return calcColumnWidth(captionLength) + HEADER_SORT_ICON_WIDTH;
}
public void onEvent(Event event, Widget sender) {
if(event == Events.SCROLL_TO_ROW) {
Integer value = (Integer) Events.SCROLL_TO_ROW.getData();
scrollGridToRow(value.intValue());
} else {
getEventSource().fireEvent(event);
}
}
// -------------------- public events ------------------------
public static interface Events extends BaseInternalDataGrid.Events, HeaderGrid.Events {
//todo implement
}
private EventSource eventSource = new EventSource(this);
public EventSource getEventSource() {
return eventSource;
}
// ----------------- end of public events --------------------
// ======================== Resizable implementation =====================
private int offsetHeight;
private int offsetWidth;
public void setOffsetHeight(int height) {
if ((height < 0) || (offsetHeight == height)) return; // invalid or unchanged value
offsetHeight = height;
if (isAttached()) {
doSetOffsetHeight();
}
}
public void setOffsetWidth(int width) {
if ((width < 0) || (offsetWidth == width)) return; // invalid or unchanged value
offsetWidth = width;
if (isAttached()) {
doSetOffsetWidth();
}
}
private void doSetOffsetHeight() {
int headerHeight = headerGrid.getOffsetHeight();
dataGridScrollPanel.setOffsetHeight(offsetHeight - (inPopup ? 0 : headerHeight));
offsetHeight = dataGridScrollPanel.getOffsetHeight() + (inPopup ? 0 : headerHeight);
panel.setHeight(StringUtil.pixelToSize(offsetHeight));
}
private void doSetOffsetWidth() {
headerPanel.setWidgetPosition(headerGrid, 0, 0);
if(inPopup) {
mainPanel.setWidth(offsetWidth - DataGrid.SPACE_BEFORE + "px");
} else {
mainPanel.setWidth(offsetWidth - DataGrid.SPACE_BEFORE + "px");
headerPanel.setWidth(offsetWidth - DataGrid.SPACE_BEFORE + "px");
}
dataGridScrollPanel.setOffsetWidth(offsetWidth - DataGrid.SPACE_BEFORE);
offsetWidth = dataGridScrollPanel.getOffsetWidth();
panel.setWidth(StringUtil.pixelToSize(offsetWidth));
}
protected void onAttach() {
super.onAttach();
if (offsetHeight > 0) { // offsetHeight was set
doSetOffsetHeight();
}
if (offsetWidth > 0) { // offsetWidth was set
doSetOffsetWidth();
}
}
public int getOffsetWidth() {
int retValue = super.getOffsetWidth();
retValue = (retValue != 0) ? retValue : offsetWidth;
return retValue;
}
public int getOffsetHeight() {
int retValue = super.getOffsetHeight();
retValue = (retValue != 0) ? retValue : offsetHeight;
return retValue;
}
public void setHeight(String height) {
setOffsetHeight(StringUtil.sizeToPixel(height));
}
public void setWidth(String width) {
setOffsetWidth(StringUtil.sizeToPixel(width));
}
// ===================== End of Resizable implementation ==================
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -