Вы находитесь на странице: 1из 29

© 2009 Marty Hall

The Google
g Web Toolkit ((GWT):
)
Laying out Windows with Panels
((GWT 1.6 Version))
Originals of Slides and Source Code for Examples:
http://courses.coreservlets.com/Course-Materials/ajax.html
p j
Customized Java EE Training: http://courses.coreservlets.com/
Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.

© 2009 Marty Hall

For live Ajax & GWT training, see training


courses att http://courses.coreservlets.com/.
htt // l t /
Taught by the author of Core Servlets and JSP, More
Servlets and JSP,
JSP and this tutorial
tutorial. Available at public
venues, or customized versions can be held on-site
at yyour organization.
g
• Courses developed and taught by Marty Hall
– Java 5, Java 6, intermediate/beginning servlets/JSP, advanced servlets/JSP, Struts, JSF, Ajax, GWT, custom mix of topics
Customized
• Courses developed Java
and taught by EE Training: http://courses.coreservlets.com/
coreservlets.com experts (edited by Marty)
Servlets,
– Spring, JSP, Struts,
Hibernate, JSF/MyFaces/Facelets,
EJB3, Ruby/Rails Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known Contact author and developer. At public
hall@coreservlets.com venues or onsite at your location.
for details
Topics in This Section
• Strategy behind Panel usage
– Similar to use of LayoutManagers in desktop Java
• Most common Panel types
– HorizontalPanel
H i lP l
– VerticalPanel
– TabPanel and DecoratedTabPanel
– DockPanel
– Grid
– HorizontalSplitPanel
– VerticalSplitPanel
– P
PopupPanel
P l

© 2009 Marty Hall

Overview

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.
Layout Strategies
• HTML-based layout
–WWrite
i HTML by
b hand,
h d designate
d i places
l for
f individual
i di id l
controls
– HTML body contains a lot of content
– Best when GWT is used for
• A traditional Web application with some pieces of Ajax-
enabled content
• Complex page where HTML layout does not change
• Java-based layout
– HTML body gives place for main div only
– Java uses Panels to build up overall layout
• Similar to way LayoutManagers are used in desktop Java
– Best when GWT is used to
• Mimic a desktop application
7
• Create an application where HTML layout changes on fly

HTML-Based Layout
• HTML
<body>
Regular HTML <div id="id-1"></div>
Regular HTML <div id="id-2"></div>
R
Regular
l HTML <div
<di id
id="id-3"></div>
"id 3"></di >
Regular HTML
</body>
• Java
J
public void onModuleLoad() {
SomeWidget w1 = …;
RootPanel.get("id-1").add(w1);
1 1
SomeWidget w2 = …;
RootPanel.get("id-2").add(w2);
SomeWidget w3 = …;
;
RootPanel.get("id-3").add(w3);
}
8
Java-Based Layout
• HTML
<body>
<div id="main-id"></div>
</body>

• Java
J
public void onModuleLoad() {
SomePanel panel = …;
panel.setVariousProperties();
l tV i P ti ()
SomeWidget w1 = …;
panel.add(w1);
SomeWidget w2 = …;
panel.add(w2);

SomeWidget wN = …;
panel.add(wN);
RootPanel.get("main-id").add(panel);
}
9

Methods Supported by Most


Panels
• add(Widget w)
– Add
Adds a Wid
Widget to the
h PPanel.
l Wh
Where iit gets inserted
i d depends
d d on
the Panel type.
• Most Panels support “insert” to put Widget in specific place
• All Panels
P l supportt “remove”
“ ” (one
( Widget)
Wid t) and d “clear”
“ l ” (all)
( ll)
– The Widget that you add can itself be a Panel
– Many Panels have specialized versions of add with extra args
• setSize, setWidth, setHeight
– These take CSS-style size descriptors
• setStyleName
– For CSS styling. But most widgets also have a predefined CSS
style name (e.g., gwt-Button).
• getChildren, getWidget, getWidgetCount
– Look up information about widgets already inside the Panel
10
Top-Level Example Code: Java
public class GwtPanels implements EntryPoint {
public
bli void
id onModuleLoad()
d l d() {
addHorizontalPanel();
addVerticalPanel();
()
addTabPanel();
addDockPanel();
addGrid();
ddG id()
addHorizontalSplitPanel();
addVerticalSplitPanel();
addButtonForPopup();
}

}
11

Top-Level Example Code: HTML


<body>
< />
<p/>
<fieldset>
<legend>Simple Horizontal Panels</legend>
<div id="horizontal-panel"></div>
</fieldset>
<p/>
<fieldset>
<legend>Simple Vertical Panels</legend>
<di id
<div id="vertical-panel"></div>
" ti l l"></di >
</fieldset>

</body>

12
© 2009 Marty Hall

HorizontalPanel

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.

Summary
• Purpose
– To put widgets side-by-side
– Similar to Swing’s BoxLayout (with a horizontal layout)
• Main methods
– setSpacing(int pixels)
• Sets inter
inter-widget
widget spacing in pixels
– add(Widget w)
• Adds a widget, in left-to-right order.
• Use “insert” if you
o want
ant to put
p t widget
idget at specific inde
index
– setHorizontalAlignment, setVerticalAlignment
• Sets default alignment

14
Example Code
private void addHorizontalPanel() {
String text = "<b>This
<b>This is a simple<br/>HorizontalPanel</b>
simple<br/>HorizontalPanel</b>";
;
HorizontalPanel hPanel = makeHorizontalPanel(text, 5);
RootPanel.get("horizontal-panel").add(hPanel);
}

private HorizontalPanel makeHorizontalPanel(String text,


int numButtons) {
HorizontalPanel hPanel = new HorizontalPanel();
hPanel.setSpacing(5);
hPanel.add(new HTML(text));
for (int i=1; i <= numButtons; i++) {
hPanel.add(new Button("Button " + i));
}
return(hPanel);
( );
}

15

Example Result
(Local Web Mode)

16
Underlying HTML
<div id="horizontal-panel">
<table cellspacing="5"
cellspacing "5" cellpadding="0">
cellpadding "0">
<tbody><tr>
<td align="left" style="vertical-align: top;">
<div class="gwt-HTML">
<b>This is a simple<br/>HorizontalPanel</b>
</div>
</td>
<td align="left" style="vertical-align: top;">…</td>
<td align="left"
g style="vertical-align:
y g top;">…</td>
p; /
<td align="left" style="vertical-align: top;">…</td>
<td align="left" style="vertical-align: top;">…</td>
<td align=
align="left"
left style=
style="vertical-align:
vertical align: top;">
top; >…</td>
</td>
</tr></tbody></table>
</div>
17

© 2009 Marty Hall

VerticalPanel

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.
Summary
• Purpose
– To put widgets on top of each other.
– Similar to Swing’s BoxLayout (with a vertical layout)
• Main methods
– setSpacing(int pixels)
• Sets inter
inter-widget
widget spacing in pixels
– add(Widget w)
• Adds a widget, in top-to-bottom order.
• Use “insert” if you
o want
ant to put
p t widget
idget at specific inde
index
– setHorizontalAlignment, setVerticalAlignment
• Sets default alignment

19

Example Code
private void addVerticalPanel() {
String text =
"<b>This is a simple<br/>VerticalPanel</b>";
VerticalPanel vPanel = makeVerticalPanel(text, 5);
RootPanel.get("vertical-panel").add(vPanel);
g ( p ) ( );
}

private VerticalPanel makeVerticalPanel(String text,


int numButtons) {
VerticalPanel vPanel = new VerticalPanel();
vPanel.setSpacing(5);
vPanel.add(new HTML(text));
for (int i=1; i <= numButtons; i++) {
vPanel.add(new Button("Button " + i));
}
return(vPanel);
}
20
Example Result

21

Underlying HTML
<div id="vertical-panel">
<table cellspacing
cellspacing="5"
5 cellpadding
cellpadding="0"><tbody>
0 ><tbody>
<tr>
<td align="left" style="vertical-align: top;">
<div class="gwt-HTML">
g
<b>This is a simple<br/>VerticalPanel</b>
</div>
</td>
</tr>
<tr><td align="left" style="vertical-align: top;">…</td></tr>
<tr><td align="left" style="vertical-align: top;">…</td></tr>
<t ><td align="left"
<tr><td li "l ft" style="vertical-align:
t l " ti l li t
top;">…</td></tr>
"> </td></t >
<tr><td align="left" style="vertical-align: top;">…</td></tr>
<tr><td align="left" style="vertical-align: top;">…</td></tr>
</tbody></table>
</div>

22
© 2009 Marty Hall

TabPanel and
DecoratedTabPanel

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.

Summary
• Purpose
– T
To panels
l or widgets
id t on top
t off eachh other,
th andd select
l t them
th by
b
clicking on tabs
• TabPanel uses square tabs
• DecoratedTabPanel uses rounded tabs
– Similar to Swing’s JTabbedPane
• Main methods
– add(Widget
dd(Wid t w, St
String
i tabText)
t bT t)
• Adds a widget, in left-to-right order. Note two args for “add”.
– selectTab(int tabNumber)
• Programmatically selects a panel
– setWidth(String widthDescriptor)
• Sets the width. E.g., setWidth("300px").
• The height is usually determined by the contents
– setAnimationEnabled(true)
• Makes it so that panels slide into view when tabs selected
24
Example Code
private void addTabPanel() {
DecoratedTabPanel tPanel = new DecoratedTabPanel();
tPanel.setWidth("400px");
for(int i=1; i <= 5; i++) {
St i
String panelText
lT t =
"<h1>This is Panel " + i + ". <i>Wow!</i></h1>";
tPanel.add(new HTML(panelText), "Panel " + i);
}
tPanel.selectTab(0);
tPanel.setAnimationEnabled(true);
RootPanel.get("tab-panel").add(tPanel);
}

25

Example Result

26
Underlying HTML
• Enclosing HTML table with fixed width
• First row: HTML table for the tabs
– Each cell with CSS class gwt-TabBarItem-wrapper
– Selected
S l d tab
b also
l with
i h CSS class
l
gwt-TabBarItem-wrapper-selected
• Second row: single cell (td) for contents
– Contains a bunch of divs
– All except selected one have display:none
• Details
– Download and run this example, then view in Firebug

27

© 2009 Marty Hall

DockPanel

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.
Summary
• Purpose
– To put widgets (usually Panels) in five possible regions
– Similar to AWT’s BorderLayout
• However
However, unlike BorderLayout,
BorderLayout you are allowed to add
multiple entries to NORTH, SOUTH (stacked on top of
each other) and EAST, WEST (placed side-by-side)
• Main methods
– setSpacing(int pixels)
• Sets inter-widget
g spacing
p g in p
pixels
– add(Widget w, DockPanel.REGION_NAME)
• Adds a widget to specified region (DockPanel.NORTH,
..SOUTH,
SOUTH …EAST,
EAST …WEST,
WEST …CENTER)
CENTER)
• Can add a fixed-sized ScrollPanel to the CENTER region,
and scrollbars will be automatically added if needed
29

Example Code
private void addDockPanel() {
DockPanel dPanel = new DockPanel();
dPanel.setSpacing(5);
dPanel.setHorizontalAlignment
(HasHorizontalAlignment.ALIGN_CENTER);
VerticalPanel westPanel =
makeVerticalPanel("<b>This is<br/>WEST</b>", 9);
dPanel.add(westPanel, DockPanel.WEST);
VerticalPanel eastPanel =
(
makeVerticalPanel("<b>This is<br/>EAST</b>",
/ / , 9);
);
dPanel.add(eastPanel, DockPanel.EAST);

30
Example Code (Continued)
HorizontalPanel northPanel =
makeHorizontalPanel("<b>This is<br/>NORTH</b>",
is<br/>NORTH</b>" 3);
dPanel.add(northPanel, DockPanel.NORTH);
HorizontalPanel southPanel =
makeHorizontalPanel("<b>This is<br/>SOUTH</b>",
is<br/>SOUTH</b>" 3);
dPanel.add(southPanel, DockPanel.SOUTH);
ScrollPanel sPanel =
new ScrollPanel(new
S llP l( HTML(
HTML(getCenterText()));
tC t T t()))
sPanel.setSize("475px", "300px");
dPanel.add(sPanel, DockPanel.CENTER);
R tP
RootPanel.get("dock-panel").add(dPanel);
l t("d k l") dd(dP l)
}

31

Supporting Code
private String getCenterText() {
g text =
String
"<h2>This is CENTER</h2> " +
"<p>Note that in GWT, unlike in Swing or AWT, you can " +
"add more than one entry to NORTH, SOUTH, EAST, or WEST, " +
"and the entries come out next to each other.</p>
/ " +
"<p>Also, in the CENTER, you can add a ScrollPanel and " +
"get scrollbars without needing an IFRAME.</p>" +
p a do te
"<p>Random text
t so t
that
at sc
scrollbars
o ba s aare
e needed.
eeded. " +
getRandomText();
return(text);
}

private String getRandomText() {


String text =
Blah, blah, blah, blah, blah, blah, blah. " +
"Blah,
"Yadda, yadda, yadda, yadda, yadda, yadda. ";
return(text + text + text + text + text + text + text);
32
}
Example Result

33

Underlying HTML
<div id="dock-panel">
<table cellspacing=
cellspacing="5"
5 cellpadding=
cellpadding="0">
0 >
<tbody>
<tr>
<td … rowspan
rowspan="3">West
3 >West stuff here</td>
<td … colspan="1">North stuff here</td>
<td … rowspan="3">East stuff here</td>
</tr>
/
<tr>
<td … >
<div style="overflow:
y auto;
position: relative;
width: 475px; height: 300px;">
<div class="gwt-HTML"><h2>This is CENTER</h2>…</div>
</div> …
<tr>South stuff here</tr>
34 …</table></div>
© 2009 Marty Hall

Grid

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.

Summary
• Purpose
– To
T putt widgets
id t in
i tabular
t b l layout
l t with
ith fixed
fi d cell
ll sizes
i
– Similar to AWT’s GridLayout
• Constructor
– new Grid(int rows, int columns)
• Note that class is called “Grid”, not “GridPanel”
• Main methods
– setWidget(int row, int col, Widget w)
• Inserts widget into cell. Note that you do not use “add”
– setHTML(int
( row,, int col,, Stringg htmlText))
• Wraps htmlText in HTML widget, then inserts
– setText(int row, int col, String text)
• Inserts p
plain text into cell
– getRowCount, getColumnCount
– resize(rows, cols), resizeRows(rows), resizeColumns(cols)
36
Example Code
private void addGrid() { // Class is Grid, not GridPanel
Grid grid = new Grid(3
Grid(3, 5);
for(int i=0; i<grid.getColumnCount(); i++) {
grid.setText(0, i, "Text in col " + i);
grid setHTML(1, i,
grid.setHTML(1,
"<b>HTML</b> in col <i>" + i + "</i>");
grid.setWidget(2, i,
new Button("Button
Button( Button in col " + i));
}
RootPanel.get("grid").add(grid);
}

37

Example Result

38
Underlying HTML
<div id="grid">
<table>
<colgroup><col/></colgroup>
<tbody>
<tr>
<td>Text in col 0</td>
<td>Text in col 1</td>
<td>Text in col 2</td>
<td>Text in col 3</td>
<td>Text in col 4</td>
</tr>
/
<tr>…</tr>
<tr>…</tr>
</tbody>
y
</table>
</div>
39

© 2009 Marty Hall

HorizontalSplitPanel

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.
Summary
• Purpose
– To put two widgets (usually HTML widgets or Panels)
side-by-side and let end user drag divider
– Similar to Swing
Swing’ss JSplitPane with
HORIZONTAL_SPLIT
• Main methods
– setSize(String sizeDescriptor)
• You usually give a fixed size
– setSplitPosition(String positionDescriptor)
• Usually set in percent, e.g., setSplitPosition("30%")
– setLeftWidget(Widget
g ( g w))
– setRightWidget(Widget w)
41

Example Code
private void addHorizontalSplitPanel() {
HorizontalSplitPanel hsPanel =
new HorizontalSplitPanel();
hsPanel.setSize("475px", "300px");
hsPanel setSplitPosition("30%");
hsPanel.setSplitPosition( 30% );
String text = getSplitPanelText();
hsPanel.setLeftWidget(new HTML(text));
hsPanel.setRightWidget(new HTML(text));
RootPanel.get("horizontal-split-panel").add(hsPanel);
}

42
Supporting Code
private String getSplitPanelText() {
String text =
"<p><b>Here is some text for " +
"each side of the splitter. " +
"Drag
Drag the splitter and the text " +
"will be rearranged.</b></p>" +
"<p>" + getRandomText() + "</p>";
return(text);
}

43

Example Results

44
Underlying HTML
<div id="horizontal-split-panel">
<div class="gwt-HorizontalSplitPanel"
class gwt HorizontalSplitPanel
style="position: relative; height: 300px; width: 475px;">
<div style="… position: absolute; …">
<div style="… position: absolute; … width: 120px;">…</div>
<div style="position: absolute; … left: 120px;">
<table class="hsplitter" … >
<tbody>
<t >
<tr>
<td valign="middle" align="center">
<img (splitter image) …/>
</td>
</tr></tbody></table>
</div>
<div style=" … left: 127px;">…</div>
</div></div></div>

45

© 2009 Marty Hall

VerticalSplitPanel

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.
Summary
• Purpose
– To put two widgets (usually HTML widgets or Panels)
on top of each other and let end user drag divider
– Similar to Swing
Swing’ss JSplitPane with VERTICAL_SPLIT
VERTICAL SPLIT
• Main methods
– setSize(String
S (S g sizeDescriptor)
p )
• You usually give a fixed size
– setSplitPosition(String positionDescriptor)
• Usually
U ll sett iin percent,
t e.g., setSplitPosition("30%")
tS litP iti ("30%")
– setTopWidget(Widget w)
g ( g w))
– setBottomWidget(Widget

47

Example Code
private void addVerticalSplitPanel() {
VerticalSplitPanel vsPanel =
new VerticalSplitPanel();
vsPanel.setSize("475px", "300px");
vsPanel setSplitPosition("30%");
vsPanel.setSplitPosition( 30% );
String text = getSplitPanelText();
vsPanel.setTopWidget(new HTML(text));
vsPanel.setBottomWidget(new HTML(text));
RootPanel.get("vertical-split-panel").add(vsPanel);
}

48
Example Results

49

Underlying HTML
• See example from HorizontalSplitPanel

50
© 2009 Marty Hall

PopupPanel

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.

Summary
• Purpose
– To make temporary popup window.
window Also see DialogBox class.
class
• Usually contains warning, info, or asks for input: something that
user should take action on immediately
– Similar to Swing’s JDialog
• B
Butt note
t that
th t this
thi iis an HTML div
di with
ith absolute
b l t positioning,
iti i nott a
native dialog box. Use Window.alert for native dialog.
• Constructor
– New PopupPanel(boolean autoClose)
• true means close when user clicks outside popup
• Main methods
– setWidget(Widget popupContents)
– setPopupPosition(int x, int y)
• In absolute screen coordinates
– setAnimationEnabled(true)
• So
S popup ffades
d iin/out
/ t
– show(), hide()
• You don’t add a popup, you open it (show) and close it (hide)
52
Example Code
private void addButtonForPopup() {
Button button = new Button("Click to Make Popup");
button.addClickHandler(new PopupHandler());
RootPanel.get("button-for-popup").add(button);
}

53

Example Code (Continued)


private class PopupHandler implements ClickHandler {
public void onClick(ClickEvent event) {
PopupPanel popup = new PopupPanel(true);
String text =
"Click
Click <i>outside</i> popup<br/>to close it";
it ;
VerticalPanel vPanel = makeVerticalPanel(text, 2);
popup.setWidget(vPanel);
UIObject button = (UIObject)event.getSource();
int x = button.getAbsoluteLeft() + 100;
int y = button.getAbsoluteTop() - 100;
popup.setPopupPosition(x,
p p p p p ( , y);
popup.setAnimationEnabled(true);
popup.show();
}
}

54
Example Results

55

Underlying HTML
<div class="gwt-PopupPanel"
style="overflow:
style= overflow: visible;
left: 112px; top: 1921px; position: absolute;
clip: rect(auto, auto, auto, auto);">
<div class="popupContent">
<table cellspacing="5" cellpadding="0">
<tbody>
<tr>…Text…</tr>
<tr>…First Button…</tr>
<tr>…Second Button…</tr>
</tbody>
</table>
</div>
</div>

56
© 2009 Marty Hall

Wrap-up

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.

Other Panel Types


• FlowPanel
– Wid
Widgets
t th
thatt you add
dd have
h the
th normall flow
fl off whatever
h t
HTML element you use for the panel placeholder.
• HTMLPanel
– A panel that contains HTML, but where you can add widgets
to any HTML sub-element that has an id. Has helper method
to create unique ids.
• FlexTable
Fl T bl
– More powerful table creator than Grid. Can add rows and
columns on the fly, and can have rowspan and colspan.
• AbsolutePanel
– A panel that positions all of its children absolutely, allowing
them to overlap.
p
• StackPanel and DecoratedStackPanel
– Like TabPanel, but arranged vertically instead of horizontally.
58
Summary
• Main layout approaches
– HTML-based:
HTML b d best b t for
f simple
i l apps with
ith light
li ht GWT usage
– Java-based: best for heavy use of GWT and desktop feel
• Most common Panel types
– HorizontalPanel, VerticalPanel
• Like BoxLayout from desktop Java
– TabPanel , DecoratedTabPanel
• Like JTabbedPane from desktop Java
– DockPanel
• Like BorderLayout from desktop Java
– Grid
• Like GridLayout from desktop Java
– HorizontalSplitPanel, VerticalSplitPanel
• Like JSplitPane from desktop Java
– PopupPanel (and DialogBox)
59
• Like JDialog from desktop Java

© 2009 Marty Hall

Questions?

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.

Вам также может понравиться