tag:blogger.com,1999:blog-86096817901140227752024-02-20T09:09:50.848+01:00Just my 2 cents about JavaIn this blog I will share my opinions about Java in general, JavaFX 2.0 and software development as a whole.Anonymoushttp://www.blogger.com/profile/06758323276772641565noreply@blogger.comBlogger11125tag:blogger.com,1999:blog-8609681790114022775.post-57484580302759016672012-07-03T17:03:00.000+02:002012-10-29T21:59:02.867+01:00JavaFX 2.0 Layout Panes - GridPane<div style="text-align: center;">
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" rel="stylesheet" type="text/css"></link>
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" rel="stylesheet" type="text/css"></link>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript">
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js" type="text/javascript">
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js" type="text/javascript">
</script>
<script language="javascript">
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBNuEC55ut4dxMmIhQaNlbNfsOjmbVLaUoJxc5sY7QQ2AXi8Pvz1XoTzdNYKs6cPohKg7Cx2F28n4A7tvq4n12wbY6GHysSq0TYQtRIOU8RFYUJxK8F7tSKpMH4rRTgijZAcj8QOKRNCrW/s1600/2012_06_24+-+gridpane+example3.png" imageanchor="1"><img border="0" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBNuEC55ut4dxMmIhQaNlbNfsOjmbVLaUoJxc5sY7QQ2AXi8Pvz1XoTzdNYKs6cPohKg7Cx2F28n4A7tvq4n12wbY6GHysSq0TYQtRIOU8RFYUJxK8F7tSKpMH4rRTgijZAcj8QOKRNCrW/s320/2012_06_24+-+gridpane+example3.png" width="320" /></a></div>
<br />
The <code>GridPane</code> is without a doubt the most powerfull and flexible layout pane in JavaFX 2.0.<br />
It lays out its children in a flexible grid of columns and rows and is very similar to Swing´s <code>GridBagLayout</code> or HTML´s table model. This approach makes this pane very well suited for any kind of form (like contact forms on a website).<br />
You have the ability to...
<br />
<ul>
<li>
apply any <code>Node</code> to a cell (specified by column and row) in the <code>GridPane</code>
</li>
<li>
to let the <code>Node</code> span multiple columns/rows
</li>
<li>
to align the <code>Node</code> in the cell it was applied to
</li>
<li>
to set horizontal or vertical grow for the <code>Node</code>
</li>
<li>
and to apply a margin to be kept around the <code>Node</code> in the cell.
</li>
</ul>
The flexibility of the <code>GridPane</code> also extends to a very flexible API. You can use static class methods like <code>setColumnIndex(node, index)</code> or <code>setRowSpan(node, value)</code>, or you can use convenience instance methods like <code>gridpane.add(node, column, row, columnSpan, rowSpan)</code>.<br />
<br />
<b>Note:</b>
<br />
<ul>
<li>
You don´t have to set the maximum number of columns or rows in the <code>GridPane</code> as it will grow automatically.
</li>
<li>
The size of one column is automatically determined by the widest <code>Node</code> in this column, the height of each row is determined by the tallest <code>Node</code> in the row.
</li>
</ul>
The last note is probably the most important fact about the <code>GridPane</code> as it has to be considered for the column/row and the column span/row span of every single <code>Node</code> in order to get the layout you want.<br />
For more complex layouts it is a very good idea to draw the layout on a piece of paper and to draw all lines for the columns and rows. This will ease development because you can diretly see in which cell you have to put each <code>Node</code> and how many rows or columns they have to span.<br />
<br />
Lets have a look at the first simple example:<br />
<a name='more'></a><br />
<h1>
GridPane – Example 1</h1>
<pre class="brush: java">import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
/**
* Created on: 23.06.2012
* @author Sebastian Damm
*/
public class GridPaneExample extends Application
{
@Override
public void start(Stage primaryStage) throws Exception
{
GridPane gridPane = new GridPane();
gridPane.setPadding(new Insets(40, 0, 0, 50));
gridPane.setHgap(5); gridPane.setVgap(5);
Scene scene = new Scene(gridPane, 300, 150);
Label lbUser = new Label("Username:");
GridPane.setHalignment(lbUser, HPos.RIGHT);
TextField tfUser = new TextField();
Label lbPass = new Label("Password:");
GridPane.setHalignment(lbPass, HPos.RIGHT);
PasswordField tfPass = new PasswordField();
Button btLogin = new Button("Login");
GridPane.setMargin(btLogin, new Insets(10, 0, 0, 0));
gridPane.add(lbUser, 0, 0);
gridPane.add(tfUser, 1, 0);
gridPane.add(lbPass, 0, 1);
gridPane.add(tfPass, 1, 1);
gridPane.add(btLogin, 1, 2);
primaryStage.setTitle("GridPaneExample 1");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{ Application.launch(args); }
}
</pre>
<br />
Here you can see a little login form with with two labels and two textfields for the username and the password. Additionally theres a 'login' button.<br />
In lines 21-23 we create the <code>GridPane</code> and apply some padding. Furthermore you can specify a horizontal and a vertical gap to be kept between each <code>Node</code>. Next, take a look at line 28: The alignment of a <code>Node</code> inside the boundaries of the cell it was put into, can be set with the static class methods <code>GridPane.setHalignment(Node node, HPos pos)</code>, respectively <code>GridPane.setValignment(Node node, VPos pos)</code>.<br />
<br />
In line 36 you can see how to put a individual margin around a single <code>Node</code> by using the <code>GridPane.setMargin(Node node, Insets insets)</code> method.<br />
Finally in lines 38 to 42 we add each <code>Node</code> to the <code>GridPane</code> and specify the column and the row of the <code>Node</code>.<br />
<br />
Your application should look like this now:<br />
<br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZPoyuTv9VHKDKAiwHrZsou3mS-MJRB2CKiNuaOB4xxrmrWn00zz3TQ_CJjlb1avLCMDA7wnwjoRl41w1UdK2k4zcVoRNxLubCV6zsvqxU8h6t0FhxZWgCufPm65ENwLJFCp7uZKaD_Uka/s1600/2012_06_24+-+gridpane+example1.png" imageanchor="1"><img border="0" height="186" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZPoyuTv9VHKDKAiwHrZsou3mS-MJRB2CKiNuaOB4xxrmrWn00zz3TQ_CJjlb1avLCMDA7wnwjoRl41w1UdK2k4zcVoRNxLubCV6zsvqxU8h6t0FhxZWgCufPm65ENwLJFCp7uZKaD_Uka/s320/2012_06_24+-+gridpane+example1.png" width="316" /></a>
</div>
<br />
<br />
In the next example you will see, why we need to set the column span and the row span of each <code>Node</code> in more complex layouts. Have a look at this code:<br />
<br />
<h1>
GridPane – Example 2: User form </h1>
<pre class="brush: java">import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.paint.RadialGradientBuilder;
import javafx.scene.paint.Stop;
import javafx.stage.Stage;
/**
* Created on: 23.06.2012
* @author Sebastian Damm
*/
public class GridPaneExample2 extends Application
{
private final Paint background = RadialGradientBuilder.create()
.stops(new Stop(0d, Color.TURQUOISE), new Stop(1, Color.web("3A5998")))
.centerX(0.5d).centerY(0.5d).build();
private final String LABEL_STYLE = "-fx-text-fill: white; -fx-font-size: 14;"
+ "-fx-effect: dropshadow(one-pass-box, black, 5, 0, 1, 1);";
@Override
public void start(Stage primaryStage) throws Exception
{
Scene scene = new Scene(createGridPane(), 370, 250, background);
primaryStage.setTitle("GridPaneExample 2 - User form");
primaryStage.setScene(scene);
primaryStage.show();
}
private GridPane createGridPane()
{
GridPane gridPane = new GridPane();
gridPane.setPadding(new Insets(20, 0, 20, 20));
gridPane.setHgap(7); gridPane.setVgap(7);
Label lbFirstName = new Label("First Name:");
lbFirstName.setStyle(LABEL_STYLE);
GridPane.setHalignment(lbFirstName, HPos.RIGHT);
TextField tfFirstName = new TextField();
Label lbLastName = new Label("Last Name:");
lbLastName.setStyle(LABEL_STYLE);
GridPane.setHalignment(lbLastName, HPos.RIGHT);
TextField tfLastName = new TextField();
Label lbCity = new Label("City:");
lbCity.setStyle(LABEL_STYLE);
GridPane.setHalignment(lbCity, HPos.RIGHT);
TextField tfCity = new TextField();
Label lbStreetNr = new Label("Street/Nr.:");
lbStreetNr.setStyle(LABEL_STYLE);
GridPane.setHalignment(lbStreetNr, HPos.RIGHT);
TextField tfStreet = new TextField();
tfStreet.setPrefColumnCount(14);
GridPane.setColumnSpan(tfStreet, 2);
TextField tfNumber = new TextField();
tfNumber.setPrefColumnCount(3);
Label lbNotes = new Label("Notes:");
lbNotes.setStyle(LABEL_STYLE);
GridPane.setHalignment(lbNotes, HPos.RIGHT);
TextArea taNotes = new TextArea();
taNotes.setPrefColumnCount(5);
taNotes.setPrefRowCount(5);
GridPane.setColumnSpan(taNotes, 3);
GridPane.setRowSpan(taNotes, 2);
ImageView imageView = new ImageView(new Image(getClass()
.getResourceAsStream("person.png"), 0, 65, true, true));
GridPane.setHalignment(imageView, HPos.LEFT);
GridPane.setColumnSpan(imageView, 2);
GridPane.setRowSpan(imageView, 3);
// gridPane.setGridLinesVisible(true);
gridPane.add(lbFirstName, 0, 0); gridPane.add(tfFirstName, 1, 0);
gridPane.add(imageView, 2, 0); gridPane.add(lbLastName, 0, 1);
gridPane.add(tfLastName, 1, 1); gridPane.add(lbCity, 0, 2);
gridPane.add(tfCity, 1, 2); gridPane.add(lbStreetNr, 0, 3);
gridPane.add(tfStreet, 1, 3); gridPane.add(tfNumber, 3, 3);
gridPane.add(lbNotes, 0, 4); gridPane.add(taNotes, 1, 4);
return gridPane;
}
public static void main(String[] args)
{ Application.launch(args); }
}
</pre>
<br />
In this example we create a user form with different inputs and an image. To make the application appear a little nicer, i created a <code>RadialGradient</code> for the background of the <code>Scene</code> and applied a white font color and a little dropshadow to each label.<br />
<br />
The application should look like this:<br />
<br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibXBPASnD3cSRbceBRqr4KtxxHMbze6oIgECREzv4CYywWZtl5pSQc7Yb-51sFox4rwXR6hVaK0IWANZ46rQEICo6-9XoThhJQ2xulW32RctVs5MD9SMycJ4r3lLkE0jD6mse3gZ-_PKyC/s1600/2012_06_24+-+gridpane+example2.png" imageanchor="1"><img border="0" height="237" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibXBPASnD3cSRbceBRqr4KtxxHMbze6oIgECREzv4CYywWZtl5pSQc7Yb-51sFox4rwXR6hVaK0IWANZ46rQEICo6-9XoThhJQ2xulW32RctVs5MD9SMycJ4r3lLkE0jD6mse3gZ-_PKyC/s320/2012_06_24+-+gridpane+example2.png" width="320" /></a>
</div><br />
Compared to the previous example, the first difference occurs in line 64.<br />
With <code>GridPane.setColumnSpan(tfStreet, 2);</code> i tell this <code>TextField</code> to occupy two columns. This is needed, because i want this textfield to be a little wider (see line 63) than the other textfields. Otherwise the second column would be as wide as this textfield and therefore stretch the smaller ones.<br />
The <code>TextArea</code> (starting at line 71) and the <code>ImageView</code> (line 77) span across multiple columns and rows.
<br />
Next, take a look at line 83. If you remove the comment lines and start the application, it should look like this:<br /><br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhN1tYP1M_Fo5-Ddh25plgBk0bPLeNs-ssAnOMkiN3vPYdlalTFADZBXVe2ZMw_NAnytF5ZRj3Unu5WVCOH_GrJ4mD_rRdkGAWCDYze1kZLrzECo2tnR4cWkKTp1zVJbPA5dwlFuVH2bkK4/s1600/2012_06_24+-+gridpane+example2+with+grid+lines.png" imageanchor="1"><img border="0" height="237" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhN1tYP1M_Fo5-Ddh25plgBk0bPLeNs-ssAnOMkiN3vPYdlalTFADZBXVe2ZMw_NAnytF5ZRj3Unu5WVCOH_GrJ4mD_rRdkGAWCDYze1kZLrzECo2tnR4cWkKTp1zVJbPA5dwlFuVH2bkK4/s320/2012_06_24+-+gridpane+example2+with+grid+lines.png" width="320" /></a>
<br />
</div><br />
As you can see, this method makes all grid lines (including the horizontal and vertical gap between each <code>Node</code> visible which can be a great help if your <code>Nodes</code> arent aligned the way you want it.<br />
I don´t know how many times i wished for a method like this during the time i learned Swing and the <code>GridBagLayout</code> and i bet that i´m not the only one ;)<br />
<br />
Finally, please remove all lines, where column span or row span are specified (lines 64, 74, 75, 80, 81). This will help you to understand the necessity of column span and row span.<br /><br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH5i7iYFl33-DK05H8pyYZJERdVeOT9bsSWkdlUeBt1r_WMHgBOl76CtTBnW6tWHFF3lBTNqtSd3fHhMkB6hvePq0Lg8Rg3LaLro7hqr2EC3H4OyQEBqTWO-U5UZptpghAYLJhayZ64E-T/s1600/2012_06_24+-+gridpane+example2+no+span.png" imageanchor="1"><img border="0" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH5i7iYFl33-DK05H8pyYZJERdVeOT9bsSWkdlUeBt1r_WMHgBOl76CtTBnW6tWHFF3lBTNqtSd3fHhMkB6hvePq0Lg8Rg3LaLro7hqr2EC3H4OyQEBqTWO-U5UZptpghAYLJhayZ64E-T/s320/2012_06_24+-+gridpane+example2+no+span.png" width="320" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-v4L5Lqi7PAyBS9X6rT_MMRDaYmUO0kyV1cX0QEvWKJikmnvUFtCAZ7gEPvtPs7-c1TJSe5JVCpb5qr9X6NB6PKmOSKsVELaLSAf0FRfPactg7dsnb1drTf1KWpwvSBEpfYmqopw-ybGc/s1600/2012_06_24+-+gridpane+example2+no+span+with+grid+lines.png" imageanchor="1"><img border="0" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-v4L5Lqi7PAyBS9X6rT_MMRDaYmUO0kyV1cX0QEvWKJikmnvUFtCAZ7gEPvtPs7-c1TJSe5JVCpb5qr9X6NB6PKmOSKsVELaLSAf0FRfPactg7dsnb1drTf1KWpwvSBEpfYmqopw-ybGc/s320/2012_06_24+-+gridpane+example2+no+span+with+grid+lines.png" width="320" /></a>
<br />
<p>You can see, that each <code>Node</code> occupies one single cell and that the layout is pretty messed up because the width/height of each column/row depend on the widest/tallest child <code>Node</code>.</p>
<br /><br />
<h1>GridPane – Example 3: The setConstraints method</h1>
<p>The instance method <code>add</code> "only" provides two versions, one with the <code>Node</code>, the column and the row, and one with additional column span and row span. Other properties like the alignment or the grow have to be set with dedicated class methods like <code>GridPane.setHalignment</code> like in the first two examples.</p>
<p>But theres another nice way: the <code>GridPane.setConstraints(...)</code>method.</p> At the moment (JavaFX 2.2) there are five overloaded versions of this method from
<blockquote><code>setConstraints(Node child, int columnIndex, int rowIndex)</code></blockquote>
<p>to</p>
<blockquote><code>setConstraints(Node child, int columnIndex, int rowIndex, int columnspan, int rowspan, HPos halignment, VPos valignment, Priority hgrow, Priority vgrow, Insets margin)</code>.</blockquote></p>
<p>This is pretty similiar to Swing´s <code>GridBagConstraints</code> but here you don´t have to create a dedicated object and reuse it for multiple graphical objects.</p>
<p>If you apply the constraints to every <code>Node</code> like this, you can simply add the <code>Nodes</code> to the <code>GridPane´s</code> collections of children.</p>
<p>With this approach the code of the second example looks like this:</p>
<pre class="brush: java">
private GridPane createGrid()
{
GridPane gridPane = new GridPane();
gridPane.setPadding(new Insets(20, 0, 20, 20));
gridPane.setHgap(7); gridPane.setVgap(7);
Label lbFirstName = new Label("First Name:");
lbFirstName.setStyle(LABEL_STYLE);
GridPane.setConstraints(lbFirstName, 0, 0, 1, 1, HPos.RIGHT, VPos.CENTER);
TextField tfFirstName = new TextField();
GridPane.setConstraints(tfFirstName, 1, 0);
Label lbLastName = new Label("Last Name:");
lbLastName.setStyle(LABEL_STYLE);
GridPane.setConstraints(lbLastName, 0, 1, 1, 1, HPos.RIGHT, VPos.CENTER);
TextField tfLastName = new TextField();
GridPane.setConstraints(tfLastName, 1, 1);
Label lbCity = new Label("City:");
lbCity.setStyle(LABEL_STYLE);
GridPane.setConstraints(lbCity, 0, 2, 1, 1, HPos.RIGHT, VPos.CENTER);
TextField tfCity = new TextField();
GridPane.setConstraints(tfCity, 1, 2);
Label lbStreetNr = new Label("Street/Nr.:");
lbStreetNr.setStyle(LABEL_STYLE);
GridPane.setConstraints(lbStreetNr, 0, 3, 1, 1, HPos.RIGHT, VPos.CENTER);
TextField tfStreet = new TextField();
tfStreet.setPrefColumnCount(14);
GridPane.setConstraints(tfStreet, 1, 3, 2, 1);
TextField tfNumber = new TextField();
tfNumber.setPrefColumnCount(3);
GridPane.setConstraints(tfNumber, 3, 3);
Label lbNotes = new Label("Notes:");
lbNotes.setStyle(LABEL_STYLE);
GridPane.setConstraints(lbNotes, 0, 4, 1, 1, HPos.RIGHT, VPos.CENTER);
TextArea taNotes = new TextArea();
taNotes.setPrefColumnCount(5);
taNotes.setPrefRowCount(5);
GridPane.setConstraints(taNotes, 1, 4, 3, 2);
ImageView imageView = new ImageView(new Image(getClass()
.getResourceAsStream("person.png"), 0, 65, true, true));
GridPane.setConstraints(imageView, 2, 0, 3, 3, HPos.LEFT, VPos.CENTER);
gridPane.getChildren().addAll(lbFirstName, tfFirstName, imageView
, lbLastName, tfLastName, lbCity, tfCity, lbStreetNr, tfStreet
, tfNumber, lbNotes, taNotes);
return gridPane;
}
</pre>
<br />
<p>You can see the usage of the overloaded <code>setConstraints(...)</code> methods and how you can simply add the <code>Nodes</code> to the <code>GridPane</code> in lines 51-53.</p>
<p>I hope i could provide a good introduction to the <code>GridPane</code> in JavaFX 2.0. Feel free to add comments and post questions.</p>Anonymoushttp://www.blogger.com/profile/06758323276772641565noreply@blogger.com16tag:blogger.com,1999:blog-8609681790114022775.post-11498269910976312132012-06-25T17:57:00.000+02:002012-09-22T19:18:08.245+02:00JavaFX 2.0 Layout Panes - AnchorPane<link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" rel="stylesheet" type="text/css"></link>
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" rel="stylesheet" type="text/css"></link>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript">
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js" type="text/javascript">
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js" type="text/javascript">
</script>
<script language="javascript">
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script>
<p>An <code>AnchorPane</code> is similar to a <code>BorderPane</code> (see my previous post <a href="http://dammsebastian.blogspot.de/2012/03/javafx-20-layot-panes-borderpane.html">JavaFX 2.0 Layout Panes - BorderPane</a>) as it also provides several areas or regions for your nodes.</p>
<p>In contrast to a <code>BorderPane</code>, an <code>AnchorPane</code> provides only four different regions: Left, Right, Bottom and Top (a <code>BorderPane</code> additionally provides a center region).</p>
<p>There are several more major differences between the two panes:
<ul>
<li>
In an <code>AnchorPane</code> you can anchor multiple nodes to one area (in a <code>BorderPane</code> you can only set one node to each area).
</li>
<li>
In an <code>AnchorPane</code> you can anchor one single node to multiple areas, i.e. anchoring a <code>Button</code> to the left and the top of the <code>AnchorPane</code>, whereas in a <code>BorderPane</code> every node can only be applied to one area.
</li>
<li>
In an <code>AnchorPane</code> you can specify the offset to the anchor.
</li>
<li>
A <code>BorderPane</code> provides instance methods to populate each area (i.e. <code>setCenter(Node node)</code>, <code>setRight(Node node)</code>, ...). An <code>AnchorPane</code> offers static methods like <code>AnchorPane.setTopAnchor(Node node, Double offset)</code> that are applied directly to a <code>Node</code>.
</li>
<li>
In a <code>BorderPane</code> each child will grow and shrink with its parent depending on the area it is applied to. In an <code>AnchorPane</code> children will only be resized/stretched if they are anchored to opposite sides of the pane.
For example if a <code>Button</code> is anchored to the left and the right anchor of an <code>AnchorPane</code>, the <code>Button</code> will be stretched horizontally.
</li>
</ul></p>
<br />
<p>Please take a look at this first simple example:</p>
<a name='more'></a>
<br />
<h1>AnchorPane – Example 1</h1>
<pre class="brush: java">
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/**
* Created on: 16.06.2012
* @author Sebastian Damm
*/
public class AnchorPaneExample extends Application
{
private final String LABEL_STYLE = "-fx-font: 20pt Cambria; "
+ "-fx-text-fill: white; "
+ "-fx-effect: dropshadow(one-pass-box, black, 10, 0, 3, 3);";
@Override
public void start(Stage primaryStage) throws Exception
{
AnchorPane root = new AnchorPane();
Scene scene = new Scene(root, 400, 200, Color.ROYALBLUE);
Label lb1 = new Label("Top Anchor");
lb1.setStyle(LABEL_STYLE);
AnchorPane.setTopAnchor(lb1, 10d);
AnchorPane.setLeftAnchor(lb1, 150d);
Label lb2 = new Label("Right Anchor");
lb2.setStyle(LABEL_STYLE);
AnchorPane.setRightAnchor(lb2, 10d);
AnchorPane.setTopAnchor(lb2, 85d);
Label lb3 = new Label("Bottom Anchor");
lb3.setStyle(LABEL_STYLE);
AnchorPane.setBottomAnchor(lb3, 10d);
AnchorPane.setLeftAnchor(lb3, 138d);
Label lb4 = new Label("Left Anchor");
lb4.setStyle(LABEL_STYLE);
AnchorPane.setLeftAnchor(lb4, 10d);
AnchorPane.setTopAnchor(lb4, 85d);
root.getChildren().addAll(lb1, lb2, lb3, lb4);
primaryStage.setTitle("AnchorPaneExample 1");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{ Application.launch(args); }
}
</pre>
<br />
<p>For this first example we just create some <code>Labels</code>, apply some custom style (a dedicated post about css styling in an external css file will be posted once the series about layout panes is done) and anchor them at two anchors. The last step is to add all labels to the collection of childrens of the <code>AnchorPane</code>. Otherwise, the applied anchors won´t have any effect.</p>
<p>Your application should look like this now:</p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOJleiji3dmszZ12mEVbiC85GU6opSUu9zJUDHbnFuFpE0l1paGAPmReVzeAKCLaBR4UGyC8Zp53vja_kzuSW0LyWszEoUz_Kf_yH5f8Nxaegy7CvQBkI58S_RMxmCFFhh1SHSI9sTQYty/s1600/anchorPaneExample1+normal.png" imageanchor="1" style=""><img border="0" height="182" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOJleiji3dmszZ12mEVbiC85GU6opSUu9zJUDHbnFuFpE0l1paGAPmReVzeAKCLaBR4UGyC8Zp53vja_kzuSW0LyWszEoUz_Kf_yH5f8Nxaegy7CvQBkI58S_RMxmCFFhh1SHSI9sTQYty/s320/anchorPaneExample1+normal.png" /></a>
<p>If you resize your window, it should look like one of the following two pictures:</p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIASe18PvH1Om-3pA2AzUtFIhvmL6m5bNtylVEl8j7EEP9PbJ2GW_qRun-hTN2AMNlEnjmAYttl_ynfErXsx7BZ2PWkTxdwJYhUYdiiHCp4WtpCe5aS8gUNphYnkq0nHkyPAftR94eIUbH/s1600/anchorPaneExample1+stretched+horizontally.png" imageanchor="1" style=""><img border="0" height="320" width="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIASe18PvH1Om-3pA2AzUtFIhvmL6m5bNtylVEl8j7EEP9PbJ2GW_qRun-hTN2AMNlEnjmAYttl_ynfErXsx7BZ2PWkTxdwJYhUYdiiHCp4WtpCe5aS8gUNphYnkq0nHkyPAftR94eIUbH/s320/anchorPaneExample1+stretched+horizontally.png" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuCwFPKtdset63a0SbhXDUZAkJnGmYKz5ilwHrgDvLpRCtZpMJwppOLSG5x4zuE1fQCzJqaPfszSzSi89Azu_8i3UigPFZw3iqs5JRUtcoiFeAYJWYlUKEtL3pKc0FgPLOeOdZoypflZOQ/s1600/anchorPaneExample1+stretched+vertically.png" imageanchor="1" style=""><img border="0" height="85" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuCwFPKtdset63a0SbhXDUZAkJnGmYKz5ilwHrgDvLpRCtZpMJwppOLSG5x4zuE1fQCzJqaPfszSzSi89Azu_8i3UigPFZw3iqs5JRUtcoiFeAYJWYlUKEtL3pKc0FgPLOeOdZoypflZOQ/s320/anchorPaneExample1+stretched+vertically.png" /></a>
<br/ >
<p>You can see, that all labels maintain their position based on the anchors, they were applied to and the given offset.</p>
<br /> <br />
<p>In the next small example you will see the 'stretching' of the child nodes i mentioned at the beginning of this blog post: </p>
<br />
<h1>AnchorPane – Example 2: Stretching child nodes</h1>
<pre class="brush: java">
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/**
* Created on: 16.06.2012
* @author Sebastian Damm
*/
public class AnchorPaneExample2 extends Application
{
@Override
public void start(Stage primaryStage) throws Exception
{
AnchorPane root = new AnchorPane();
Scene scene = new Scene(root, 400, 200, Color.ROYALBLUE);
Button b1 = new Button("Button 1");
AnchorPane.setTopAnchor(b1, 10d);
AnchorPane.setLeftAnchor(b1, 20d);
AnchorPane.setRightAnchor(b1, 20d);
Button b2 = new Button("Button 2");
AnchorPane.setTopAnchor(b2, 50d);
AnchorPane.setBottomAnchor(b2, 20d);
AnchorPane.setLeftAnchor(b2, 170d);
root.getChildren().addAll(b1, b2);
primaryStage.setTitle("AnchorPaneExample 2 - Stretching child nodes");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{ Application.launch(args); }
}
</pre>
<br />
<p>This example contains two buttons, that are anchored to opposite sides of the <code>AnchorPane</code>(the third anchor is only applied to prevent an overlay of the two buttons). In order to keep the specified offset, the <code>AnchorPane</code> will stretch the <code>Node</code>, as long as it is a resizable <code>Node</code>. In the case of a non-resizable <code>Node</code>, only the top and the left anchor will be considered.</p>
<p>This code should result in something like this:</p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBCPDE8UWbFyoI2p2rS3-5M5A3berLgQ-pkE_WGol2vbCq5ZsygQqqxuZaSa7yxv_ETBZGt5-vMD3ngri6BfavSV_jkUt_gs2x32WW0KVQrHwYhe85FKZcyv4XX5WtBhUmUVd5sT7X7BD0/s1600/anchorPaneExample2+normal.png" imageanchor="1" style=""><img border="0" height="182" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBCPDE8UWbFyoI2p2rS3-5M5A3berLgQ-pkE_WGol2vbCq5ZsygQqqxuZaSa7yxv_ETBZGt5-vMD3ngri6BfavSV_jkUt_gs2x32WW0KVQrHwYhe85FKZcyv4XX5WtBhUmUVd5sT7X7BD0/s320/anchorPaneExample2+normal.png" /></a>
<br /> <br />
<p>By resizing the window, the buttons should be stretched like in the following two screenshots:</p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrL64-PnNmMGYtgkeOfXwlaa-hveJHAori_HOBVEaCnlaMFFGW9QSAxrO2MzYpHiFrs3bR-xKfdzDqNH4_E5ba-VqPX_Z__A50jJezHkbfqyz0iEBzjzowWhWr131ucmB2Yg-GXcX_BnmF/s1600/anchorPaneExample2+stretched+vertically.png" imageanchor="1" style=""><img border="0" height="320" width="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrL64-PnNmMGYtgkeOfXwlaa-hveJHAori_HOBVEaCnlaMFFGW9QSAxrO2MzYpHiFrs3bR-xKfdzDqNH4_E5ba-VqPX_Z__A50jJezHkbfqyz0iEBzjzowWhWr131ucmB2Yg-GXcX_BnmF/s320/anchorPaneExample2+stretched+vertically.png" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRsXp29faLug3LbxyyGiYQ8_g0-rcfB882q1nAEGlmrgz1vcVXlCBQRjQxgNWIL2DW29tZ_qqAmaWKozf3kzfKp-0eY9HCg_GRz5KDYnSSjC84J33JVrWBKcvzsE9yJWMqgmSQ3htC4TL-/s1600/anchorPaneExample2+stretched+horizontally.png" imageanchor="1" style=""><img border="0" height="73" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRsXp29faLug3LbxyyGiYQ8_g0-rcfB882q1nAEGlmrgz1vcVXlCBQRjQxgNWIL2DW29tZ_qqAmaWKozf3kzfKp-0eY9HCg_GRz5KDYnSSjC84J33JVrWBKcvzsE9yJWMqgmSQ3htC4TL-/s320/anchorPaneExample2+stretched+horizontally.png" /></a>
<p>So, these are the basics of the <code>AnchorPane</code>. Generally, i like a <code>BorderPane</code> more, but i think thats also up to personal preferences, because you can create the same layout in both panes. But in my experience, most layouts could be realized faster and with less code in a <code>BorderPane</code>. </p>
<br /> <br />Anonymoushttp://www.blogger.com/profile/06758323276772641565noreply@blogger.com3tag:blogger.com,1999:blog-8609681790114022775.post-52546136383222756822012-05-10T14:53:00.000+02:002012-10-29T21:57:37.024+01:00JavaFX 2.0 Layout Panes - BorderPane<link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" rel="stylesheet" type="text/css"></link>
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" rel="stylesheet" type="text/css"></link>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript">
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js" type="text/javascript">
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js" type="text/javascript">
</script>
<script language="javascript">
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script>
<p>A <code>BorderPane</code> is very well suited to develop more complex layouts. In general the <code>BorderPane</code> provides five different regions: Top, Right, Bottom, Left and Center. You can set a <code>Node</code> to each of these areas by calling the <code>setTop/setBottom/set…</code> methods. This approach makes it very easy to develop “website-like” application windows where you have a menubar or toolbar at the top, a navigation on the left, some kind of footer at the bottom, your main content in the center area and possibly some additional information at the right. </p>
<p>It is important to know, that each of these areas resizes differently:
<ul>
<li>
The top and bottom areas will resize to their children preferred height and take all space available for their width.
</li>
<li>
The left and right areas will resize to their children preferred width and take all space available for their height.
</li>
<li>
The center area takes all space available for its height and its width.
</li>
</ul></p>
<p>Following graphic demonstrates the behavior of a <code>BorderPane</code> when resizing your application window: </p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizgNgW_GkuMJd6B0wPDCjbwcWnwC78prugmYENnQp-LSdrcUrDBf2Beik1j2F0r5A1gJFRBJWSmeL9UTRsYOA-zO_F5gMWvPjlDlUFQ22REEzk2NsXIB7yUow4SP7mXDRLEQ3dyJhn56Yx/s1600/borderpane_architecture.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="247" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizgNgW_GkuMJd6B0wPDCjbwcWnwC78prugmYENnQp-LSdrcUrDBf2Beik1j2F0r5A1gJFRBJWSmeL9UTRsYOA-zO_F5gMWvPjlDlUFQ22REEzk2NsXIB7yUow4SP7mXDRLEQ3dyJhn56Yx/s320/borderpane_architecture.png" /></a><br />Source: own illustration</div>
<p>Take a look at this example:</p>
<br />
<a name='more'></a>
<h1>BorderPane – Example</h1>
<br />
<pre class="brush: java">
/**
* Created on: 29.03.2012
* @author Sebastian Damm
*/
public class BorderPaneExample extends Application
{
private BorderPane root;
@Override
public void start(Stage primaryStage) throws Exception
{
root = new BorderPane();
root.setTop(getMenu());
root.setRight(getRightHBox());
root.setBottom(getFooter());
root.setLeft(getLeftHBox());
root.setCenter(getCenterPane());
Scene scene = new Scene(root, 900, 500);
primaryStage.setTitle("BorderPane Example");
primaryStage.setScene(scene);
primaryStage.show();
}
private MenuBar getMenu()
{
MenuBar menuBar = new MenuBar();
Menu menuFile = new Menu("File");
Menu menuEdit = new Menu("Edit");
Menu menuHelp = new Menu("Help");
menuBar.getMenus().addAll(menuFile, menuEdit, menuHelp);
return menuBar;
}
private HBox getRightHBox()
{
HBox hbox = new HBox();
VBox vbox = new VBox(50);
vbox.setPadding(new Insets(0, 20, 0, 20));
vbox.setAlignment(Pos.CENTER);
vbox.getChildren().addAll(new Text("Additional Info 1"),
new Text("Additional Info 2"), new Text("Additional Info 3"));
hbox.getChildren().addAll(new Separator(Orientation.VERTICAL), vbox);
return hbox;
}
private HBox getLeftHBox()
{
HBox hbox = new HBox();
VBox vbox = new VBox(10);
vbox.setPadding(new Insets(10));
Text text = new Text("Navigation");
text.setFont(Font.font("Helvetica", FontWeight.BOLD, 20));
VBox vboxText = new VBox(10);
for (int i = 1; i <= 10; i++)
{
vboxText.getChildren().add(new Text("Category " + i));
}
vboxText.setTranslateX(10);
vbox.getChildren().addAll(text, vboxText);
hbox.getChildren().addAll(vbox, new Separator(Orientation.VERTICAL));
return hbox;
}
private VBox getFooter()
{
VBox vbox = new VBox();
HBox hbox = new HBox(20);
hbox.setPadding(new Insets(5));
hbox.setAlignment(Pos.CENTER);
hbox.getChildren().addAll(new Text("Footer Item 1")
, new Text("Footer Item 2"), new Text("Footer Item 3"));
vbox.getChildren().addAll(new Separator(), hbox);
return vbox;
}
private StackPane getCenterPane()
{
StackPane stackPane = new StackPane();
stackPane.setAlignment(Pos.CENTER);
Rectangle rec = new Rectangle();
rec.setFill(Color.DODGERBLUE);
rec.widthProperty().bind(stackPane.widthProperty().subtract(50));
rec.heightProperty().bind(stackPane.heightProperty().subtract(50));
stackPane.getChildren().addAll(rec);
return stackPane;
}
public static void main(String[] args)
{
Application.launch(args);
}
}</pre>
<br />
<p>This little application shows how to use a <code>BorderPane</code>. In the <code>start</code> method we only use the various <code>set…</code> methods of the <code>BorderPane</code> class in order to populate each area with a <code>Node</code>.</p>
<p>The top area is filled with a <code>MenuBar</code>. Here I simply create a <code>MenuBar</code> with three different <code>Menus</code>. In one of my next posts I will cover the creation of menus in JavaFX in depth.</p>
<p>Besides the menu there should only be one aspect of the code, that may be new to you.
Please take a look at line 100: </p>
<p>The center area of our <code>BorderPane</code> is populated with a <code>StackPane</code> that holds a <code>Rectangle</code>. Because a <code>Rectangle</code> doesn´t resize directly with its parent (like all <code>Shape</code> objects), we have to go for a different approach when we want to resize the <code>Rectangle</code>. This is why I <i>binded</i> the width and the height of the <code>Rectangle</code> to the width and the height of the <code>StackPane</code> (substracted by 50 pixels). When the size of the <code>StackPanes</code> is changed, the <code>Rectangle</code> will automatically be resized accordingly.</p>
<p>Here are three pictures of how your application should look like and how it should resize:</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijyF-FRMAOYPuM2KXy8HyxyaiNNPCc4yxMKWED7paeSRWECyKjCXFUIysbLHSy_6QoHIfWnSJK4ekrZyAB_9e9YqxKj5kOb8u_qYuvg1HXkSQvcQ1GSh8-w8rL495Llk4GtxehmH11fLy7/s1600/borderpane+example+-+pic1.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="239" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijyF-FRMAOYPuM2KXy8HyxyaiNNPCc4yxMKWED7paeSRWECyKjCXFUIysbLHSy_6QoHIfWnSJK4ekrZyAB_9e9YqxKj5kOb8u_qYuvg1HXkSQvcQ1GSh8-w8rL495Llk4GtxehmH11fLy7/s320/borderpane+example+-+pic1.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8fsO7RN9cI_ZRsGXb3cKFAc3mgDPZ54De1bBC9upwQWzr67f47p_8TxLslS823G1qEyRa-u9CS-m0PZ8dI2eNnkVJvYF7wGHmwbweGJR5CcD-1CYpGAWfgcfXupFeViMdAG-RB4sCb1D3/s1600/borderpane+example+-+pic2.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="132" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8fsO7RN9cI_ZRsGXb3cKFAc3mgDPZ54De1bBC9upwQWzr67f47p_8TxLslS823G1qEyRa-u9CS-m0PZ8dI2eNnkVJvYF7wGHmwbweGJR5CcD-1CYpGAWfgcfXupFeViMdAG-RB4sCb1D3/s320/borderpane+example+-+pic2.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7pCIZW1693YRfb2Nm0v0K5BpM5oGTJPr7NinR4ObIHjGbacSCSoDjjButNCPalcmhq4rLm0o6ICs5T7rKP6Kqedx8miLfkE18FqdGGSPLE4VyBNb98RnQrIL2N1-fBcMJR6UvyAPomu2O/s1600/borderpane+example+-+pic3.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="320" width="188" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7pCIZW1693YRfb2Nm0v0K5BpM5oGTJPr7NinR4ObIHjGbacSCSoDjjButNCPalcmhq4rLm0o6ICs5T7rKP6Kqedx8miLfkE18FqdGGSPLE4VyBNb98RnQrIL2N1-fBcMJR6UvyAPomu2O/s320/borderpane+example+-+pic3.png" /></a></div>
<p>As you can see the different areas of the <code>BorderPane</code> resize accordingly to the rules I illustrated at the top of this post.</p>Anonymoushttp://www.blogger.com/profile/06758323276772641565noreply@blogger.com11tag:blogger.com,1999:blog-8609681790114022775.post-69018321336328771962012-04-04T11:25:00.000+02:002012-09-22T19:26:04.640+02:00JavaFX 2.0 Layout Panes - FlowPane and TilePane<link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" rel="stylesheet" type="text/css"></link>
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" rel="stylesheet" type="text/css"></link>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript">
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js" type="text/javascript">
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js" type="text/javascript">
</script>
<script language="javascript">
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script>
<p> <code>FlowPanes</code> and <code>TilePanes</code> are nice layout panes, if you want to layout your children consecutively one after another, either horizontally or vertically. They are quite similiar to each other as both will layout their children either in columns (in case of a horizontal Flow/TilePane) and wrap at their width or in rows (in case of a vertical Flow/TilePane) and wrap at their height.</p>
<p>The only major difference is, that the <code>TilePane</code> places all children in tiles that are the same size! So the size of the greatest children is taken for the size of each individual tile in the <code>TilePane</code>. Therefore a <code>TilePane</code> is also a nice way to size and align buttons and other controls equally. (See my previous post <a href="http://dammsebastian.blogspot.de/2012/03/testest.html">Sizing Buttons equally inside a VBox or HBox</a>)</p>
<br />
<h1>FlowPane and TilePane – Example 1</h1>
<br />
<a name='more'></a>
<pre class="brush: java">
import java.util.Random;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
/**
*
* Created on: 24.03.2012
* @author Sebastian Damm
*/
public class FlowPaneAndTilePaneExample extends Application
{
private Random random;
private VBox root;
private FlowPane flowPane;
private TilePane tilePane;
@Override
public void start(Stage primaryStage) throws Exception
{
random = new Random();
root = new VBox(30);
VBox upperVBox = createUpperVBox();
VBox lowerVBox = createLowerVBox();
fillPanesWithImages();
root.getChildren().addAll(upperVBox, lowerVBox);
Scene scene = new Scene(root, 800, 600, Color.ANTIQUEWHITE);
primaryStage.setTitle("FlowPane and TilePane Example");
primaryStage.setScene(scene);
primaryStage.show();
}
private VBox createUpperVBox()
{
VBox vbox = new VBox(20);
Text textFlowPane = new Text("I am a FlowPane");
textFlowPane.setFont(Font.font("Calibri", FontWeight.BOLD, 30));
textFlowPane.setUnderline(true);
textFlowPane.setEffect(new DropShadow());
VBox.setMargin(textFlowPane, new Insets(10, 0, 0, 10));
flowPane = new FlowPane();
flowPane.setHgap(5);
flowPane.setVgap(5);
vbox.getChildren().addAll(textFlowPane, flowPane);
VBox.setMargin(vbox, new Insets(10));
return vbox;
}
private VBox createLowerVBox()
{
VBox vbox = new VBox(20);
Text textTilePane = new Text("I am a TilePane");
textTilePane.setFont(Font.font("Calibri", FontWeight.BOLD, 30));
textTilePane.setUnderline(true);
textTilePane.setEffect(new DropShadow());
VBox.setMargin(textTilePane, new Insets(10, 0, 0, 10));
tilePane = new TilePane();
tilePane.setHgap(5);
tilePane.setVgap(5);
vbox.getChildren().addAll(textTilePane, tilePane);
VBox.setMargin(vbox, new Insets(10));
return vbox;
}
private void fillPanesWithImages()
{
for (int i = 1; i <= 6; i++)
{
int imgSize = random.nextInt(128) + 1;
Button bt = new Button();
Image img = new Image(FlowPaneAndTilePaneExample.class
.getResourceAsStream("images/person" + i + ".png"),
imgSize > 50 ? imgSize : 50, 0, true, false);
ImageView view = new ImageView(img);
bt.setGraphic(view);
flowPane.getChildren().add(bt);
Button bt2 = new Button();
Image img2 = new Image(FlowPaneAndTilePaneExample.class
.getResourceAsStream("images/person" + i + ".png")
, imgSize > 50 ? imgSize : 50, 0, true, false);
ImageView view2 = new ImageView(img2);
bt2.setGraphic(view2);
tilePane.getChildren().add(bt2);
}
}
public static void main(String[] args)
{
Application.launch(args);
}
}</pre>
<br />
<p>This little application shows the major difference between a <code>FlowPane</code> and a <code>TilePane</code> by putting the same content in both panes. The both panes will be put in another <code>VBox</code> with an additional <code>Text</code> on top.</p>
<p><i> I am assuming that only the parts of the code with the FlowPane, the TilePane and the image loading are new to you by now. If you have problems understanding this JavaFX code please see my previous examples where I started with the basics of JavaFX 2.0.</i></p>
<p>Both panes provide amongst others a <code>setHgap</code> and a <code>setVgap</code> method to declare a spacing between each column and each row. To fill the buttons I chose to load some images.</p>
<p>In JavaFX 2.0 images can be shown with a <code>ImageView</code> which expects an <code>Image</code> object. (<b>Note:</b> This is an javafx.scene.image.Image, not an java.awt.image!)</p>
<p>Such an <code>ImageView</code> can then by applied to any <code>Labeled</code> object. <code>Labeled</code> is a subclass of <code>Control</code> and amongst others the abstract parent class of <code>Label</code> and <code>ButtonBase</code> (which is the base class for every kind of button), which allows you to set an image to every kind of label and button.</p>
<p>My six buttons are all 128x128 pixels. To show you the difference between a <code>FlowPane</code> and a <code>TilePane</code> I chose to resize these images. At the moment this is only possible directly in the constructor of the <code>Image</code> class as there are no methods to change the size of an <code>Image</code> object later on. One constructor takes an <code>InputStream</code>, two double values for the width and the height and two boolean values for preserving the aspect ratio of the image and for the ‘smooth’ property. If you want to resize your image and keep the aspect ratio you can just specify either the width or the height and keep the ratio by passing ‘true’ as the first boolean value. With the ‘smooth’ property you can choose between a clearer or a faster rendering of the image.</p>
<p>Depending on the random value generated for the size, your application should look something like this:</p>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzln3iPy7wsRALQlQ5iNyDbXPThhJpdTruqe5XD-JB4rPYtazebWqBsXBCIJFf-6ikEyE7cwCN8R5OG33y6PIobthKgh2CsBTsPAM5cmuSH_uJSkdMiU1np7rK6tp5IsRRyumqwdyuXhMx/s1600/flowPaneAndTilePaneExample.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="250" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzln3iPy7wsRALQlQ5iNyDbXPThhJpdTruqe5XD-JB4rPYtazebWqBsXBCIJFf-6ikEyE7cwCN8R5OG33y6PIobthKgh2CsBTsPAM5cmuSH_uJSkdMiU1np7rK6tp5IsRRyumqwdyuXhMx/s320/flowPaneAndTilePaneExample.png" /></a></div>
<br />
<p>You can see that the images are basically the same. The difference is, that the <code>FlowPane</code> lays out all images directly after another only separated by the gap specified with the <code>setHgap</code> method, whereas the <code>TilePane</code> put all images in tiles of the same size. </p>
<br />
<h1>FlowPane and TilePane – Example 2</h1>
<p>Here is another small example: As stated in the introduction of this post, a <code>TilePane</code> is also a very nice way for sizing and aligning buttons equally. To show the main difference between a <code>FlowPane</code> and a <code>TilePane</code> another time, the same elements will be put in both panes again.</p>
<p>Here is the code: </p>
<pre class="brush: java">
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Separator;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.RadialGradientBuilder;
import javafx.scene.paint.Stop;
import javafx.scene.text.Font;
import javafx.stage.Stage;
/**
*
* Created on: 24.03.2012
* @author Sebastian Damm
*/
public class FlowPaneAndTilePaneExample2 extends Application
{
private VBox root;
private FlowPane flowPane;
private TilePane tilePane;
@Override
public void start(Stage primaryStage) throws Exception
{
root = new VBox();
root.setAlignment(Pos.CENTER);
initFlowPane();
initTilePane();
createButtons();
root.getChildren().addAll(flowPane, new Separator(), tilePane);
Scene scene = new Scene(root, 400, 300);
RadialGradient background = RadialGradientBuilder.create()
.stops(new Stop(0d, Color.web("#fff"))
, new Stop(0.47, Color.web("#cbebff"))
, new Stop(1d, Color.web("#a1dbff"))
)
.cycleMethod(CycleMethod.NO_CYCLE)
.build();
scene.setFill(background);
primaryStage.setTitle("FlowPane and TilePane Example 2");
primaryStage.setScene(scene);
primaryStage.show();
}
private void initFlowPane()
{
flowPane = new FlowPane(Orientation.VERTICAL);
flowPane.setHgap(5);
flowPane.setVgap(5);
flowPane.setPrefHeight(200);
flowPane.setAlignment(Pos.CENTER);
VBox.setMargin(flowPane, new Insets(10));
}
private void initTilePane()
{
tilePane = new TilePane(Orientation.VERTICAL);
tilePane.setHgap(5);
tilePane.setVgap(5);
tilePane.setPrefHeight(200);
tilePane.setAlignment(Pos.CENTER);
VBox.setMargin(tilePane, new Insets(10));
}
private void createButtons()
{
Button bt = new Button("1");
bt.setMaxWidth(Double.MAX_VALUE);
bt.setMaxHeight(Double.MAX_VALUE);
Button bt2 = new Button("Button 1");
bt2.setMaxWidth(Double.MAX_VALUE);
bt2.setMaxHeight(Double.MAX_VALUE);
Button bt3 = new Button("Button");
bt3.setMaxWidth(Double.MAX_VALUE);
bt3.setMaxHeight(Double.MAX_VALUE);
bt3.setFont(Font.font("Cambria", 22));
Button bt4 = new Button("1");
bt4.setMaxWidth(Double.MAX_VALUE);
bt4.setMaxHeight(Double.MAX_VALUE);
Button bt5 = new Button("Button 1");
bt5.setMaxWidth(Double.MAX_VALUE);
bt5.setMaxHeight(Double.MAX_VALUE);
Button bt6 = new Button("Button");
bt6.setMaxWidth(Double.MAX_VALUE);
bt6.setMaxHeight(Double.MAX_VALUE);
bt6.setFont(Font.font("Helvetica", 22));
flowPane.getChildren().addAll(bt, bt2, bt3);
tilePane.getChildren().addAll(bt4, bt5, bt6);
}
public static void main(String[] args)
{
Application.launch(args);
}
}</pre>
<p> Again the root node is a <code>VBox</code> with a <code>FlowPane</code> in the upper region and a <code>TilePane</code> in the lower region. There are some parts in the code that may be new to you. First of all take a look at the lines 44-51. Here I create a radial gradient for the background of the scene with help from one of the numerous builder classes in JavaFX 2.0. I will cover gradients and also the builder pattern in own posts later on, so I won´t explain much here. For now you just need to know, that these lines create a radial background which is then applied to the scene via scene´s <code>setFill</code> method. (Like in previous examples we could have specified the background fill directly in the constructor of the scene, because it expects a <code>Paint</code> object, which includes not only normal colors, but also every kind of gradient).</p>
<p>In contrast to the first example, this time we use vertical panes which are populated with buttons. Because I want to allow the buttons to grow to whatever space is provided by their parent, I set the max height as well as the max width of every button to the constant <code>Double.MAX_VALUE</code>. (Take a look at my previous example <a href="http://dammsebastian.blogspot.de/2012/03/testest.html">Sizing Buttons equally inside a VBox or HBox</a> if you haven´t already)</p>
<p>Your application should look like this:</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDwZgnKYbmAHxvVDBBmW6vz28Vj8VfJGnOZAwpYhxKQPIVuXfHoe_zwMdhpONAC4QltJ4_G-k7NvSTS0vUS2CzCWVF6BSm5ZNAC4xK3Dddwae6YGt9hr-RCI5XKKncX-MHfZa1whR-2Kru/s1600/flowPaneAndTilePaneExample+2+-+pic1.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="258" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDwZgnKYbmAHxvVDBBmW6vz28Vj8VfJGnOZAwpYhxKQPIVuXfHoe_zwMdhpONAC4QltJ4_G-k7NvSTS0vUS2CzCWVF6BSm5ZNAC4xK3Dddwae6YGt9hr-RCI5XKKncX-MHfZa1whR-2Kru/s320/flowPaneAndTilePaneExample+2+-+pic1.png" /></a></div>
<p>As you can see in both panes the buttons grow to the width of their parent, but only in the <code>TilePane</code> the buttons also grow vertically because each tile in a <code>TilePane</code> is equally sized. This example may not seem very important but in the applications I developed in JavaFX 2.0 until now, I always wanted to size and align buttons equally because it is a subtle aspect that makes your application look more clean and polished.</p>
<p>If you resize you window, it should look like this:</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhseR_OsNIGF7zdd0YkYV-syoBVbeD8sv25Elp3qBp4C2FMtbEO-ceTcOh9-Li4EarOIRcUkPcTrAxr32eBbhsShv2KU2dkctDvTZv5sbEQZxN3B4Fk633VTym_bqdnxnKYyIQaKZnBqEk9/s1600/flowPaneAndTilePaneExample+2+-+pic2.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="101" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhseR_OsNIGF7zdd0YkYV-syoBVbeD8sv25Elp3qBp4C2FMtbEO-ceTcOh9-Li4EarOIRcUkPcTrAxr32eBbhsShv2KU2dkctDvTZv5sbEQZxN3B4Fk633VTym_bqdnxnKYyIQaKZnBqEk9/s320/flowPaneAndTilePaneExample+2+-+pic2.png" /></a></div>
<p>Take a note, that once the buttons are not layed out vertically anymore in the <code>FlowPane</code> the buttons only occupy the space they need (based on their content) whereas in the <code>TilePane</code> all buttons are still of equal size.</p>Anonymoushttp://www.blogger.com/profile/06758323276772641565noreply@blogger.com5tag:blogger.com,1999:blog-8609681790114022775.post-62202256222153004522012-03-21T17:40:00.000+01:002012-09-22T19:23:43.819+02:00JavaFX 2.0 Layout Panes - Sizing Buttons equally inside a VBox or HBox<link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" rel="stylesheet" type="text/css"></link>
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" rel="stylesheet" type="text/css"></link>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript">
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js" type="text/javascript">
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js" type="text/javascript">
</script>
<script language="javascript">
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script>
<p>When you have multiple buttons in a <code>VBox</code> or a <code>HBox</code> you often want to size and align them equally. The default preferred width of a button is computed based on its content (which includes the text as well as possible graphics) and the default preferred size of a <code>VBox</code> and a <code>HBox</code> is based on the biggest of their children.</p>
<p>If you want your buttons to grow with their parent you either have to raise their max size manually or to set it to the constant <code>Double.MAX_VALUE</code> which forces controls to grow as big as permitted by their parent.</p>
<a name='more'></a><br />
<pre class="brush: java">
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
*
* Created on: 20.03.2012
* @author Sebastian Damm
*/
public class SizingButtonsEqually extends Application
{
@Override
public void start(Stage primaryStage) throws Exception
{
VBox root = new VBox(30);
root.setPadding(new Insets(10));
root.setAlignment(Pos.CENTER);
HBox hbox = new HBox(30);
hbox.setAlignment(Pos.CENTER);
VBox vbox = new VBox(10);
vbox.setMaxWidth(200);
vbox.setStyle("-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: black");
VBox vbox2 = new VBox(10);
vbox2.setMaxWidth(200);
vbox2.setStyle("-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: black");
Button bt1 = new Button("1");
Button bt2 = new Button("I am Button!"); // got it? ;)
Button bt3 = new Button("I am a veeeeeeeery long button");
Button bt4 = new Button("1");
bt4.setMaxWidth(Double.MAX_VALUE);
Button bt5 = new Button("I am Button!");
bt5.setMaxWidth(Double.MAX_VALUE);
Button bt6 = new Button("I am a veeeeeeeery long button");
bt6.setMaxWidth(Double.MAX_VALUE);
vbox.getChildren().addAll(bt1, bt2, bt3);
vbox2.getChildren().addAll(bt4, bt5, bt6);
hbox.getChildren().addAll(vbox, vbox2);
HBox hbox2 = new HBox(20);
hbox2.setStyle("-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: black");
hbox2.setAlignment(Pos.CENTER);
hbox2.setPrefHeight(50);
VBox.setVgrow(hbox2, Priority.ALWAYS);
for (int i = 0; i < 10; i++)
{
Button bt = new Button(String.valueOf(i));
bt.setMaxHeight(Double.MAX_VALUE);
hbox2.getChildren().add(bt);
}
root.getChildren().addAll(hbox, hbox2);
Scene scene = new Scene(root, 500, 250);
primaryStage.setTitle("Sizing Buttons equally inside a VBox or HBox");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{
Application.launch(args);
}
}</pre>
This code should´nt include anything that you haven´t seen already and your application should look like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIRwv8U-BiCL6SiReplpgHLe2_yxL10_Hwj8ZMInQta7Z7wDuVh72uRzKaC6QzXQAlzojOu3rHwQ7xsvLUyDpgjBEeH95k4v3o7g9H8D-nSjC3m4ZLwMiuHpanuYm3v3eN_csLMgOXfaUy/s1600/sizing+buttons+equally.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="178" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIRwv8U-BiCL6SiReplpgHLe2_yxL10_Hwj8ZMInQta7Z7wDuVh72uRzKaC6QzXQAlzojOu3rHwQ7xsvLUyDpgjBEeH95k4v3o7g9H8D-nSjC3m4ZLwMiuHpanuYm3v3eN_csLMgOXfaUy/s320/sizing+buttons+equally.png" width="320" /></a></div>
<br />
I chose again to give the Boxes a border to demonstrate their size and how they grow. If you resize the window you can see that the lower <code>HBox</code> grows vertically with the window and that all children buttons inside the <code>HBox</code> grow equally and use all the available space (because they could grow to <code>Double.MAX_VALUE</code> theoretically).
<p>Another way to size and align your button equally is to use a <code>TilePane</code>. Please see the 2nd example in my post <a href="http://dammsebastian.blogspot.de/2012/03/javafx-20-layout-panes-flowpane-and.html#more">FlowPane and TilePane</a> for a example on this.</p>Anonymoushttp://www.blogger.com/profile/06758323276772641565noreply@blogger.com0tag:blogger.com,1999:blog-8609681790114022775.post-3193759507008903472012-03-20T16:18:00.000+01:002012-09-22T19:24:04.324+02:00JavaFX 2.0 Layout Panes - HBox and VBox<link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" rel="stylesheet" type="text/css"></link>
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" rel="stylesheet" type="text/css"></link>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript">
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js" type="text/javascript">
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js" type="text/javascript">
</script>
<script language="javascript">
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script>
<p>If you want an overview on all different layout panes in JavaFX 2.0 or if you want to know yome basic facts about them, please see my previous post <a href="http://dammsebastian.blogspot.de/2012/03/layout-panes-in-javafx-20.html">Layout Panes in JavaFX 2.0</a>.</p>
<p>The layout panes <code>HBox</code> and <code>VBox</code> are definitely the most basic layout containers in JavaFX 2.0. As you can already tell by their name, their purpose is to layout all their children in one horizontal row (<code>HBox</code>) or in one vertical column (<code>VBox</code>). Because they´re very easy to use and very useful regarding minor layout issues, you´ll probably use them a lot. I´ll give two examples on how you can use them. As in the other examples, first of all the code and afterwards the explanations.
<br />
<h1>HBox and VBox – Example 1</h1>
<pre class="brush: java">
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
*
* Created on: 20.03.2012
* @author Sebastian Damm
*/
public class HBoxandVBoxExample extends Application
{
@Override
public void start(Stage primaryStage) throws Exception
{
HBox hbox = new HBox(50);
hbox.setAlignment(Pos.CENTER); // default TOP_LEFT
VBox vbox1 = new VBox();
vbox1.setAlignment(Pos.BOTTOM_CENTER);
vbox1.setStyle("-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: black");
VBox vbox2 = new VBox(10);
vbox2.setAlignment(Pos.CENTER);
vbox2.setStyle("-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: black");
VBox vbox3 = new VBox(20);
vbox3.setAlignment(Pos.TOP_CENTER);
vbox3.setStyle("-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: black");
for (int i = 0; i < 5; i++)
{
Button bt = new Button("Button " + (i+1));
Button bt2 = new Button("Button " + (i+1)); // unfortunately there´s no "clone" or "copy" method
Button bt3 = new Button("Button " + (i+1));
vbox1.getChildren().add(bt);
vbox2.getChildren().add(bt2);
vbox3.getChildren().add(bt3);
}
hbox.getChildren().addAll(vbox1, vbox2, vbox3);
Scene scene = new Scene(hbox, 350, 250); // the hbox is the root node
primaryStage.setTitle("HBox and VBox Example");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{
Application.launch(args);
}
}</pre>
<br />
<p>Basically we create three different VBoxes and put them into one HBox. In both classes you can define a spacing value either directly in the constructor or via the <code>setSpacing</code> method.
This value will be used as the gap between the individual children in the pane.
The line <code>HBox hbox = new HBox(50);</code> therefore creates a HBox to hold three VBoxes with a gap of 50 pixel between each of them.</p>
<p>We use the <code>setAlignment</code> method to specify, how the individual VBoxes should arrange and layout all their childen.</p>
<p>With <code>setStyle</code> you can apply custom CSS styles to any <code>Node</code>. I don´t want to go into much detail yet, because I´ll cover CSS styles in JavaFX 2.0 in one of my next posts, but if you´re already familiar with CSS you´ll probably already have noticed that the JavaFX 2.0 team fortunately decided to follow the CSS standards defined by W3C (<a href="http://www.w3.org/">http://www.w3.org</a>) very closely.
If you´re not familiar with CSS you just need to know that theses lines of CSS create a 1px wide black border around the component. I use them here to show you the size of the individual VBoxes.</p>
<p>The next few lines should be pretty ordinary for you by now: We create five buttons for each VBox, put the different VBoxes into our HBox, declare a <code>Scene</code> object (with the <code>HBox</code> as root) and show our application. </p>
<a name='more'></a><br />
Your application should look like this now:
<br />
<div class="separator" style="clear: both; text-align: center;"> <br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheqkALYYvgonNepdf0fzkjQF_jATo7A3pNINTONDf3ypt-6lGPLDbc77PakTguCud3qTJDawAQfW3Rol-53efr5M1TXVJXBHEikmwZz4Gxidm8StZ3uf6UTVDB4LxtUiRjh8KoF2z9ZN4n/s1600/hboxAndVboxExample1_pic1.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="250" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheqkALYYvgonNepdf0fzkjQF_jATo7A3pNINTONDf3ypt-6lGPLDbc77PakTguCud3qTJDawAQfW3Rol-53efr5M1TXVJXBHEikmwZz4Gxidm8StZ3uf6UTVDB4LxtUiRjh8KoF2z9ZN4n/s320/hboxAndVboxExample1_pic1.png" /></a></div>
<br />
<p>You can see that each <code>VBox</code> lays out their children buttons with the defined spacing value and that the <code>HBox</code> lays out the three VBoxes with a gap of 50 pixels.
Because we set a different alignment for each <code>VBox</code> you can see that that they arrange the buttons inside their bounds in a specific way.
<br /><b>Note:</b> We also specified a alignment for the <code>HBox</code>, otherwise the three VBoxes would not have been layed out in the center! </p>
<br />
If you resize the window of your application it should look like this:
<br />
<div class="separator" style="clear: both; text-align: center;"><br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRuoN-euRT1Mr1xbWNWPIfHsJpipdpx7A58tyVEweEgEmtAphSJJn1336TfUxvFzL1iZ23-70HMepr8e2jqYNFLM-ZK_MO9Sp1dlFDSAcPUi0EBuXfzsl2W5xDQiMp-dNKdjGyByp7sIao/s1600/hboxAndVboxExample1_pic2.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="229" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRuoN-euRT1Mr1xbWNWPIfHsJpipdpx7A58tyVEweEgEmtAphSJJn1336TfUxvFzL1iZ23-70HMepr8e2jqYNFLM-ZK_MO9Sp1dlFDSAcPUi0EBuXfzsl2W5xDQiMp-dNKdjGyByp7sIao/s320/hboxAndVboxExample1_pic2.png" /></a></div>
<br />
<p>You can see that the VBoxes grow and fill the space provided by their parent and that they still arrange their children according to their set alignment.</p>
<br />
<h1>HBox and VBox – Example 2</h1>
<p>The next example will show how to use the static <code>setMargin</code> and <code>setHgrow</code> (respectively <code>setVgrow</code>) methods:</p>
<br />
<pre class="brush: java">
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
/**
*
* Created on: 20.03.2012
* @author Sebastian Damm
*/
public class HBoxandVBoxExample2 extends Application
{
@Override
public void start(Stage primaryStage) throws Exception
{
StackPane root = new StackPane();
HBox hbox = new HBox(30); // create a HBox to hold 2 vboxes
// create a vbox with a textarea that grows vertically
VBox vbox = new VBox(10);
Label lbName = new Label("I´m a label!");
TextField textField = new TextField();
TextArea textArea = new TextArea();
textArea.setPrefWidth(100);
VBox.setVgrow(textArea, Priority.ALWAYS);
vbox.getChildren().addAll(lbName, textField, textArea);
// create a vbox that grows horizontally inside the hbox
VBox vbox2 = new VBox(10);
Label lbName2 = new Label("I´m also a label!");
TextField tf2 = new TextField();
tf2.setPromptText("type here");
TextArea textArea2 = new TextArea();
textArea2.setPrefWidth(100);
vbox2.getChildren().addAll(lbName2, tf2, textArea2);
HBox.setHgrow(vbox2, Priority.ALWAYS);
// the next two lines behave equally - try to comment the first line out and use the 2nd line
hbox.setPadding(new Insets(20));
// StackPane.setMargin(hbox, new Insets(20));
hbox.getChildren().addAll(vbox, vbox2);
root.getChildren().add(hbox);
Scene scene = new Scene(root, 500, 300); // the stack pane is the root node
primaryStage.setTitle("HBox and VBox Example 2");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{
Application.launch(args);
}
}</pre>
<br />
<p>In this example we create two VBoxes that are children of a HBox. Inside the VBoxes there are one label, one textfield and one textarea.</p>
<p>The first remarkable line is <code>VBox.setVgrow(textArea, Priority.ALWAYS)</code>. With this line we define, that the <code>TextArea</code> object should always grow vertically if it is contained by a <code>VBox</code> (otherwise there won´t be any effects). Next, put a focus on <code>HBox.setHgrow(vbox2, Priority.ALWAYS)</code>. Here we tell the second <code>VBox</code> to grow horizontally inside the <code>HBox</code>.</p>
<p>Finally with <code>hbox.setPadding(new Insets(20));</code> or <code>StackPane.setMargin(hbox, new Insets(20))</code> we give the whole <code>HBox</code> some padding. The two lines behave equally here because on the one side we specify a padding for the pane itself that should be used by the pane inside its bounds to layout its children and on the other side we tell the parent to lay out the pane with the given margin around it.
<br/ ><br/ ><b>Note:</b> Margin is the outer distance/gap, padding the inner one.<br/><br /> Here is a picture showing you the 'CSS Box Model' that demonstrates the relation between the content, the padding, the border, and the margin of an element.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdc3RlxeK9qYZE9Ygob7kSdCmW588_5O5byYdqRtxFQBJN3Ea-ov7DVTLVqayKfpI18jmamuxPZv5ASPfw8nO7GllDu3QmCKUk0RfJLo-78lPxT7oZEJNltfJZNuZFs7z98gP7muBzdcJZ/s1600/box-model.gif" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="173" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdc3RlxeK9qYZE9Ygob7kSdCmW588_5O5byYdqRtxFQBJN3Ea-ov7DVTLVqayKfpI18jmamuxPZv5ASPfw8nO7GllDu3QmCKUk0RfJLo-78lPxT7oZEJNltfJZNuZFs7z98gP7muBzdcJZ/s320/box-model.gif" /></a><br/>Source: <a href="http://www.w3schools.com/css/css_boxmodel.asp"></a>w3Schools.com</div>
<p>Because the <code>setPadding</code> method is defined in the <code>Region</code> class, every layout pane can use this method. The <code>Insets</code> class is used a lot for those purposes and provides two different constructors: One that takes one double value and defines the same padding for each side and one constructor that takes four double values and defines the padding clockwise from the top to the left side.
<br/><b>Hint:</b> If you apply a border to the <code>HBox</code> and switch between the two lines for setting padding/margin, you will see the difference more clearly.</p>
<p><br />Your application should look like this:</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizkptkZ9SD0H9lnzbL8p4NfoIL9tEnA2bIJPjFJ721N34-bMr0krJn4ejJYd_cwd2aDb5UgqQ1KvZwsR6Lb43AwC0aPibReDebjF_bX_BP6ypvoXk24si3f7WGEFOjcH9oBopKCx_fYkGk/s1600/hboxAndVboxExample2_pic1.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="208" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizkptkZ9SD0H9lnzbL8p4NfoIL9tEnA2bIJPjFJ721N34-bMr0krJn4ejJYd_cwd2aDb5UgqQ1KvZwsR6Lb43AwC0aPibReDebjF_bX_BP6ypvoXk24si3f7WGEFOjcH9oBopKCx_fYkGk/s320/hboxAndVboxExample2_pic1.png" /></a></div>
<p>Note the 10px padding around the <code>HBox</code>. If you now resize you window it should look similar to this: </p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFUS1M4abgIy-HH3nL4WVW0tuKYco9j0K5H1sbJ8Txg_BTd2AnMVR76BT-rQGkMu7cXldk0pjrvDgFVvRLXnw38WSGWklDqD0S58WDL2JdRLccc-9mlfNn18zEXbps8b_7eWnBqOznKUsK/s1600/hboxAndVboxExample2_pic2.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="204" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFUS1M4abgIy-HH3nL4WVW0tuKYco9j0K5H1sbJ8Txg_BTd2AnMVR76BT-rQGkMu7cXldk0pjrvDgFVvRLXnw38WSGWklDqD0S58WDL2JdRLccc-9mlfNn18zEXbps8b_7eWnBqOznKUsK/s320/hboxAndVboxExample2_pic2.png" /></a></div>
<p>As you can see the <code>TextArea</code> in the left <code>VBox</code> grows vertically and the whole right <code>VBox</code> grows horizontally inside the <code>HBox</code>.</p>Anonymoushttp://www.blogger.com/profile/06758323276772641565noreply@blogger.com5tag:blogger.com,1999:blog-8609681790114022775.post-25686061184953532722012-03-19T13:01:00.000+01:002012-03-28T15:39:06.436+02:00Layout Panes in JavaFX 2.0<p>Creating a graphical user interface that looks nice and that provides a good usability is a very common task in software development. Fortunately JavaFX 2.0 offers great support in that area.
</p>
<h1>
What is a layout manager and why do we need them?</h1>
<p>Layout managers are regions or areas that follow individual rules to (re)arrange and to (re)size all their children in relation to their own size. Generally, it is also possible to specify a fixed position of your components in an application window. But how should the window know what to do when you resize your application window? Should it leave the new available space blank? Should some components “vanish” if you make the window smaller? Should it resize some components? If yes, which one and how?</p>
<p>These questions show, why layout managers are necessary in software development.</p>
<h1>Facts about layout managers in JavaFX 2.0</h1>
<ul>
<li>
In JavaFX 2.0 layout managers are called “panes”
</li>
<li>
Every layout pane extends the <code>Region</code> class
</li>
<li>
To create your own layout pane, it is highly recommended to extend <code>Region</code> yourself
</li>
<li>
Types of layout panes in JavaFX 2.0
<ul>
<li>
HBox (lays out its children in a horizontal row)
</li>
<li>
VBox (lays out its children in a single vertical column)
</li>
<li>
Border Pane (lays out its children in five different regions: Top, Right, Bottom, Left and Center)
</li>
<a name='more'></a>
<li>
Anchor Pane (similar to a Border Pane, differences will be covered in detail)
</li>
<li>
Flow Pane (lays out its children censecutively one after another)
</li>
<li>
Tile Pane (similar to a Flow Pane, differences will be covered in detail)
</li>
<li>
Stack Pane (lays out its children by putting them on top of each other on one single stack)
</li>
<li>
Grid Pane (lays out its children in a grid of columns and rows)
</li>
</ul>
</li>
<li>
There are some “false friends” in JavaFX 2.0 regarding layout panes:
<ul>
<li>
Tab Pane, Titled Pane and Split Pane. These extend <code>Control</code> and not <code>Region</code>. <b>These are no layout managers/panes</b>, as they do not (re)arrange or (re)size their children.
</li>
</ul>
</li>
<li>
Every layout pane provides a <code>setPadding</code> method defined in the <code>Region</code> class.
With this method you can tell a pane to layout its children with the specified padding around them.
</li>
<li>
Almost every layout pane (<code>AnchorPane</code> being the only exception) provides a <code>setAlignment</code> method.
This method specifies how the layout pane aligns and arranges all children inside the layout pane.
</li>
<li>
Almost every layout pane (<code>AnchorPane</code> again being the only exception) provides a <b>static</b> <code>setMargin</code> method.
With this method you can give one or more certain nodes inside the pane a specific margin that the parent will keep around it when layouting its children.
</li>
</ul>
<ul>
</ul>
<br />
In the next few posts I´ll give 1 or 2 examples for every layout pane in JavaFX 2.0.<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/06758323276772641565noreply@blogger.com0tag:blogger.com,1999:blog-8609681790114022775.post-92160626819258713332012-03-18T14:51:00.000+01:002012-06-25T13:00:38.097+02:00Hello World in JavaFX 2.0<link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" rel="stylesheet" type="text/css"></link>
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" rel="stylesheet" type="text/css"></link>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript">
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js" type="text/javascript">
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js" type="text/javascript">
</script>
<script language="javascript">
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">Before talking about the example itself, I want to show you how to create a JavaFX application in NetBeans.
(If you haven´t installed JavaFX and NetBeans yet, please see my previous post <a href="http://dammsebastian.blogspot.de/2012/03/installing-javafx-20-and-netbeans-771.html">Installing JavaFX 2.0 and NetBeans 7.7.1</a>)
Click on “New Project” in the “File” menu to open the project wizard. Then choose “JavaFX->JavaFX Application” and press “Next”.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV3ePUF47rlTOia-8Gjvs-9jaQ2zQwA9_UnfSlDLc_DDSTK_Bjfi1fktTuuZMgYwSD7vM_EavrsHjyMKwP-YdFrUXdyty7eSrFAV6_tzf1BmotAlZW16hyMQxGRm6NtpirWrU_QdrsTPQ0/s1600/creating_your_first_javafxapp_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: Arial, Helvetica, sans-serif;"><img border="0" height="219" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV3ePUF47rlTOia-8Gjvs-9jaQ2zQwA9_UnfSlDLc_DDSTK_Bjfi1fktTuuZMgYwSD7vM_EavrsHjyMKwP-YdFrUXdyty7eSrFAV6_tzf1BmotAlZW16hyMQxGRm6NtpirWrU_QdrsTPQ0/s320/creating_your_first_javafxapp_1.png" width="320" /></span></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">In the next dialog you can specify the name of your application and a destination folder, where it should be stored. If you have installed JavaFX correctly the “JavaFX Platform” should be specified already. Otherwise you can add the platform yourself by clicking on “Manage Platforms->Add Platform” and specifying the paths to your JavaFX installation.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2OxObGRd0hIBH2MQkuvSlaYNvUenjzvyGxYXaGNzPE_ImD9eak1i-N38pcRr8RbeANEPdU_l8GLzUIcIs9LOJsmS2vVDziqxbPE70FvcnaRUv_P1KjkTDB3oi6p7CeccHelQ-IGpaiosm/s1600/creating_your_first_javafxapp_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: Arial, Helvetica, sans-serif;"><img border="0" height="214" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2OxObGRd0hIBH2MQkuvSlaYNvUenjzvyGxYXaGNzPE_ImD9eak1i-N38pcRr8RbeANEPdU_l8GLzUIcIs9LOJsmS2vVDziqxbPE70FvcnaRUv_P1KjkTDB3oi6p7CeccHelQ-IGpaiosm/s320/creating_your_first_javafxapp_2.png" width="320" /></span></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><b>Note:</b> By default the “Create Application Class” checkbox is checked. Please uncheck it because we´ll create our own application class.
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Click on “finish” to create your first JavaFX application.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<br />
<h1>Hello World in JavaFX 2.0 – Example 1</h1>
<p>
Probably every single software developer knows the famous „HelloWorld“ example as it is often used to show the syntax of a (unknown) programming language and to give a first clue, of what the language looks like.
I don´t want to break this tradition, so here are 2 different versions of a HelloWorld program in JavaFX 2.0. I´ll show the complete code first and then explain the individual parts.
</p>
<pre class="brush: java">
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
*
* Created on: 17.03.2012
* @author Sebastian Damm
*/
public class HelloJavaFX extends Application
{
@Override
public void start(Stage stage) throws Exception
{
Button bt = new Button("Print HelloWorld");
bt.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent arg0)
{
System.out.println("HelloWorld! :)");
}
});
StackPane root = new StackPane();
Scene scene = new Scene(root, 300, 150);
root.getChildren().add(bt);
stage.setTitle("HelloWorld in JavaFX 2.0");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args)
{
Application.launch(args);
}
}</pre>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">The first thing worth mentioning is that you have to extend from the <code> Application</code> class in order to create a working JavaFX application. This class provides several live-cycle methods and is the starting point for your application. It is an abstract class (which means, that you cannot instantiate it) with a single abstract method <code>start</code>, that you have to override. You are provided a <code>stage</code> object by the JavaFX runtime, which you can use to display your UI.
</span><br /><a name='more'></a><br />
<span style="font-family: Arial, Helvetica, sans-serif;">To start your application you have to call the static method <code>launch</code> as seen in the <code>main</code> method in this example. After launching your application, it will call the <code>start</code> method. Here is the JavaDoc of the <code>Application</code> class, which shows the individual steps when starting a JavaFX application.</span><br />
<blockquote>
<span style="font-family: Arial, Helvetica, sans-serif;">The entry point for JavaFX applications is the Application class. The JavaFX runtime does the following, in order, whenever an application is launched:
Constructs an instance of the specified Application class
</span><br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Calls the init() method </span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Calls the start(javafx.stage.Stage) method </span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Waits for the application to finish, which happens either when the last window has been closed, or the application calls Platform.exit()</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Calls the stop() method </span></li>
</ul>
</blockquote>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Let´s start with the real source code inside the <code>start</code> method.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">First of all we create a simple <code>Button</code> and specify an action to be triggered when the button is clicked via the <code>setOnAction</code> method (compare JButton´s <code>addActionListener</code>).</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Next we create a <code>StackPane</code> object, which is one of the layout panes in JavaFX (One of the next blog posts will cover all different layout panes in JavaFX). I use a <code>StackPane</code> here, because it automatically takes all the available space provided by its surrounding parent and because it automatically centers its children inside.</span><br /><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><b>Note: </b> The foundation of a JavaFX application is the <code>Scene graph</code>.
Every single <code>Node</code> (which includes simple controls, groups and layout panes) is part of a hierarchical tree of nodes, which is called the <code>Scene graph</code>.
The <code>Scene graph</code> and therefore your whole JavaFX application has always <b>one single</b> root node!</span><br /><br />
<span style="font-family: Arial, Helvetica, sans-serif;">As mentioned above, the <code>start</code> method has a <code>Stage</code> object parameter, which is provided by the JavaFX runtime. This <code>Stage</code> object is a kind of window. You have to give it a <code>Scene</code> object as its viewable content. You can create a <code>Scene </code> object by passing the root node of your application. Optional parameters are the width and the height of your scene as well as a <code>Paint</code> object, which includes simple colors and also complex color gradients.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">With <code>root.getChildren().add(bt);</code> you add the button to your root node, which is a stackpane. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">After that we set a title to the <code>stage</code> and apply the created <code>scene</code> object. Finally with the <code>show</code> method we tell the <code>stage</code> to show. (compare Swing´s <code>setVisible</code></span><br />
<code><span style="font-family: Arial, Helvetica, sans-serif;">
</span></code><br />
<code><span style="font-family: Arial, Helvetica, sans-serif;">Now your application should look like this:</span></code><br />
<code><span style="font-family: Arial, Helvetica, sans-serif;">
</span></code><br />
<div class="separator" style="clear: both; text-align: center;">
<code><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-unDleFkO7gJ8F-_BG-2e2iSDCzR9ITyGpkAJSNQkM5FP08xKSdtxkVw2t4TP0YJKKgkD2OpnSYKNQzNYlmk1NdfUZo3j5LDp-f44B2fGHUYFmSga-76Pk4uAtjqBpAaSuK0d3g8_YIQL/s1600/helloworld_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: Arial, Helvetica, sans-serif;"><img border="0" height="188" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-unDleFkO7gJ8F-_BG-2e2iSDCzR9ITyGpkAJSNQkM5FP08xKSdtxkVw2t4TP0YJKKgkD2OpnSYKNQzNYlmk1NdfUZo3j5LDp-f44B2fGHUYFmSga-76Pk4uAtjqBpAaSuK0d3g8_YIQL/s320/helloworld_1.png" width="316" /></span></a></code></div>
<code>
<span style="font-family: Arial, Helvetica, sans-serif;">
And it should print "HelloWorld" to the command line if you click the button.
Nothing spectacular yet, but it´s your first working JavaFX application, so congratulations! :)
<br /> <br /> <br />
</span></code><br />
<h1>
<span style="font-family: Arial, Helvetica, sans-serif;">Hello World in JavaFX 2.0 – Example 2</span></code></h1>
<code>
<span style="font-family: Arial, Helvetica, sans-serif;">Additionally a slightly changed example, which will show the text in the GUI.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">
The code:
<br />
</span></code><br />
<pre class="brush: java">
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.effect.DropShadow;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
/**
*
* Created on: 17.03.2012
* @author Sebastian Damm
*/
public class HelloJavaFX2 extends Application
{
@Override
public void start(Stage stage) throws Exception
{
final Group root = new Group();
Scene scene = new Scene(root, 500, 200, Color.DODGERBLUE);
final Text text = new Text(140, 120, "Hello JavaFX 2.0!");
text.setFont(Font.font("Calibri", 35));
text.setFill(Color.WHITE);
text.setEffect(new DropShadow());
Button bt = new Button("Show HelloWorld");
bt.setLayoutX(180);
bt.setLayoutY(50);
bt.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent arg0)
{
root.getChildren().add(text);
}
});
root.getChildren().add(bt);
stage.setTitle("HelloWorld in JavaFX 2.0");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args)
{
Application.launch(args);
}
}</pre>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">Instead of using a layout pane we use a <code>Group</code> object here. <code>Group</code> is a subclass of <code>Parent</code> (which is a subclass of <code>Node</code>) and takes one or more children. A <code>Group</code> isn´t directly resizable and you can add transformations or effects to a <code>Group</code> which will then affect all children of the <code>Group</code>.
(Note that we now also provided a <code>Paint</code> for the <code>Scene</code>.)</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Next we create a <code>Text</code> object. Because we have no layout pane, we specify the x and y coordinates directly. We specify a custom font, change the color to white and add a <code>DropShadow</code>.
<br />
The <code>Button</code> also gets coordinates and instead of printing “HelloWorld” to the command line when we click the button, we add the created <code>Text</code> object to our root element (and therefore to the <code>Scene Graph</code>). </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">After clicking the button, your application shoul look like this.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br />
</span><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNgBBArpxmuUxSTreghyphenhyphen4ljbj98eev8VJf8j3T6w1UbGiBFSa8zjiv96iSov4L3elHqm1YXNVUzYVCBT8A9FDEiWp6HSgdVKGwxWIFv4boFwFKDtq17vO1a2neea_OlLKvWTIb9Cp9W-eH/s1600/helloworld_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: Arial, Helvetica, sans-serif;"><img border="0" height="147" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNgBBArpxmuUxSTreghyphenhyphen4ljbj98eev8VJf8j3T6w1UbGiBFSa8zjiv96iSov4L3elHqm1YXNVUzYVCBT8A9FDEiWp6HSgdVKGwxWIFv4boFwFKDtq17vO1a2neea_OlLKvWTIb9Cp9W-eH/s320/helloworld_2.png" width="320" /></span></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /> <br />
</span><span style="font-family: Arial, Helvetica, sans-serif;"><b>Summary:</b>
</span><br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">A JavaFX <code>Stage</code> object is a kind of window and behaves similar to a <code>JFrame</code> or <code>JDialog</code> in Swing.
</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">
A JavaFX <code>Scene</code> object is the viewable content of a <code>Stage</code> and has a single <code>Parent</code> root node.
</span></li>
<li>
<span style="font-family: Arial, Helvetica, sans-serif;"><code>Node</code> is one of the most important classes in JavaFX. Every control or layout pane is a kind of node.
</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">
The <code>Scene Graph</code> is a hierarchical tree of nodes. It has one single root node and is the foundation of your application. It has to be passed to a <code>Scene</code> object
</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">
In order to create and start a JavaFX application you have to complete the following steps:
</span><ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">
Extend the <code>Application </code> class
</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">
Override the abstract <code>start</code> method
</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">
Create a root node and add some elements to it
</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">
Create a <code>Scene </code> object and pass the root node to it
</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">
Apply the <code>Scene</code> to the <code>Stage</code> via <code>setScene</code>
</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">
Tell the <code>Stage</code> to show with the <code>show</code> method
</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">
Call <code>Application.launch</code> in your <code>main</code> method
</span></li>
</ul>
</li>
</ul>
</code>Anonymoushttp://www.blogger.com/profile/06758323276772641565noreply@blogger.com4tag:blogger.com,1999:blog-8609681790114022775.post-42249011288501266862012-03-17T17:50:00.000+01:002012-03-28T15:20:23.226+02:00Starting a series of JavaFX 2.0 beginner tutorials<div class="MsoNormal" style="text-align: left;">
</div>
<div class="MsoNormal">
<span lang="EN-US">As
mentioned in my 2 introduction posts, I´ll start a series of beginner tutorials
for JavaFX 2.0.<o:p></o:p></span></div>
<div class="MsoNormal">
<span lang="EN-US">I will
start with the obligatory “HelloWorld” example and try to cover as many as
possible beginner topics in the next few weeks. Feel free to tell me in the
comments, what you want to see.<o:p></o:p></span></div>
<div class="MsoNormal">
<span lang="EN-US"><br /></span></div>
<div class="MsoNormal">
<h1>Who are the tutorials targeted at?</h1></div>
<div class="MsoNormal">
</div>
<ul>
<li>People with average to good Java knowledge</li>
<li>People that what to learn JavaFX 2.0 but have little to no knowledge yet</li>
</ul>
<div>
<div class="MsoNormal">
<span lang="EN-US"><br /></span></div>
<div class="MsoNormal">
<span lang="EN-US">I won´t
cover any Java basics, but we will start at the very beginning of JavaFX 2.0<o:p></o:p></span></div>
</div>
<br />
<br />Anonymoushttp://www.blogger.com/profile/06758323276772641565noreply@blogger.com1tag:blogger.com,1999:blog-8609681790114022775.post-41606590032203148572012-03-16T13:29:00.000+01:002012-03-28T15:20:43.144+02:00Installing JavaFX 2.0 and NetBeans 7.7.1<br />
<div class="MsoNormal">
<span lang="EN-US">My first blog
post will cover the most essential part => Installing JavaFX 2.0 and setting
up your development environment.<o:p></o:p></span></div>
<div class="MsoNormal">
<span lang="EN-US">As of Java
SE 7 Update 2, Java SE includes JavaFX 2.0, so if you don´t have a version of
Java installed, go for this package. If you already have installed a
different Java SE/EE version you can also download JavaFX 2.0 stand-alone.<o:p></o:p></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span lang="EN-US">Here is the
download of the latest Java SE version, which is 7 Update 3:<o:p></o:p></span></div>
<div class="MsoNormal">
<span lang="EN-US"><a href="http://www.oracle.com/technetwork/java/javase/downloads/jdk-7u3-download-1501626.html">http://www.oracle.com/technetwork/java/javase/downloads/jdk-7u3-download-1501626.html</a></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
</div>
<div class="MsoNormal">
<span lang="EN-US">If you want
to install Java EE as well, you can download the package with JavaSE and JavaEE.</span><br />
<span lang="EN-US">Note: It is "only" JavaSE 7 Update1, which means, that JavaFX 2.0 isn´t included. If you download this package, you´ll have to download the JavaFX 2.0 SDK separately.<o:p></o:p></span></div>
<div class="MsoNormal">
<span lang="EN-US"><a href="http://www.oracle.com/technetwork/java/javaee/downloads/java-ee-sdk-6u3-jdk-7u1-downloads-523391.html">http://www.oracle.com/technetwork/java/javaee/downloads/java-ee-sdk-6u3-jdk-7u1-downloads-523391.html</a><o:p></o:p></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
</div>
<div class="MsoNormal">
<span lang="EN-US">The
standalone version of JavaFX 2.0 can be found here:<o:p></o:p></span></div>
<div class="MsoNormal">
<span lang="EN-US"><a href="http://www.oracle.com/technetwork/java/javafx/downloads/index.html">http://www.oracle.com/technetwork/java/javafx/downloads/index.html</a><o:p></o:p></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
</div>
<div class="MsoNormal">
<span lang="EN-US">Either way,
simply download the appropriate file for your operating system and follow the
installation instructions.<o:p></o:p></span></div><a name='more'></a><br />
<div class="MsoNormal">
<span lang="EN-US">After
installing Java/JavaFX 2.0 we also need an IDE. I turned into a NetBeans guy about
1 year ago, but you can also use Eclipse, IntelliJ IDEA or something different,
but I will only cover NetBeans in this blog. I´ll also use NetBeans 7.1.1 for
the upcoming JavaFX 2.0 beginner tutorials.<o:p></o:p></span></div>
<div class="MsoNormal">
<span lang="EN-US"><br /></span></div>
<div class="MsoNormal">
<span lang="EN-US">The newest
version of NetBeans can be found here:<o:p></o:p></span></div>
<div class="MsoNormal">
<span lang="EN-US"><a href="http://netbeans.org/downloads/index.html">http://netbeans.org/downloads/index.html</a><o:p></o:p></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span lang="EN-US">You can
choose between different bundles, depending on what kind of applications you
plan to develop. <o:p></o:p></span></div>
<div class="MsoNormal">
<span lang="EN-US">If you also
want to develop JavaEE applications as well, you should download the JavaEE bundle.
Otherwise, the JavaSE bundle will be enough for our purposes.<o:p></o:p></span></div>
<div class="MsoNormal">
<span lang="EN-US">Assuming </span>you
installed the Java SDK and the JavaFX 2.0 SDK correctly, NetBeans will
automatically find your Java SDKs as seen in the following picture.</div>
<div class="MsoNormal">
<span lang="EN-US"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRNoyFfWK8RPbfeyCOrBkJfOkaIwGPnJ-w1TjAexnJkjEaT8GnQhu1-YpX5hem99dXvCaiUVmuoe5PGfqSWDmtu3ZILvH3-62k0Lq-zTlhAGVQZrKWMXfcE2Tgp-zqppHo-FYoBNThUuVW/s1600/installing_netbeans_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRNoyFfWK8RPbfeyCOrBkJfOkaIwGPnJ-w1TjAexnJkjEaT8GnQhu1-YpX5hem99dXvCaiUVmuoe5PGfqSWDmtu3ZILvH3-62k0Lq-zTlhAGVQZrKWMXfcE2Tgp-zqppHo-FYoBNThUuVW/s320/installing_netbeans_1.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<div class="MsoNormal">
<span lang="EN-US">Follow the last instructions and complete the installation.<o:p></o:p></span></div>
<div class="MsoNormal">
<span lang="EN-US"><br /></span></div>
<div class="MsoNormal">
<span lang="EN-US">My next blog post will cover the famous "Hello World" example in JavaFX 2.0.</span></div>
<br />
<div class="MsoNormal">
<span lang="EN-US"><br /></span></div>
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/06758323276772641565noreply@blogger.com0tag:blogger.com,1999:blog-8609681790114022775.post-25344922740803408752012-03-15T10:11:00.000+01:002012-03-28T15:26:21.375+02:00Welcome to my blog<p>So, welcome to my blog. First of all I would like to introduce myself quickly: My name is Sebastian Damm, I am 23 years old, I live in Germany and I am about to finish my apprenticeship
as a software developer. As English isn´t my native language, please excuse any spelling or grammar mistakes. Nevertheless I want to write my blog in English to make it appeal to a broader audience.</p>
<br /> <h1>What is this blog all about?</h1>
<p>As I am a big Java fan, the majority of posts will be about different Java technologies and news. Because I learned JavaFX 2.0 in the last few weeks, I decided, that
it´ll be a good idea to post some beginner tutorials and introductions about
JavaFX 2.0, because many people want to learn it at the moment.
So expect the
first several posts to cover some JavaFX 2.0 basics and beginner examples.</p>
<br /> <br />Anonymoushttp://www.blogger.com/profile/06758323276772641565noreply@blogger.com0