Tuesday, January 06, 2009

How to Make Igoogle Like Windows Using GWT (Java)

I tried to make a site like igoogle using GWT. I used gwt-dnd library. I used the demo example codes seen here (demo 5), simplified the code and add window buttons.

You can see the demo of my application here.

You can download the full project here.

I used DecoratedPopupPanel to make My Windows, the class is shown below.


package com.mycompany.client;

import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.DecoratedPopupPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MouseListener;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class MyDialogBox extends DecoratedPopupPanel{

VerticalPanel verticalPanel = new VerticalPanel();
HorizontalPanel horizontalPanel = new HorizontalPanel();
Label label = new Label("Hello World");
HorizontalPanel buttonPanel = new HorizontalPanel();
final Image openButton;

public MyDialogBox(final HTML html) {
verticalPanel.add(horizontalPanel);
horizontalPanel.add(label);
horizontalPanel.add(buttonPanel);
verticalPanel.add(html);
add(verticalPanel);

html.setWidth("100%");

//required to set window width
final HTML spaceHTML = new HTML("");
spaceHTML.setHeight("0px");

final Image minimizeButton = new Image("minimize.png");
minimizeButton.addClickListener(new ClickListener(){

public void onClick(Widget sender) {
int width = MyDialogBox.this.getOffsetWidth();
spaceHTML.setWidth(width - 20 + "");
verticalPanel.add(spaceHTML);
html.setVisible(false);
MyDialogBox.this.setWidth(width + "px");
minimizeButton.setVisible(false);
openButton.setVisible(true);
}});
Image closeButton = new Image("close.png");
closeButton.addClickListener(new ClickListener(){

public void onClick(Widget sender) {
MyDialogBox.this.setVisible(false);
MyDialogBox.this.hide();
MyDialogBox.this.removeFromParent();
}});
openButton = new Image("open.png");
openButton.addClickListener(new ClickListener(){

public void onClick(Widget sender) {
html.setVisible(true);
minimizeButton.setVisible(true);
openButton.setVisible(false);
}});

setAnimationEnabled(true);
buttonPanel.add(minimizeButton);
buttonPanel.add(openButton);
buttonPanel.add(closeButton);
openButton.setVisible(false);

label.setStyleName("title");
horizontalPanel.setStyleName("toolbar");
buttonPanel.setStyleName("butonPanel");
horizontalPanel.setCellWidth(buttonPanel, "40px");
}

public void addMouseListener(MouseListener listener) {
// TODO Auto-generated method stub

}

public void removeMouseListener(MouseListener listener) {
// TODO Auto-generated method stub

}

public Label getLabel()
{
return label;
}

public VerticalPanel getVerticalPanel()
{
return verticalPanel;
}

}


Using the code below, I put the windows to panel.


/*
* Copyright 2008 Fred Sauer
*
* 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.mycompany.client;

import java.util.ArrayList;
import java.util.Iterator;

import com.allen_sauer.gwt.dnd.client.PickupDragController;
import com.allen_sauer.gwt.dnd.client.drop.IndexedDropController;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
* Example of columns that can be rearranged, with widget that can be moved
* within a column or between columns.
*/
public final class IndexedPanelExample extends Example {

private static final int COLUMNS = 2;

private static final String CSS_DEMO_INDEXED_PANEL_EXAMPLE = "demo-IndexedPanelExample";

private static final String CSS_DEMO_INDEXED_PANEL_EXAMPLE_COLUMN_COMPOSITE = "demo-IndexedPanelExample-column-composite";

private static final String CSS_DEMO_INDEXED_PANEL_EXAMPLE_CONTAINER = "demo-IndexedPanelExample-container";

private static final String CSS_DEMO_INDEXED_PANEL_EXAMPLE_HEADING = "demo-IndexedPanelExample-heading";

private static final String CSS_DEMO_INDEXED_PANEL_EXAMPLE_SPACER = "demo-IndexedPanelExample-spacer";
private static final String CSS_DEMO_INDEXED_PANEL_EXAMPLE_WIDGET = "demo-IndexedPanelExample-widget";

private static final int ROWS = 3;

private static final int SPACING = 0;

private static final String[] columnWidths = { "350px", "150px"};
private static final String[] captionWidths = { "375px", "175px"};

static ArrayList<HTML> widgetList = new ArrayList<HTML>();

public static AbsolutePanel boundaryPanel;

public IndexedPanelExample(DemoDragHandler demoDragHandler) {
addStyleName(CSS_DEMO_INDEXED_PANEL_EXAMPLE);
int count = 0;

// use the boundary panel as this composite's widget
boundaryPanel = new AbsolutePanel();
boundaryPanel.setSize("100%", "100%");
setWidget(boundaryPanel);

// initialize our column drag controller
PickupDragController columnDragController;
columnDragController = initializeDragController(demoDragHandler, boundaryPanel);

// initialize our widget drag controller
PickupDragController widgetDragController;
widgetDragController = initializeDragController(demoDragHandler, boundaryPanel);

// initialize our widget drag controller
PickupDragController widgetDragController2;
widgetDragController2 = initializeDragController(demoDragHandler, boundaryPanel);

ArrayList<PickupDragController> widgetDragControllerList = new ArrayList<PickupDragController>();
widgetDragControllerList.add(widgetDragController);
widgetDragControllerList.add(widgetDragController2);

// initialize horizontal panel to hold our columns
HorizontalPanel horizontalPanel = new HorizontalPanel();
horizontalPanel.addStyleName(CSS_DEMO_INDEXED_PANEL_EXAMPLE_CONTAINER);
horizontalPanel.setSpacing(SPACING);
boundaryPanel.add(horizontalPanel);

// initialize our column drop controller
IndexedDropController columnDropController = new IndexedDropController(horizontalPanel);
columnDragController.registerDropController(columnDropController);

for (int col = 1; col <= COLUMNS; col++) {
// initialize a vertical panel to hold the heading and a second vertical
// panel

VerticalPanel columnCompositePanel = new VerticalPanel();
columnCompositePanel.addStyleName(CSS_DEMO_INDEXED_PANEL_EXAMPLE_COLUMN_COMPOSITE);

// initialize inner vertical panel to hold individual widgets
VerticalPanel verticalPanel = new VerticalPanel();
verticalPanel.addStyleName(CSS_DEMO_INDEXED_PANEL_EXAMPLE_CONTAINER);
verticalPanel.setSpacing(SPACING);
horizontalPanel.add(columnCompositePanel);

// initialize a widget drop controller for the current column
NoInsertAtEndIndexedDropController widgetDropController = new NoInsertAtEndIndexedDropController(verticalPanel);
widgetDragControllerList.get(col - 1).registerDropController(widgetDropController);

// Put together the column pieces
Label heading = new Label("Column " + col);
heading.addStyleName(CSS_DEMO_INDEXED_PANEL_EXAMPLE_HEADING);
columnCompositePanel.add(heading);
columnCompositePanel.add(verticalPanel);

heading.setWidth(captionWidths[col - 1]);

// make the column draggable by its heading
columnDragController.makeDraggable(columnCompositePanel, heading);

for (int row = 1; row <= ROWS; row++) {
// initialize a widget
HTML widget = new HTML("Draggable #" + ++count);
widget.addStyleName(CSS_DEMO_INDEXED_PANEL_EXAMPLE_WIDGET);
widget.setHeight(Random.nextInt(4) + 2 + "em");
MyDialogBox myDialogBox = new MyDialogBox(widget);
verticalPanel.add(myDialogBox);
verticalPanel.setSpacing(3);

widget.setWidth(columnWidths[col - 1]);

widgetList.add(widget);
// make the widget draggable

widgetDragControllerList.get(col - 1).makeDraggable(myDialogBox, myDialogBox.getLabel());
}

// prevent vertical panel from collapsing to zero when last widget is
// removed
Label spacerLabel = new Label("");
spacerLabel.setStylePrimaryName(CSS_DEMO_INDEXED_PANEL_EXAMPLE_SPACER);
verticalPanel.add(spacerLabel);
}

}

private PickupDragController initializeDragController(DemoDragHandler demoDragHandler, AbsolutePanel boundaryPanel) {
PickupDragController columnDragController;
columnDragController = new PickupDragController(boundaryPanel, false);
columnDragController.setBehaviorMultipleSelection(false);
columnDragController.addDragHandler(demoDragHandler);
return columnDragController;
}

@Override
public String getDescription() {
return "Allows drop to occur anywhere among the children of a supported <code>IndexedPanel</code>.";
}

@Override
public Class<?>[] getInvolvedClasses() {
return new Class[] { IndexedPanelExample.class,
NoInsertAtEndIndexedDropController.class,
PickupDragController.class, };
}

}



And at last put them to page.


package com.mycompany.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;

/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class MyApplication implements EntryPoint {

public void onModuleLoad() {

final HTML eventTextArea = new HTML("");
DemoDragHandler demoDragHandler = new DemoDragHandler(eventTextArea);
RootPanel.get().add(new IndexedPanelExample(demoDragHandler));

}

}



That is all you are done ;)

6 comments:

dogan said...

can we drag a block from one column to the other?

yekmer said...

sure you can, I disabled it. if you understand how IndexPanel.java works, you can eaisily do that. If you can't ask me for help.

didier said...

I did the same concept, a gadget portal. Take a look at genwork.morphexchange.com

yekmer said...

It looks nice didier, will it be a commercial product or you are developing just for fun?

didier said...

Genwork is an opensource product. You can find sources on sf.net

i wanted to create a simple and powerful portal (optimized with GWT). I plan to use it on my profesional activities (i'm a JEE architect). Gadget are very modular

I'm looking for parter/developper to help me. If you or someone is interested, please let me know @ dabder@hotmail.com.

yekmer said...

sorry didier, I would be happy to help you at this joyful project, but I have lots of boring examinations, at that time I am working half time for a company, and also I have my own half projects waiting for me :(
It really looks so nice. I will inform you if someone is interested in your open source project.

Share