L16-JavaFXControls
L16-JavaFXControls
2
(c) Paul Fodor and Pearson Inc.
Label class
3
(c) Paul Fodor and Pearson Inc.
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Ellipse;
public class LabelWithGraphic extends Application {
@Override
public void start(Stage primaryStage) {
ImageView us = new ImageView(new Image("us.jpg"));
Label lb1 = new Label("US\n50 States", us);
lb1.setStyle("-fx-border-color: green; -fx-border-width: 2");
lb1.setContentDisplay(ContentDisplay.BOTTOM);
lb1.setTextFill(Color.RED);
Label lb2 = new Label("Circle", new Circle(50, 50, 25));
lb2.setContentDisplay(ContentDisplay.TOP);
lb2.setTextFill(Color.ORANGE);
Label lb3 = new Label("Retangle", new Rectangle(10, 10, 50, 25));
lb3.setContentDisplay(ContentDisplay.RIGHT);
Label lb4 = new Label("Ellipse", new Ellipse(50, 50, 50, 25));
lb4.setContentDisplay(ContentDisplay.LEFT);
4
(c) Paul Fodor and Pearson Inc.
Ellipse ellipse = new Ellipse(50, 50, 50, 25);
ellipse.setStroke(Color.GREEN);
ellipse.setFill(Color.WHITE);
StackPane stackPane = new StackPane();
stackPane.getChildren().addAll(ellipse, new Label("JavaFX"));
Label lb5 = new Label("A pane inside a label", stackPane);
lb5.setContentDisplay(ContentDisplay.BOTTOM);
5
(c) Paul Fodor and Pearson Inc.
ButtonBase and Button
A button is a control that triggers an action event when clicked.
JavaFX provides regular buttons, toggle buttons, check box buttons,
and radio buttons.
The common features of these buttons are defined in ButtonBase
and Labeled classes.
6
(c) Paul Fodor and Pearson Inc.
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.text.Text;
return pane;
}
8
(c) Paul Fodor and Pearson Inc.
CheckBox
A CheckBox is used for the user to make a selection (square box).
CheckBox inherits all the properties from ButtonBase and Labeled:
onAction, text, graphic, alignment, graphicTextGap, textFill,
contentDisplay.
9
(c) Paul Fodor and Pearson Inc.
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
text.setFont(fontNormal);
chkBold.setOnAction(handler);
chkItalic.setOnAction(handler);
12
(c) Paul Fodor and Pearson Inc.
import static javafx.application.Application.launch;
import javafx.geometry.Insets;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
rbRed.setOnAction(e -> {
if (rbRed.isSelected()) {
text.setFill(Color.RED);
}
13 }); (c) Paul Fodor and Pearson Inc.
rbGreen.setOnAction(e -> {
if (rbGreen.isSelected()) {
text.setFill(Color.GREEN);
}
});
rbBlue.setOnAction(e -> {
if (rbBlue.isSelected()) {
text.setFill(Color.BLUE);
}
});
return pane;
}
14
(c) Paul Fodor and Pearson Inc.
TextField
A text field can be used to enter or display a string. TextField is a
subclass of TextInputControl.
15
(c) Paul Fodor and Pearson Inc.
import static javafx.application.Application.launch;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
public class TextFieldDemo extends RadioButtonDemo{
@Override
protected BorderPane getPane() {
BorderPane pane = super.getPane();
return pane;
}
17
(c) Paul Fodor and Pearson Inc.
ComboBox
A combo box, also known as a choice list or drop-down list, contains
a list of items from which the user can choose.
18
(c) Paul Fodor and Pearson Inc.
ListView
A list view is a component that performs basically the same
function as a combo box, but it enables the user to choose a
single value or multiple values.
19
(c) Paul Fodor and Pearson Inc.
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.SelectionMode;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.collections.FXCollections;
lv.getSelectionModel().selectedItemProperty().addListener(
ov -> {
imagePane.getChildren().clear();
for (Integer i: lv.getSelectionModel().getSelectedIndices()) {
imagePane.getChildren().add(ImageViews[i]);
}
});
21
(c) Paul Fodor and Pearson Inc.
ScrollBar
A scroll bar is a control that enables the user
to select from a range of values. The
scrollbar appears in two styles: horizontal
and vertical.
22
(c) Paul Fodor and Pearson Inc.
Slider
Slider is similar to ScrollBar, but Slider
has more properties and can appear in
many forms.
23
(c) Paul Fodor and Pearson Inc.
Media
The Media class is used to obtain the source of a media type.
The MediaPlayer class is used to play and control the media.
The MediaView class is used to display video.
24
(c) Paul Fodor and Pearson Inc.
MediaPlayer
The MediaPlayer class plays and controls media with properties:
autoPlay, currentCount, cycleCount, mute, volume, and
totalDuration.
25
(c) Paul Fodor and Pearson Inc.
MediaView
The MediaView class is a subclass of Node that provides a view of the
Media being played by a MediaPlayer.
The MediaView class provides the properties for viewing the media.
26
(c) Paul Fodor and Pearson Inc.
Example: Using Media
This example displays a video in a view: use the play/pause button to
play or pause the video and use the rewind button to restart the video,
and use the slider to control the volume of the audio.
27
(c) Paul Fodor and Pearson Inc.
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.geometry.Pos;
import javafx.util.Duration;
public class MediaDemo extends Application {
private static final String MEDIA_URL = "sample.mp4";
@Override
public void start(Stage primaryStage) {
Media media = new Media(MEDIA_URL);
MediaPlayer mediaPlayer = new MediaPlayer(media);
MediaView mediaView = new MediaView(mediaPlayer);
Button playButton = new Button(">");
playButton.setOnAction(e -> {
if (playButton.getText().equals(">")) {
mediaPlayer.play();
playButton.setText("||");
} else {
mediaPlayer.pause();
playButton.setText(">");
28 } (c) Paul Fodor and Pearson Inc.
});
Button rewindButton = new Button("<<");
rewindButton.setOnAction(e -> mediaPlayer.seek(Duration.ZERO));
Slider slVolume = new Slider();
slVolume.setPrefWidth(150);
slVolume.setMaxWidth(Region.USE_PREF_SIZE);
slVolume.setMinWidth(30);
slVolume.setValue(50);
mediaPlayer.volumeProperty().bind(slVolume.valueProperty().divide(100));
HBox hBox = new HBox(10);
hBox.setAlignment(Pos.CENTER);
hBox.getChildren().addAll(playButton, rewindButton,
new Label("Volume"), slVolume);
BorderPane pane = new BorderPane();
pane.setCenter(mediaView);
pane.setBottom(hBox);
29
(c) Paul Fodor and Pearson Inc.
CSS
Cascading Style Sheets (CSS) is a language used for describing the look and
formatting of a document.
CSS is designed primarily to enable the separation of document content
from document presentation (layout, colors, and fonts).
It is used to style web pages and user interfaces written in HTML, XHTML, and any
kind of XML document.
The CSS language specifications are Web standards maintained by
the World Wide Web Consortium (W3C).
CSS rule set example:
30
(c) Paul Fodor and Pearson Inc.
JavaFX CSS
JavaFX Cascading Style Sheets (CSS) is based on the W3C CSS and
allows to customize and develop themes for JavaFX controls and
scene graph objects
http://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html
JavaFX uses the prefix "-fx-" to define its vendor CSS properties
(separate from W3C CSS).
A style sheet uses the style class or style id to define styles.
Mutiple style classes can be applied to a single node and a style id to a
unique node.
The syntax .styleclass defines a style class.
The syntax #styleid defines a style id.
31
(c) Paul Fodor and Pearson Inc.
Style Class and Style ID
mystyle.css:
.plaincircle {
-fx-fill: white;
-fx-stroke: black;
}
.circleborder {
-fx-stroke-width: 5;
-fx-stroke-dash-array: 12 2 4 2;
}
.border {
-fx-border-color: black;
-fx-border-width: 5;
}
#redcircle {
-fx-fill: red;
-fx-stroke: red;
}
#greencircle {
-fx-fill: green;
-fx-stroke: green;
}
32
(c) Paul Fodor and Pearson Inc.
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Circle;
public class StyleSheetDemo extends Application {
@Override
public void start(Stage primaryStage) {
HBox hBox = new HBox(5);
Scene scene = new Scene(hBox, 300, 250);
// Load the stylesheet
scene.getStylesheets().add("mystyle.css");
Pane pane1 = new Pane();
Circle circle1 = new Circle(50, 50, 30);
Circle circle2 = new Circle(150, 50, 30);
Circle circle3 = new Circle(100, 100, 30);
pane1.getChildren().addAll(circle1, circle2, circle3);
pane1.getStyleClass().add("border");
circle1.getStyleClass().add("plaincircle"); // Add a style class
circle2.getStyleClass().add("plaincircle"); // Add a style class
circle3.setId("redcircle"); // Add a style id
Pane pane2 = new Pane();
Circle circle4 = new Circle(100, 100, 30);
33
(c) Paul Fodor and Pearson Inc.
circle4.getStyleClass().addAll("circleborder", "plainCircle");
circle4.setId("greencircle"); // Add a style class
pane2.getChildren().add(circle4);
pane2.getStyleClass().add("border");
hBox.getChildren().addAll(pane1, pane2);
primaryStage.setTitle("StyleSheetDemo");
primaryStage.setScene(scene);
primaryStage.show();
}
34
(c) Paul Fodor and Pearson Inc.
QuadCurve
A quadratic curve is mathematically defined as a quadratic
polynomial.
QuadCurve(double startX, double startY,
double controlX, double controlY, double
endX, double endY)
(controlX, controlY)
(endX, endY)
(startX, startY)
35
(c) Paul Fodor and Pearson Inc.
QuadCurve
The getter and setter methods for property values and a getter for property
javafx.scene.shape.QuadCurve itself are provided in the class, but omitted in the UML diagram for brevity.
36
(c) Paul Fodor and Pearson Inc.
Menus
Menus make selection easier and are widely used in window
applications.
JavaFX provides five classes that implement menus: MenuBar,
Menu, MenuItem, CheckMenuItem, and
RadioButtonMenuItem.
MenuBar is a top-level menu component used to hold the
menus.
A menu consists of menu items that the user can select (or
toggle on or off).
A menu item can be an instance of MenuItem,
CheckMenuItem, or RadioButtonMenuItem.
Menu items can be associated with nodes and keyboard
37 accelerators. (c) Paul Fodor and Pearson Inc.
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.geometry.Pos;
menuItemAdd.setAccelerator(
KeyCombination.keyCombination("Ctrl+A"));
menuItemSubtract.setAccelerator(
KeyCombination.keyCombination("Ctrl+S"));
menuItemMultiply.setAccelerator(
KeyCombination.keyCombination("Ctrl+M"));
menuItemDivide.setAccelerator(
KeyCombination.keyCombination("Ctrl+D"));
HBox hBox1 = new HBox(5);
tfNumber1.setPrefColumnCount(2);
tfNumber2.setPrefColumnCount(2);
39 tfResult.setPrefColumnCount(2);
(c) Paul Fodor and Pearson Inc.
hBox1.getChildren().addAll(new Label("Number 1:"), tfNumber1,
new Label("Number 2:"), tfNumber2, new Label("Result:"),
tfResult);
hBox1.setAlignment(Pos.CENTER);
double result = 0;
switch (operator) {
case '+': result = number1 + number2; break;
case '-': result = number1 - number2; break;
case '*': result = number1 * number2; break;
case '/': result = number1 / number2; break;
}
tfResult.setText(result + "");
};
41
(c) Paul Fodor and Pearson Inc.
Context Menu
A context menu (also known as a popup menu) is like a
regular menu, but does not have a menu bar and can float
anywhere on the screen.
Creating a context menu is similar to creating a regular menu.
First, create an instance of ContextMenu, then add MenuItem,
CheckMenuItem, and RadioMenuItem to the context menu.
42
(c) Paul Fodor and Pearson Inc.
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.image.ImageView;
public class ContextMenuDemo extends Application {
@Override
public void start(Stage primaryStage) {
ContextMenu contextMenu = new ContextMenu();
MenuItem menuItemNew = new MenuItem("New",
new ImageView("image/new.gif"));
MenuItem menuItemOpen = new MenuItem("Open",
new ImageView("image/open.gif"));
MenuItem menuItemPrint = new MenuItem("Print",
new ImageView("image/print.gif"));
MenuItem menuItemExit = new MenuItem("Exit");
contextMenu.getItems().addAll(menuItemNew, menuItemOpen,
menuItemPrint, menuItemExit);
Pane pane = new Pane();
Scene scene = new Scene(pane, 300, 250);
primaryStage.setTitle("ContextMenuDemo");
primaryStage.setScene(scene);
primaryStage.show();
43
(c) Paul Fodor and Pearson Inc.
pane.setOnMousePressed(
e -> contextMenu.show(pane, e.getScreenX(), e.getScreenY()));
44
(c) Paul Fodor and Pearson Inc.
SplitPane
The SplitPane class can be used to display multiple panes and
allow the user to adjust the size of the panes.
45
(c) Paul Fodor and Pearson Inc.
TabPane
The TabPane class can be used to display multiple panes with
tabs.
46
(c) Paul Fodor and Pearson Inc.
TabPane
javafx.scene.control.Control The getter and setter methods for property values and
a getter for property itself are provided in the class, but
omitted in the UML diagram for brevity.
javafx.scene.control.TabPane
-side: ObjectProperty<Side> The position of the tab in the tab pane. Possible values are:
Side.TOP, Side.BOTTOM, Side.LEFT, and Side.RIGHT (default:
Side.TOP).
Creates a default tab pane.
+TabPane()
+getTabs(): ObservableList<Tab> Returns a list of tabs in this tab pane.
java.lang.Object The getter and setter methods for property values and
a getter for property itself are provided in the class, but
omitted in the UML diagram for brevity.
javafx.scene.control.Tab
javafx.scene.control.Control The getter and setter methods for property values and
a getter for property itself are provided in the class, but
omitted in the UML diagram for brevity.
javafx.scene.control.TableView<S>
CellDataFeatures<S,T>,ObservableValue
<T>>>
-graphic: ObjectProperty<Node> The graphic for this TableColumn.
-id: StringProperty The id for this TableColumn.
-resizable: BooleanProperty Indicates whether the column is resizable.
-sortable: BooleanProperty Indicates whether the column is sortable.
-text: StringProperty Text in the table column header.
-style: StringProperty Specify the CSS style for the column.
-visible: BooleanProperty Specify whether the column is visible (default: true).
+TableColumn() Creates a default TableColumn.
+TableColumn(text: String) Creates a TableView with the specified header text.
49
(c) Paul Fodor and Pearson Inc.
FXML
FXML is a declarative XML-based language created by
Oracle Corporation for defining the user interface of a
JavaFX 2.0 application.
It can be edited and created using the JavaFX Scene
Builder 2 (downloaded separately from J2SE)
Create a new JavaFX project in Netbeans and you
will get 3 files: an FXML file with the UI design, a
main application .java file that loads the FXML and a
controller for the event handlers for the UI Nodes.
50
(c) Paul Fodor and Pearson Inc.
FXML document:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="200"
xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8"
fx:controller="javafxapplication1.FXMLDocumentController">
<children>
<FlowPane prefHeight="200.0" prefWidth="200.0">
<children>
<Label fx:id="label" minHeight="16" minWidth="69"
text="Welcome to FXML" />
</children>
</FlowPane>
</children>
</AnchorPane>
51
(c) Paul Fodor and Pearson Inc.
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
public class JavaFXApplication5 extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
public class FXMLDocumentController implements Initializable {
@FXML
private Label label;
@Override
public void initialize(URL url, ResourceBundle rb) {
}
}52
(c) Paul Fodor and Pearson Inc.
HTML in JavaFX
HTML intro.: the Internet Web pages format
Example: html_sample_01.html
<!DOCTYPE html>
<html> ← This is the HTML tag. Every HTML page has one
<body>
← This is a paragraph
<p>My first paragraph.</p>
</body>
</html>
53
(c) Paul Fodor and Pearson Inc.
HTML
HTML is a language for describing web pages.
HTML stands for Hyper Text Markup Language
HTML is a markup language
A markup language is a set of markup tags
The tags describe document content
HTML documents contain HTML tags and plain text
HTML documents are also called web pages
54
(c) Paul Fodor and Pearson Inc.
HTML
HTML markup tags are usually called HTML tags
HTML tags are keywords (tag names) surrounded by angle
brackets like <html>
HTML tags normally come in pairs like <b> and </b>
The first tag in a pair is the start tag, the second tag is
the end tag
The end tag is written like the start tag, with a forward
slash before the tag name
Start and end tags are also called opening tags and closing
tags
<tagname>content</tagname>
55 <p>This is a paragraph.</p>
(c) Paul Fodor and Pearson Inc.
HTML by Examples
http://www.w3schools.com/html/html_examples.asp
HTML links:
<a href="http://www.w3schools.com">This is a link</a>
It appears as: This is a link
HTML images:
<img src="w3schools.jpg" width="104" height="142">
It appears as:
56
(c) Paul Fodor and Pearson Inc.
JavaFX with HTML
You can put HTML code in JavaFX:
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
public class HTMLDemo extends Application {
@Override
public void start(Stage primaryStage) {
WebView browser = new WebView();
WebEngine webEngine = browser.getEngine();
webEngine.loadContent("<html><b><u>T</u>wo</b><br>lines</html>");
StackPane root = new StackPane();
root.getChildren().add(browser);
Scene scene = new Scene(root, 100, 150); import org.w3c.dom.Document;
primaryStage.setTitle("Hello World!"); // ... get the document of the engine
primaryStage.setScene(scene); Document doc = webEngine.getDocument();
primaryStage.show(); // and the elements
import org.w3c.dom.Element;
}
... Element el = doc.getElementById("id1");
public static void main(String[] args) {
launch(args);
}
57
} (c) Paul Fodor and Pearson Inc.
JavaFX with HTML
You can get the Document only when the asynchronized WebEngine had
finished loading the page. That is,
Document doc = webEngine.getDocument();
may be null if the page is not loaded yet.
Solution: listen to the state of the WebEngine object to know when it is done loading:
engine.getLoadWorker().stateProperty().addListener(
(ObservableValue<? extends State> observable,
State oldValue, State newValue)
-> {
if (newValue == State.SUCCEEDED)
docManager.setStatsDoc(engine.getDocument());
});
58
(c) Paul Fodor and Pearson Inc.
javafx.scene.canvas.Canvas
javafx.scene.canvas.Canvas is an image that can be drawn on using a
set of graphics commands provided by a GraphicsContext.
javafx.scene.canvas.GraphicsContext issues draw calls to
a Canvas using a buffer:
each call pushes the necessary parameters onto the buffer where they
will be later rendered onto the image of the Canvas node by the
rendering thread at the end of a pulse.
Canvas canvas = new Canvas(250,250);
GraphicsContext gc =
canvas.getGraphicsContext2D();
gc.fillRect(75,75,100,100);
59
(c) Paul Fodor and Pearson Inc.
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.geometry.Point2D;
import javafx.geometry.Rectangle2D;
import javafx.scene.Group;
import javafx.scene.image.Image;
import javafx.stage.Screen;
import java.util.ArrayList;
import java.util.Iterator;
public class CanvasDemo extends Application {
Stage primaryStage;
Scene scene;
Canvas canvas;
GraphicsContext gc;
Image logo1Image, logo2Image;
ArrayList<Point2D> logo1Locations, logo2Locations;
@Override
public void start(Stage initPrimaryStage) {
primaryStage = initPrimaryStage;
initStage();
initData();
initGUI();
60 initHandlers();
(c) Paul Fodor and Pearson Inc.
}
public void initStage() {
Screen screen = Screen.getPrimary();
Rectangle2D bounds = screen.getVisualBounds();
primaryStage.setX(bounds.getMinX());
primaryStage.setY(bounds.getMinY());
primaryStage.setWidth(bounds.getWidth());
primaryStage.setHeight(bounds.getHeight());
}
public void initData() {
logo1Locations = new ArrayList();
logo2Locations = new ArrayList();
logo1Image = new Image("file:images/logo1.png");
logo2Image = new Image("file:images/logo2.png");
}
public void initGUI() {
canvas = new Canvas();
gc = canvas.getGraphicsContext2D(); // is graphics destination: monitor
Group root = new Group();
root.getChildren().add(canvas);
scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
canvas.setWidth(scene.getWidth());
canvas.setHeight(scene.getHeight());
}
61
(c) Paul Fodor and Pearson Inc.
public void initHandlers() {
canvas.setOnMouseClicked(mouseEvent -> {
Point2D point = new Point2D(mouseEvent.getX(), mouseEvent.getY());
if (!logo1Locations.contains(point)) {
logo1Locations.add(point);
}
draw();
});
canvas.setOnMouseDragged(mouseEvent -> {
Point2D point = new Point2D(mouseEvent.getX(), mouseEvent.getY());
if (!logo2Locations.contains(point)) {
logo2Locations.add(point);
}
draw();
});
}
public void draw() {
Iterator<Point2D> it = logo1Locations.iterator();
while (it.hasNext()) {
Point2D p = it.next();
gc.drawImage(logo1Image, p.getX(), p.getY());
}
it = logo2Locations.iterator();
while (it.hasNext()) {
Point2D p = it.next();
gc.drawImage(logo2Image, p.getX(), p.getY());
}
}
public static void main(String[] args) {
62 launch();
(c) Paul Fodor and Pearson Inc.
}}
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.geometry.Rectangle2D;
import javafx.scene.Group;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.stage.Screen;
import java.util.ArrayList;
public class PentaApp extends Application {
private Stage primaryStage;
private Scene scene;
private Canvas canvas;
private GraphicsContext gc;
private ArrayList<double[]> xPoints;
private ArrayList<double[]> yPoints;
private ArrayList<Color> colors;
@Override
public void start(Stage initPrimaryStage) {
primaryStage = initPrimaryStage;
initStage();
initData();
initGUI();
63 initHandlers();
(c) Paul Fodor and Pearson Inc.
}
public void initStage() {
primaryStage.setTitle("Penta App");
Screen screen = Screen.getPrimary(); // is graphics destination: monitor
Rectangle2D bounds = screen.getVisualBounds();
primaryStage.setX(bounds.getMinX());
primaryStage.setY(bounds.getMinY());
primaryStage.setWidth(bounds.getWidth());
primaryStage.setHeight(bounds.getHeight());
}
public void initData() {
xPoints = new ArrayList();
yPoints = new ArrayList();
colors = new ArrayList();
}
public void initGUI() {
canvas = new Canvas();
gc = canvas.getGraphicsContext2D();
Group root = new Group();
root.getChildren().add(canvas);
scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
canvas.setWidth(scene.getWidth());
canvas.setHeight(scene.getHeight());
}
public void initHandlers() {
canvas.setOnMouseClicked(mouseEvent -> {
if (mouseEvent.getClickCount() == 2) {
xPoints.clear();
64 yPoints.clear();
(c) Paul Fodor and Pearson Inc.
colors.clear();
gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
}
});
canvas.setOnMouseDragged(mouseEvent -> {
double x = mouseEvent.getX();
double y = mouseEvent.getY();
double[] xs = new double[5];
double[] ys = new double[5];
// CENTER
xs[0] = x;
ys[0] = y - (int) (Math.random() * 20) - 1;
// TOP-RIGHT POINT
xs[1] = x + (int) (Math.random() * 15) + 1;
ys[1] = y - (int) (Math.random() * 10) - 1;
// BOTTOM-RIGHT POINT
xs[2] = x + (int) (Math.random() * 10) + 1;
ys[2] = y + (int) (Math.random() * 15) + 1;
// BOTTOM-LEFT POINT
xs[3] = x - (int) (Math.random() * 10) - 1;
ys[3] = y + (int) (Math.random() * 15) + 1;
// TOP-LEFT POINT
xs[4] = x - (int) (Math.random() * 15) - 1;
ys[4] = y - (int) (Math.random() * 10) - 1;
xPoints.add(xs);
yPoints.add(ys);
int r = (int) (Math.random() * 256);
int g = (int) (Math.random() * 256);
int b = (int) (Math.random() * 256);
colors.add(Color.rgb(r, g, b));
PentaApp.this.draw();
65 });
} (c) Paul Fodor and Pearson Inc.
public void draw() {
for (int i = 0; i < xPoints.size(); i++) {
double[] xVertices = xPoints.get(i);
double[] yVertices = yPoints.get(i);
for (int j = 0; j < 5; j++) {
xVertices[j] += (int) (Math.random() * 9) - 4;
yVertices[j] += (int) (Math.random() * 9) - 4;
}
Color color = colors.get(i);
gc.setFill(color);
gc.fillPolygon(xVertices, yVertices, 5);
gc.setStroke(Color.BLACK);
gc.strokePolygon(xVertices, yVertices, 5);
}
}
66
(c) Paul Fodor and Pearson Inc.