Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
100% found this document useful (4 votes)
11 views

Frontend Development with JavaFX and Kotlin: Build State-of-the-Art Kotlin GUI Applications Peter Späth all chapter instant download

Development

Uploaded by

faluavaltea32
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (4 votes)
11 views

Frontend Development with JavaFX and Kotlin: Build State-of-the-Art Kotlin GUI Applications Peter Späth all chapter instant download

Development

Uploaded by

faluavaltea32
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 66

Download Full Version ebookmass - Visit ebookmass.

com

Frontend Development with JavaFX and Kotlin: Build


State-of-the-Art Kotlin GUI Applications Peter
Späth

https://ebookmass.com/product/frontend-development-with-
javafx-and-kotlin-build-state-of-the-art-kotlin-gui-
applications-peter-spath/

OR CLICK HERE

DOWLOAD NOW

Discover More Ebook - Explore Now at ebookmass.com


Instant digital products (PDF, ePub, MOBI) ready for you
Download now and discover formats that fit your needs...

Beginning Kotlin: Build Applications with Better Code,


Productivity, and Performance Ted Hagos

https://ebookmass.com/product/beginning-kotlin-build-applications-
with-better-code-productivity-and-performance-ted-hagos/

ebookmass.com

Programming Kotlin Applications: Building Mobile and


Server-Side Applications With Kotlin Brett Mclaughlin

https://ebookmass.com/product/programming-kotlin-applications-
building-mobile-and-server-side-applications-with-kotlin-brett-
mclaughlin/
ebookmass.com

Kotlin for Web Development and Kotlin Collections: A


Beginner's Odyssey in Web Development 2 Books in 1 Jp
Parker
https://ebookmass.com/product/kotlin-for-web-development-and-kotlin-
collections-a-beginners-odyssey-in-web-development-2-books-in-1-jp-
parker/
ebookmass.com

(eTextbook PDF) for Philosophy Here and Now: Powerful


Ideas in Everyday Life 2nd Edition

https://ebookmass.com/product/etextbook-pdf-for-philosophy-here-and-
now-powerful-ideas-in-everyday-life-2nd-edition/

ebookmass.com
Maturing the Snowflake Data Cloud: A Templated Approach to
Delivering and Governing Snowflake in Large Enterprises
Andrew Carruthers
https://ebookmass.com/product/maturing-the-snowflake-data-cloud-a-
templated-approach-to-delivering-and-governing-snowflake-in-large-
enterprises-andrew-carruthers/
ebookmass.com

The Law and Ethics of Freedom of Thought, Volume 1 :


Neuroscience, Autonomy, and Individual Rights Marc
Jonathan Blitz
https://ebookmass.com/product/the-law-and-ethics-of-freedom-of-
thought-volume-1-neuroscience-autonomy-and-individual-rights-marc-
jonathan-blitz/
ebookmass.com

Depression 3rd Edition Edition Raymond W. Lam

https://ebookmass.com/product/depression-3rd-edition-edition-raymond-
w-lam/

ebookmass.com

The Only EKG Book You’ll Ever Need Eighth Edition – Ebook
PDF Version

https://ebookmass.com/product/the-only-ekg-book-youll-ever-need-
eighth-edition-ebook-pdf-version/

ebookmass.com

Christ, the Spirit, and Human Transformation in Gregory of


Nyssa's In Canticum Canticorum (Oxford Studies in
Historical Theology) Alexander L. Abecina
https://ebookmass.com/product/christ-the-spirit-and-human-
transformation-in-gregory-of-nyssas-in-canticum-canticorum-oxford-
studies-in-historical-theology-alexander-l-abecina/
ebookmass.com
Yours To Take (Dixon Creek Ranch, Book 1) (A Small Town,
Virgin Romance) Emily Silver

https://ebookmass.com/product/yours-to-take-dixon-creek-ranch-
book-1-a-small-town-virgin-romance-emily-silver/

ebookmass.com
Frontend
Development with
JavaFX and Kotlin
Build State-of-the-Art Kotlin
GUI Applications

Peter Späth
Frontend Development with JavaFX and Kotlin
Peter Späth

Frontend Development
with JavaFX and Kotlin
Build State-of-the-Art Kotlin GUI Applications
Peter Späth
Leipzig, Sachsen, Germany

ISBN-13 (pbk): 978-1-4842-9716-2 ISBN-13 (electronic): 978-1-4842-9717-9


https://doi.org/10.1007/978-1-4842-9717-9

Copyright © 2023 by Peter Späth


This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the material is concerned,
specifically the rights of translation, reprinting, reuse of illustrations, recitation, broadcasting, reproduction on microfilms or in
any other physical way, and transmission or information storage and retrieval, electronic adaptation, computer software, or by
similar or dissimilar methodology now known or hereafter developed.
Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with every occurrence of
a trademarked name, logo, or image, we use the names, logos, and images only in an editorial fashion and to the benefit of the
trademark owner, with no intention of infringement of the trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not identified as such,
is not to be taken as an expression of opinion as to whether or not they are subject to proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of publication, neither the authors
nor the editors nor the publisher can accept any legal responsibility for any errors or omissions that may be made. The publisher
makes no warranty, express or implied, with respect to the material contained herein.

Managing Director, Apress Media LLC: Welmoed Spahr


Acquisitions Editor: Celestin Suresh John
Development Editor: Laura Berendson
Coordinating Editor: Mark Powers

Cover designed by eStudioCalamar


Cover image by Jerryyaar Designer on Pixabay (www.pixabay.com)

Distributed to the book trade worldwide by Apress Media, LLC, 1 New York Plaza, New York, NY 10004, U.S.A. Phone 1-
800-SPRINGER, fax (201) 348-4505, e-mail orders-ny@springer-sbm.com, or visit www.springeronline.com. Apress Media,
LLC is a California LLC, and the sole member (owner) is Springer Science + Business Media Finance Inc. (SSBM Finance
Inc). SSBM Finance Inc. is a Delaware corporation.
For information on translations, please e-mail booktranslations@springernature.com; for reprint, paperback, or audio rights,
please e-mail bookpermissions@springernature.com.
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and licenses are also
available for most titles. For more information, reference our Print and eBook Bulk Sales web page at http://www.apress.com/
bulk-sales.
Any source code or other supplementary material referenced by the author in this book is available to readers on GitHub (https://
github.com/Apress). For more detailed information, please visit https://www.apress.com/gp/services/source-code.

Paper in this product is recyclable


Contents

1 Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Gradle for JavaFX and Kotlin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
A HelloWorld Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Setting Up for Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Setting Up for IntelliJ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Kotlin and Java Interoperability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
A Note About Kotlin Utilities for JavaFX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
A Note About FXML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
A Note About Downloading JavaFX Releases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Build Setup for This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2 Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Why you Should use Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
One-Way and Two-Way Bindings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Custom Bindings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
About Observable Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3 Stages and Scenes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
About Screens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Using Stages and the Application Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Dialog-Like Stages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
The JavaFX Application Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
About Scenes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Position and Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Camera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Cursor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Mnemonic and Accelerators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Focus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Node Lookup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Snapshots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Fill and Other Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Keyboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Mouse Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Mouse Event Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

v
vi Contents

Mouse Drag Event Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52


Gestures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4 Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
StackPane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
VBox and HBox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
FlowPane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
GridPane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
TilePane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
BorderPane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
AnchorPane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Styling Panes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Adding Stylesheets to the Whole Scene . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Adding Stylesheets to Individual Panes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
JavaFX CSS Selectors for Panes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
JavaFX CSS Properties for Panes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
5 Visual Nodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Node Coordinate Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Shapes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Canvas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Image Nodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Text Fields and Text Areas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Action Buttons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Button Bars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Toolbars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Checkboxes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Radio Buttons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Combo Boxes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Sliders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Miscellaneous Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Control Panes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Scroll Panes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Accordions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Tab Panes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Split Panes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Styling Visual Nodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
6 Lists and Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Lists with ListView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Tables with TableView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Trees with TreeView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Contents vii

7 Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
What Events Are and Event Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Event Handlers and Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Drag and Drop Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
8 Effects and Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
About Effects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Animating Your Scenes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Transitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
Timeline Animations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
9 Concurrency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
The JavaFX Concurrency Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
About Kotlin Coroutines for JavaFX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
About the Author

Peter Späth graduated in 2002 as a physicist and soon afterward became an IT consultant, mainly for
Java-related projects. In 2016, he decided to concentrate on writing books on various aspects, but with
a main focus on software development. With two books about graphics and sound processing, three
books on Android app development, and a couple of books about Java, Jakarta EE, and Kotlin, Peter
continues his effort in writing software development-related literature.

ix
About the Technical Reviewer

Massimo Nardone has more than 25 years of experience in security,


web and mobile development, cloud, and IT architecture. His true
IT passions are security and Android. He has been programming
and teaching how to program with Android, Perl, PHP, Java, VB,
Python, C/C++, and MySQL for more than 20 years. He holds a
Master of Science degree in Computing Science from the University
of Salerno, Italy. He has worked as a CISO, CSO, security executive,
IoT executive, project manager, software engineer, research engineer,
chief security architect, PCI/SCADA auditor, and senior lead IT
security/cloud/SCADA architect for many years. His technical skills
include security, Android, cloud, Java, MySQL, Drupal, Cobol, Perl,
web and mobile development, MongoDB, D3, Joomla, Couchbase,
C/C++, WebGL, Python, Pro Rails, Django CMS, Jekyll, Scratch,
and more. He worked as visiting lecturer and supervisor for exercises
at the Networking Laboratory of the Helsinki University of Technol-
ogy (Aalto University). He holds four international patents (PKI, SIP,
SAML, and Proxy areas). He is currently working for Cognizant as
head of cyber security and CISO to help both internally and externally
with clients in areas of information and cyber security, like strategy,
planning, processes, policies, procedures, governance, awareness,
and so forth. In June 2017 he became a permanent member of the
ISACA Finland Chapter Board.
Massimo has reviewed more than 45 IT books for different
publishing companies and is the coauthor of Pro Spring Security:
Securing Spring Framework 5 and Boot 2-based Java Applications
(Apress, 2019), Beginning EJB in Java EE 8 (Apress, 2018), Pro
JPA 2 in Java EE 8 (Apress, 2018), and Pro Android Games (Apress,
2015).

xi
Introduction

Building elegant and highly responsible, responsive, and stable Java client applications (fat clients)
is a highly acceptable approach if security considerations or network availability speaks against
web applications, or maintaining servers and server applications lies out of scope for your project.
Additionally, using Kotlin as a programming language boosts code expressiveness and maintainability,
allowing for a development yielding a clean code approach.
The book introduces JavaFX as a frontend technology and from the very beginning focuses
on using Kotlin instead of Java for coding the program artifacts. Many listings and code snippets
accompany the text, readily allowing for a hands-on learning style.

The Book’s Targeted Audience

The book is for low- to mid-level Java or Kotlin developers with or without JavaFX experience,
wishing to learn how to build JavaFX applications with Kotlin.
The readers will in the end be able to use Kotlin as a language for building basic to moderately
advanced and elaborated apps targeting JavaFX.
Any experience in using JavaFX and frontend coding is not a requirement for reading the book.
Being a Kotlin expert is not necessary either, but having read introductory-level books or studied
online resources is surely helpful. The online documentation of Kotlin and JavaFX also provides
valuable resources you can use as a reference while reading this book.

Source Code

All source code shown or referred to in this book can be found at github.com/apress/frontend-
development-javafx-kotlin.

How to Read This Book

This book should be read sequentially to get the most benefit from it. Of course, you can skip one
or the other chapter if you already gained knowledge elsewhere. Taking its introductory nature, the
book is not meant to present a reference fully covering each and every aspect of Kotlin frontend
programming or JavaFX, so also consulting the online documentation at
https://openjfx.io/
https://openjfx.io/javadoc/19/
https://kotlinlang.org/docs/home.html

xiii
xiv Introduction

while you are reading the book certainly is not a bad idea.
The book is split up into nine chapters. Chapter 1 gives a general introduction and presents hello
world-style programs for Gradle, Eclipse, and IntelliJ.
Chapter 2 talks about using properties as data holders and addresses one- and two-way binding
techniques for connecting controls and data in your program.
Chapter 3 introduces stages and scenes, which serve as primordial containers for visual artifacts.
Chapter 4 talks about containers and ways to lay out and style your scenes.
Chapter 5 handles nodes and controls including styling. These aspects usually constitute the biggest
part of your project work speaking of time budget.
Chapter 6 presents lists and tables, which are particularly important for enterprise-level projects.
Chapter 7 is for summarizing and deepening our knowledge about event handling in JavaFX. This
also includes drag and drop procedures.
Chapter 8 introduces effects and animation, improving user experience and giving your programs
some eye candies.
As a prospect, Chapter 9 briefly introduces concurrency techniques, giving you a starting point for
handling background processing needs.
Getting Started
1

In this chapter, we give a brief introduction to using JavaFX and Kotlin together, and we create “Hello
World”–style projects for the command line, for Eclipse, and for IntelliJ IDEA.

Introduction

JavaFX is the dedicated fat client (desktop application) GUI toolkit for current Java releases. It is
the replacement and successor of the venerable Java Swing technology. This switch happened around
2010, and since then JavaFX has been constantly improved and extended. With JREs up to version
JDK 9, JavaFX was part of the Java distribution—with JDK 11 and later, it has to be installed
separately.
The following features describe JavaFX:

. Built-in controls: Labels, editable text fields, buttons, combo boxes, checkboxes, radio buttons,
menu bars, scrollbars, accordion, tabs, canvas (for drawing shapes and figures), color picker, pag-
ination, 3D graphics (games, science, product presentation), WebView (presenting and interacting
with web contents), dialogs, sliders, spinners, progress bars
. Lists, tables, trees
. Built-in layouts: AnchorPane (anchoring nodes to one of the edges or to the center point),
BorderPane (placing nodes at bottom, top, right, left, center), FlowPane (placing nodes consec-
utively and wrapping at the boundaries), TilePane (same as FlowPane, but with all cells the same
size), GridPane (placing nodes in a grid with cell sizes dynamically calculated and on demand
spanning several rows and columns), VBox (placing nodes in columns), HBox (placing nodes in
rows), StackPane (placing nodes in an overlay fashion)
. Animation (fade, fill, stroke, translate, rotate, scale, . . . ), effects (glow, blend, bloom, blur,
reflection, sepia, shadow, lighting)
. Nodes stylable via CSS
. Some built-in chart widgets
. Flexible and concise data binding via observable properties
. Descriptive layouting via FXML
. Module support (for JDK 9+)

© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2023 1
P. Späth, Frontend Development with JavaFX and Kotlin,
https://doi.org/10.1007/978-1-4842-9717-9_1
2 1 Getting Started

. Graphics transformations and coordinate systems


. Media APIs
. Java Swing interoperability
. Comes as a set of JAR modules and native libraries
. An external Scene Builder for graphically creating scenes
. Printing API

In this book, we describe a subset of these features, giving you a starting point for your own
projects.
Using Kotlin as a programming language instead of Java gives a boost to your coding experience.
Just to give you an example, consider a button with a click handler. In Java, you’d write
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});

(255 characters) The very same code written in Kotlin reads


val btn = Button().apply {
text = "Say 'Hello World'"
setOnAction { _ ->
println("Hello World!")
}
}

With 142 characters, this is more than 40% shorter than the Java variant! And besides being shorter,
it is also more expressive and by that easier to understand and easier to maintain.
Using some sufficiently nonobtrusive utility functions, this can even be further reduced to 81
characters in size:
val btn = Button("Say 'Hello World'") {
println("Hello World!")
}

This works by Kotlin’s ability to dynamically add additional constructors to classes.

Gradle for JavaFX and Kotlin

As a build tool, we use Gradle from https://gradle.org/. It is highly flexible, works on any operating
system that provides a Java installation, and by means of plugins or preinstalled components can be
operated from many IDEs.
I first describe the CLI mode for running Gradle builds. This is how you would use it in a server
environment, but it also serves as a good starting point if you want to learn how to use Gradle inside
an IDE workflow.
If not already present, get and install a version 17 JDK. Throughout the book, we will be using
OpenJDK 17, but if chances are good you can also take Oracle’s supported JDK 17 or a higher version
from either Oracle or https://openjdk.org/ without any problems possibly coming up.
Gradle for JavaFX and Kotlin 3

Note Using Oracle’s JDK 17 or higher requires buying a license if you plan to use it for a longer
term; see www.oracle.com/java/.

As a next step, fetch Gradle from https://gradle.org. In this book, we use version 7.6 from https://
gradle.org/next-steps/?version=7.6&format=bin. In order to announce Java to Gradle, either make
sure java and javac (with .bat extension on Windows) are in your PATH, or you have the
environment variable JAVA_HOME point to your JDK installation folder (recommended). To simplify
using Gradle, you can also put GRADLE-INST-DIR/bin (with GRADLE-INST-DIR pointing to your
Gradle folder), or GRADLE-INST-DIR\bin for Windows, on the path.

Note In Linux, environment variables like PATH or JAVA_HOME get set via
export PATH=/bin:/usr/bin:/path/to/my/gradle/bin.
In Windows, you must use the system settings dialog.

In order to check your Gradle installation, in a terminal enter


gradle -version

or, if Gradle is not in the path:


/path/to/gradle -version (Linux)
C:\path\to\gradle.bat -version (Windows)

The output of the command should be similar to


---------------------------------------------------------
Gradle 7.6
---------------------------------------------------------

Build time: 2022-11-25 13:35:10 UTC


Revision: daece9dbc5b79370cc8e4fd6fe4b2cd400e150a8

Kotlin: 1.7.10
Groovy: 3.0.13
Ant: Apache Ant(TM) version 1.10.11 compiled on
July 10 2021
JVM: 17.0.1 (Oracle Corporation 17.0.1+12-39)
OS: Linux 5.15.0-56-generic amd64

Important is the “JVM:” line. The Kotlin version shown does not mean you would not be able to build
applications running under a different Kotlin version—it just tells it is using Kotlin 1.7.10 for its own
purposes.
Next, create a project folder anywhere on your system. For our example project, we call it
HelloWorld. Change into that folder:
cd /path/to/HelloWorld (Linux)
chdir C:\path\to\HelloWorld (Windows)

In order to initialize the Gradle project, enter (one line)


gradle init --dsl groovy --incubating
--insecure-protocol ALLOW --package book.kotlinfx
--project-name kotlinfx --test-framework kotlintest
--type kotlin-application

You can also enter just gradle init, but then you will subsequently be asked for project
coordinates inside the terminal.
4 1 Getting Started

The “init” task creates a simple scaffold project which consists of a main project described by
file settings.gradle and a subproject called “app” in the accordingly named subfolder. The
application can be run by just entering either of
gradle app:run
gradle run

The second variant is possible, because there is just one subproject. By the way, you can list all
possible tasks via gradle tasks or gradle tasks --all, and entering gradle help shows
more info.
Did you notice that two executable files gradlew and gradlew.bat and a folder gradle were
created? This is the Gradle Wrapper, and it is a Gradle installation on its own, and you can henceforth
use it to build the project. Just use gradlew from the wrapper instead of gradle from the Gradle
distribution. You can even delete the main Gradle installation folder at this time, if you like.
It is now time to add JavaFX to the project. In Gradle, the build.gradle file is the main
configuration file for the build process. You can find it inside the app subproject inside the app folder.
Open the file inside a text editor, and inside the plugins { . . . } section, add
plugins {
...
id 'org.openjfx.javafxplugin' version '0.0.13'
}

This plugin adds almost all that is necessary to add JavaFX to a Java or Kotlin project. Kotlin
capabilities were already added during gradle init. We however still need to make sure that
Kotlin compiles for JDK 17 and that JavaFX uses version 19 and allows for using the modules
“javafx.controls” and “javafx.graphics”. For that aim, add at the end of build.gradle
compileKotlin {
kotlinOptions {
suppressWarnings = true
jvmTarget = "17"
}
}
javafx {
version = "19"
modules("javafx.controls", "javafx.graphics")
}

Note JavaFX is separated into different modules. The modules “javafx.base”, “javafx.controls”, and
“javafx.graphics” are essential to almost any JavaFX application. Because both the controls and the
graphics module require the base module, the latter gets implicitly included in any build and can be
omitted from the modules list. For more details, see https://openjfx.io/javadoc/19/

In the next section, we code our little “Hello World” JavaFX with Kotlin application.

A HelloWorld Project

The scaffold project built via gradle init just prints “Hello World!” on the console if run. As a
starter JavaFX project, we instead want to show a little window with a button on it reacting to press
events. To do so, replace the contents of
app/src/main/kotlin/book/kotlinfx/App.kt
Setting Up for Eclipse 5

by
package book.kotlinfx

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

fun main(args:Array<String>) {
Application.launch(HelloWorld::class.java, *args)
}

class HelloWorld : Application() {


override
fun start(primaryStage:Stage) {
primaryStage.title = "Hello World!"
val btn = Button().apply {
text = "Say 'Hello World'"
setOnAction { evnt ->
println("Hello World!")
}
}

val root = StackPane().apply {


children.add(btn)
}

with(primaryStage){
scene = Scene(root, 300.0, 250.0)
show()
}
}
}

Save the file. To now run the application, enter


./gradlew run (Linux)
gradlew run (Windows)

See Figure 1-1.


To first compile and build the project is not necessary—Gradle takes care of that if needed.

Setting Up for Eclipse

Note You can skip this section if you don’t use Eclipse.

Download and install a recent Eclipse IDE from www.eclipse.org/downloads/. Start Eclipse and then,
at Window → Preferences → Java → Installed JREs, register a JDK version 17 and make it the
default. See Figure 1-2.
Then, at File → New → Project. . . → Gradle → Gradle Project, create a new Gradle project. Once
asked, enter “kotlinfx” as the project’s name; see Figure 1-3.
Keep everything else at its defaults. You end up with a main and a subproject; see Figure 1-4.
The name of the subproject reads “lib.” We want to change it to a more meaningful variant.
6 1 Getting Started

Figure 1-1 JavaFX HelloWorld Running

Figure 1-2 Eclipse JRE Setting

Caution Due to a design issue inside the Gradle-Plugin for Eclipse 2022-12, you cannot rename the
subproject’s name via Mouse-Right → Refactor → Rename. . . We must apply a workaround.
Setting Up for Eclipse 7

Figure 1-3 Eclipse Gradle Project Wizard

First, edit file settings.gradle. Change the line


include('lib')
->
include('HelloWorld')

Now delete the “lib” subproject from Eclipse. Make sure the “Also delete project contents” checkbox
is not checked.
In your system’s file explorer, rename folder lib inside WORKSPACE/kotlinfx to
HelloWorld.
On the main project, invoke Mouse-Right → Configure → Configure and Detect Nested
Projects. . . Press the “Finish” button. Ignore possibly shown errors.
Just to be on the safe side, restart Eclipse. The package view should now be as shown in
Figure 1-5.
Back to the application, replace the contents of the build.gradle file by
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.7.10'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.13'
}

repositories {
mavenCentral()
8 1 Getting Started

dependencies {
}

application {
mainClass = 'book.kotlinfx.AppKt'
}

compileKotlin {
kotlinOptions {
suppressWarnings = true
jvmTarget = "17"
}
}

javafx {
version = "19"
modules("javafx.controls", "javafx.graphics")
}

After changes to file build.gradle, the project regularly needs to be updated: on “kotlinfx,”
press Mouse-Right → Gradle → Refresh Gradle Project. Also, remove the packages inside src/
test/java; we don’t need them for now.

Figure 1-4 Eclipse


Gradle Project
Setting Up for Eclipse 9

A fresh Eclipse installation doesn’t know how to handle Kotlin files. To fix this, open Help →
Eclipse Marketplace. . . Enter “kotlin” in the search field, and select to install “Kotlin Plugin for
Eclipse” from the search result list. Restart Eclipse twice.
Make a new folder src/main/kotlin and register it as a source folder via Mouse-Right →
Java Build Path → Source → Add folder. . . See Figure 1-6.

Figure 1-5 Eclipse Subproject Renamed

Figure 1-6 Eclipse Kotlin Sources


10 1 Getting Started

Inside the Kotlin sources section, add a package book.kotlinfx and inside it a Kotlin file
App.kt with contents:
package book.kotlinfx

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

fun main(args:Array<String>) {
Application.launch(HelloWorld::class.java, *args)
}

class HelloWorld : Application() {


override
fun start(primaryStage:Stage) {
primaryStage.title = "Hello World!"
val btn = Button().apply {
text = "Say 'Hello World'"
setOnAction { _ ->
println("Hello World!")
}
}

val root = StackPane().apply {


children.add(btn)
}

with(primaryStage){
scene = Scene(root, 300.0, 250.0)
show()
}
}
}

You can now start the application inside the “Gradle Tasks” view at kotlinfx → HelloWorld →
application → run; see Figure 1-7.
After any changes to the coding, just invoke this task again. Gradle automatically takes care of
compilation and rebuilding the project artifacts necessary to run the updated application.

Setting Up for IntelliJ

Note You can skip this section if you don’t use IntelliJ IDEA.

IntelliJ IDEA can be purchased at www.jetbrains.com/idea/, but you can also download the com-
munity edition, which comes at no cost. To start developing a JavaFX via Kotlin project in IntelliJ
IDEA, create a new project and select the “JavaFX” generator. As project name, enter “HelloWorld”;
as location, choose any folder at your discretion. Then select “Kotlin” as the language and “Gradle”
as the build system, enter “book.kotlinfx” as Group ID and “HelloWorld” as Artifact ID, and select a
version 17 JDK. See Figure 1-8.
Setting Up for IntelliJ 11

Figure 1-7 JavaFX Application in Eclipse

Figure 1-8 JavaFX IntelliJ Project


12 1 Getting Started

Figure 1-9 IntelliJ Project View

If you see a classcast exception as shown in Figure 1-9, open the build.gradle file and add
inside the plugins { . . . } section:
plugins {
...
id 'org.javamodularity.moduleplugin' version '1.8.12'
}

Further down the same file, make sure it reads


application {
mainModule = 'book.kotlinfx.helloworld'
mainClass = 'book.kotlinfx.helloworld.' +
'HelloApplicationKt'
}

If not already existing, make a HelloApplication.kt file inside package book.


kotlinfx.helloworld and let it read:
package book.kotlinfx.helloworld

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

fun main(args:Array<String>) {
Application.launch(HelloWorld::class.java, *args)
}

class HelloWorld : Application() {


Kotlin and Java Interoperability 13

Figure 1-10 IntelliJ Application Running

override
fun start(primaryStage:Stage) {
primaryStage.title = "Hello World!"
val btn = Button().apply {
text = "Say 'Hello World'"
setOnAction { _ ->
println("Hello World!")
}
}

val root = StackPane().apply {


children.add(btn)
}

with(primaryStage){
scene = Scene(root, 300.0, 250.0)
show()
}
}
}

After you open the “Gradle” tab, you can now start the application at HelloWorld → Tasks →
application → run. See Figure 1-10.

Kotlin and Java Interoperability

Kotlin sits on top of the JVM (Java Virtual Machine) and as such is designed to access any Java
library, including extensions of JavaFX. This way, it is possible to enhance your JavaFX projects in
various ways, such as adding math and statistics libraries, XML and JSON processing, networking,
cryptography, and what else you might think of.
14 1 Getting Started

Almost any library you want to include gets configured in the dependencies { . . . } section
of the build.gradle file. The Gradle documentation tells you more about that.
For example, to add the Apache Commons Math library, you would write inside build.gradle:
dependencies {
...
implementation 'org.apache.commons:commons-math3:3.6.1'
}

Note In Eclipse, you afterward have to invoke Mouse-Right .→ Grade .→ Refresh Gradle Project on
the project.

This book presenting JavaFX and Kotlin at an introductory level, the inclined reader is asked to
perform their own research on possible extensions.

A Note About Kotlin Utilities for JavaFX

In Kotlin, it is possible to write functions and variables outside any class. For example, consider a file
src/main/kotlin/book/kotlinfx/aaa.kt:
package book.kotlinfx

val msg = "Hello World"

fun abc() {
println(msg)
}

You then can use it from anywhere:


package any.package

import book.kotlinfx.msg
import book.kotlinfx.abc
// or: import book.kotlinfx.*

...
abc()
...

Internally, Kotlin generates a class named after the file, class book.kotlinfx.AaaKt.class
for the example, and puts such seemingly orphaned variables and functions inside it.
While this comes handy under circumstances, it bears the risk of damaging your object-oriented
design. Even worse, you can use such non-class files to add fields and functions to existing classes in
a rather uncontrolled manner, thwarting the original purpose of such extended classes and making the
code unreadable.
We therefore use such non-class Kotlin files only under the following conditions:

. They do not alter the responsibility of any class.


. There are not too many functions and variables introduced that way.
. They do not represent something that better goes to new classes.
A Note About Kotlin Utilities for JavaFX 15

. We don’t use them to avoid creating new classes (with new responsibilities).
. We use them to improve readability (comprehensiveness), not to add complexity.
. We don’t add more than maybe one or two such files to any project.

Consider the following example: to create a button and add a click handler to it, we have to write
val btn = Button().apply {
text = "Say 'Hello World'"
setOnAction { _ ->
println("Hello World!")
}
}

or
val btn = Button("Say 'Hello World'").apply {
setOnAction { _ ->
println("Hello World!")
}
}

Wouldn’t it be nice if we had a constructor taking the text and the event handler? Even if there is
no such constructor defined in JavaFX, it is possible in Kotlin to define such a new constructor. In
order to achieve that, we would write in a Kotlin file:
package book.kotlinfx.util
import javafx.scene.control.*

fun Button(label:String,
action: Button.() -> Unit):Button =
Button(label).apply{
setOnAction { _ -> action() }
}

This could, for example, be placed inside a file util.kt (the name doesn’t matter), inside package
book.kotlinfx.util.
For any class, we can now import the extension and use the new constructor:
package what.so.ever

import book.kotlinfx.util.*

...
val btn = Button("Click on me",{
println("Clicked")
})
...

Or, because in Kotlin you can write a trailing functional parameter outside the round brackets:
package what.so.ever

import book.kotlinfx.util.*

...
val btn = Button("Click on me"){
println("Clicked")
}
...
16 1 Getting Started

The little HelloWorld program from the previous section can be rewritten to
package book.kotlinfx.helloworld

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

import book.kotlinfx.util.*

fun main(args:Array<String>) {
Application.launch(HelloWorld::class.java, *args)
}

class HelloWorld : Application() {


override
fun start(primaryStage:Stage) {
primaryStage.title = "Hello World!"
val btn = Button("Say 'Hello World'") {
println("Hello World!")
}

val root = StackPane().apply {


children.add(btn)
}

with(primaryStage){
scene = Scene(root, 300.0, 250.0)
show()
}
}
}

Throughout the whole book, we use no-class Kotlin files exactly for such kind of extensions.

A Note About FXML

Around 2012, Oracle introduced FXML, which is an XML-based description language for JavaFX. In
order to use it, you must add javafx.fxml to the modules list in build.gradle:
javafx {
version = "19"
modules(
"javafx.controls",
"javafx.graphics",
"javafx.fxml")
}

In the start() method of the application (see, e.g., the HelloWorld example earlier), you would
write
primaryStage.title = "Hello World!"

val location = this::class.java.classLoader


.getResource("helloworld.fxml")
A Note About FXML 17

val fxmlLoader = FXMLLoader(location)


val root = fxmlLoader.load<Pane>()

with(primaryStage){
scene = Scene(root, 300.0, 250.0)
show()
}

and for src/main/resources/helloworld.fxml:


<?xml version="1.0" encoding="UTF-8"?>

<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>

<GridPane fx:controller="book.kotlinfx.ch01.MyController"
xmlns:fx="http://javafx.com/fxml"
alignment="center" hgap="10" vgap="10">
<padding>
<Insets top="25" right="25" bottom="10" left="25"/>
</padding>
<HBox spacing="10" alignment="bottom_right"
GridPane.columnIndex="1" GridPane.rowIndex="2">
<Button text="Click me"
onAction="#handleButtonAction"/>
</HBox>

<Text fx:id="actiontarget"
GridPane.columnIndex="1" GridPane.rowIndex="4"/>
</GridPane>

Both Button and Text are connected to a controller class book.kotlinfx.ch01.-


MyController:
class MyController {
@FXML var actiontarget:Text? = null

@Suppress("UNUSED_PARAMETER")
@FXML fun handleButtonAction(event:ActionEvent) {
actiontarget?.setText("Button pressed")
}
}

Separating logic and design is a valid approach for good practices. So if you like, you can go ahead
and use FXML for your project. However, in this book, we don’t further apply FXML technologies
for the following reasons:

. Coding in a general-purpose programming language like Kotlin, and in a purely descriptive


language like XML, imposes some sort of technology breach in a project. While it helps to separate
design and logic, bringing those two worlds together sometimes is not that easy.
. XML is static. If you need flexibility for design and layouting, using XML is not the best choice.
. The code in Kotlin often is more expressive and more concise compared to the XML counterpart.
18 1 Getting Started

. There is nothing in FXML you can’t do with Kotlin. On the other hand, you cannot transcode all
programmatic constructs into XML.
. Defining animation or drag and drop operations in pure XML is complicated, if possible at all.

A Note About Downloading JavaFX Releases

JavaFX internally uses a set of operating system–dependent native libraries. Usually, this happens
behind the scenes, and you don’t have to take care of how this works. Under circumstances however,
you might want to have more control over what JavaFX library and native library artifacts get used. To
achieve this, download an SDK following the links presented in https://openjfx.io/. After unzipping
the archive, the directory, for example, looks like
openjfx-19_linux-x64_bin-sdk
javafx-sdk-19
legal
lib
src.zip

In order to use it, inside your app/build.gradle build file write


javafx {
sdk = '/path/to/openjfx-19_linux-x64_bin-sdk' +
'/javafx-sdk-19'
modules("javafx.controls", "javafx.graphics", ...)
}

or for Windows
javafx {
sdk = 'C:\\path\\to\\openjfx-19_win-x64_bin-sdk' +
'\\javafx-sdk-19'
modules("javafx.controls", "javafx.graphics", ...)
}

So the sdk variable must point to the parent folder of the lib directory. From here, you can build
and run Kotlin JavaFX applications as usual.

Build Setup for This Book

The sources you can download at http://todo TODO ENTER LINK consist of three parts:

. An empty Gradle project with each chapter as a subproject. You can use it for experiments and
if you prefer to enter the snippets presented in this book one after another. You can operate it via
Gradle, but Eclipse .project and .classpath files have been added, so you can immediately
load it as an Eclipse workspace.
. A Gradle project with each chapter as a subproject. Each subproject reflects the state you get after
you enter all the code snippets from a chapter. Alternatives that cannot be active at the same time for
technical reasons are commented out. You can operate it via Gradle, but again Eclipse .project
and .classpath files have been added, so you can immediately load it as an Eclipse workspace.
. A loose collection of the code snippets from the book.
Properties
2

Properties in JavaFX are data holders with other properties or third parties being able to register some
interest in being informed about value changes. This comes handy for user input and output controls
in a GUI, where the need for observing value changes and appropriately reacting to such changes is
obvious.
In JavaFX, there are following concrete types of properties:

– SimpleXxxProperty
Where “Xxx” stands for one of: Boolean, Integer, Long, Float, Double, String, Object, List, Set,
Map. Represents a read/write property. This means value changes propagate to clients like e.g. text
fields, but also receives client value updates like e.g. a user entering data into a text field.
– SimpleStyleableXxxProperty
Where “Xxx” stands for one of: Boolean, Integer, Long, Float, Double, String, Object. Represents
a read/write property targeting CSS values (node styles).
– ReadOnlyXxxWrapper
Where “Xxx” stands for one of: Boolean, Integer, Long, Float, Double, String, Object, List, Set,
Map. Represents a read-only property. This means direct value changes via setters are not possible.

This list shows the more often used classes for including properties in your code. For more
information and an exhaustive overview of all property related interfaces and classes see the
javafx.beans.property package at https://openjfx.io/javadoc/19/javafx.base/javafx/beans/
property/package-summary.html or https://docs.oracle.com/javase/8/javafx/api/index.html
All nodes in JavaFX (labels, text fields, checkboxes, sliders, . . . ) use properties to hold data. Via
binding you can connect node properties to properties in your code. We talk more about bindings
below.

Why you Should use Properties

Consider a text field and a button setting the text field’s value:
package book.kotlinfx.ch02

import book.kotlinfx.util.* // from Ch00_Util


// imports skipped

© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2023 19
P. Späth, Frontend Development with JavaFX and Kotlin,
https://doi.org/10.1007/978-1-4842-9717-9_2
20 2 Properties

fun main(args:Array<String>) {
Application.launch(App::class.java, *args)
}

class App : Application() {


override fun start(primaryStage:Stage) {
primaryStage.title = "Properties"

val t = TextField("").apply{
textProperty().addListener {
_, oldValue, newValue ->
println("textfield changed from " +
oldValue + " to " + newValue)
// inform model...
} }
val b = Button("Set 42"){
t.textProperty().value = "42"
}

val root = GridPane().apply {


padding = Insets(5.0)
hgap = 5.0
add( t, 0,0)
add( b, 1,0)
}

with(primaryStage){
scene = Scene(root, 300.0, 250.0)
show()
}
}
}

The textProperty().addListener() method actually asks for a parameter of type


javafx.beans.value.ChangeListener, but since this class has only one method, the
Kotlin compiler knows how to map the lambda construct to an instance of ChangeListener.
For the button we used the extension provided in the util.kt file, project Ch00_Util. In order
to use it, you must add a dependency in the project’s build.gradle file:
dependencies {
implementation project(':Ch00_Util')
// ...
}

The util.kt file is listed in the appendix, but it is also included within the book’s sources provided
as a download.
A text field connected to the model layer of your application design via
val t = TextField("").apply{
textProperty().addListener { _, oldVal, newVal ->
// inform model...
} }

bears the risk that business logic sneaks into the view classes. For small projects it might be acceptable
to ignore this risk, but for larger projects it is preferable to abstract model changes from the frontend
controllers. This way we would be able to enforce the separation between the frontend layer and other
Why you Should use Properties 21

layers of the application, promoting a clean application design. For this aim we can use additional
properties in our code:
val text1Property = SimpleStringProperty("Some text")
// ...

val text1 = TextField()


// ...

// Somehow connect text1 and text1Property


// ...

What is now necessary is a way to connect UI controllers and such additional properties. JavaFX
provides such a connectivity via bindings:
val text1Property = SimpleStringProperty("Some text")
// ...

val text1 = TextField().apply{


textProperty().bindBidirectional(text1Property)
}

Such additional properties can be moved to an own class, commonly referred-to as viewmodel:
fun main(args:Array<String>) {
Application.launch(AppWithViewModel::class.java, *args)
}

class MyViewModel {
val text1Property = SimpleStringProperty("Some text")
}

class AppWithViewModel : Application() {


override fun start(primaryStage:Stage) {
primaryStage.title = "Properties"

val vm = MyViewModel()

val text1 = TextField().apply{


textProperty().bindBidirectional(vm.text1Property) }

val root = GridPane().apply {


padding = Insets(5.0)
hgap = 5.0
add( text1, 0,0)
}

with(primaryStage){
scene = Scene(root, 300.0, 250.0)
show()
}
}
}

Note Such an architecture consisting of UI components talking via binding to properties in a


viewmodel, with the latter being agnostic of UI component classes, gets called MVVM (model-view-
viewmodel - the first model represents the business logic).
22 2 Properties

Another advantage of such a separation is that the viewmodel can be totally agnostic of UI
components, greatly improving testability by letting testing code directly access viewmodel classes
and their properties.
Inside the viewmodel, you can then add business logic:
class MyViewModel {
val text1Property = SimpleStringProperty("Some text")
.apply { addListener { _, oldVal, newVal ->
// business logic...
} }
}

But you can of course factor out business logic and let other classes connect to the viewmodel for that
purpose:
val vm = ... // somehow fetch MyViewModel
vm.text1Property.addListener { _, oldVal, newVal ->
// business logic...
}

One-Way and Two-Way Bindings

Using properties and bindings makes it astonishingly easy to bind one UI control to another. Consider
a slider controlling a circle’s radius. All that needs to be done is to bind the slider’s valueProperty
to the circle’s radius property:
...
val sl = Slider(0.0,30.0,20.0)
val circ = Circle().apply {
radiusProperty().bindBidirectional(
sl.valueProperty())
}

val root = GridPane().apply {


add( sl, 0,0)
add( circ, 1,0)
}
...

Without further notice we thus far used


prop1.bindBidirectional(prop2)

to connect properties to each other. You might have guessed that there is also an unidirectional binding.
In fact there is, and in order to use it you just have to write
prop1.bind(prop2) // unidirectional!

The main difference between unidirectional and bidirectional binding is, that with the former
variant changes from prop1 get propagated to prop2 and vice versa, while in prop1.bind(
prop2 ) changes from prop2 get propagated to prop1, but not the other way round. This is
important for user input controls like text edit fields, which should reflect changes in the underlying
property, but must of course propagate user input to the program as well:
val text1Property = SimpleStringProperty("Some text")
val text1 = TextField().apply{
textProperty().bindBidirectional(text1Property)
One-Way and Two-Way Bindings 23

// a change in text1Property must propagate to the


// view:
text1Property.set("New text") // shown on UI

// after user input, the text1Property must have a


// new value (maybe inside a change listener):
val newVal = text1Property.get()

For readonly controls like labels, user input is not possible, so an unidirectional binding suffices:
val text1Property = SimpleStringProperty("Some text")
val lab1 = Label().apply{
textProperty().bind(text1Property)
}

// a change in text1Property must propagate to the


// view:
text1Property.set("New text") // shown on UI

So then why not always use bidirectional bindings? First of all, bidirectional bindings sometimes
introduce overly complex data flows exhibiting unexpected behavior. Second, in unidirectional
bindings you can replace properties by binding expressions. For example, what if in
...
val sl = Slider(0.0,30.0,20.0)
val circ = Circle().apply {
radiusProperty().bind(
sl.valueProperty())
}
...

we want to change the slider range to 0.0 . . . 100.0, but leaving the circle radius range at 0.0 . . . 30.0?
For that we obviously need a way to multiply the property by 0.3 This is possible, and actually it is
easy:
...
val sl = Slider(0.0,100.0,20.0)
val circ = Circle().apply {
radiusProperty().bind(
sl.valueProperty().multiply(0.3))
}
...

Such expressions like


doubleProp.multiply(0.3)
doubleProp.multiply(otherDoubleProp)
doubleProp.add(0.3)
doubleProp.minus(0.3)
doubleProp.divide(0.3)
intProp.multiply(3)
intProp.add(otherIntProp)
stringProp.concat(otherStringProp)
...

get called binding expressions, and you can use them as a parameter to bind(), provided the type
matches. You cannot use them for bidirectional bindings, because in a + b c you can recompute c if
a or b changes, but in a + b .← c you cannot reliably recompute a and b, if c changes.
24 2 Properties

The following list shows an overview of all binding expressions. Note that a number property (Dou-
bleProperty, FloatProperty, LongProperty, IntegerProperty) is also an ObservableNumberValue. Any
property is an ObservableValue. A StringProperty is an ObservableStringValue. A BooleanProperty
is an ObservableBooleanValue.

– DoubleExpression
add(Double | Float | Long | Int | ObservableNumberValue)
.→DoubleExpression

subtract(Double | Float | Long | Int | ObservableNumberValue)


.→DoubleExpression

multiply(Double | Float | Long | Int | ObservableNumberValue)


.→DoubleExpression

divide(Double | Float | Long | Int | ObservableNumberValue)


.→DoubleExpression

negate()
.→DoubleExpression

asString(), asString(Format), asString(Locale,Format)


.→StringExpression

greaterThan(...) (same as add())


.→BooleanExpression

greaterThanOrEqualTo(...) (same as add())


.→BooleanExpression

lessThan(...) (same as add())


.→BooleanExpression

lessThanOrEqualTo(...) (same as add())


.→BooleanExpression

isEqualTo(Double | Float | Long | Int | ObservableNumberValue, double epsilon)


.→BooleanExpression

isNotEqualTo(Double | Float | Long | Int | ObservableNumberValue, double epsilon)


.→BooleanExpression

– FloatExpression
add(), subtract(), multiply(), divide()
Same as for DoubleExpression, but returns
a FloatExpression if the other operand
does not correspond to a Double
negate()
.→FloatExpression

asString(), greaterThan(), greaterThanOrEqualTo(), lessThan(),


lessThanOrEqualTo(), isEqualTo(), isNotEqualTo()
Same as for DoubleExpression
– LongExpression
add(), subtract(), multiply(), divide()
Same as for DoubleExpression, but returns
a LongExpression if the other operand does not
correspond to a Float or Double, in which case
a FloatExpression or DoubleExpression gets
returned, respectively.
negate()
One-Way and Two-Way Bindings 25

.→LongExpression

asString(), greaterThan(), greaterThanOrEqualTo(), lessThan(),


lessThanOrEqualTo(), isEqualTo(), isNotEqualTo()
Same as for DoubleExpression, plus variants
isEqualTo(Int | Long), isNotEqualTo(Int | Long)
– IntegerExpression
add(), subtract(), multiply(), divide()
Same as for DoubleExpression, but returns an
IntegerExpression if the other operand does not
correspond to a Long, Float or Double, in which
case a LongExpression, FloatExpression or
DoubleExpression gets returned, respectively.
negate()
.→IntegerExpression

asString(), greaterThan(), greaterThanOrEqualTo(),


lessThan(), lessThanOrEqualTo(),
isEqualTo(), isNotEqualTo()
Same as for LongExpression
– StringExpression
concat(ObservableValue)
.→StringExpression

concat(Object)
.→StringExpression, but does not update if the

parameter operand changes


greaterThan(String | ObservableStringValue)
.→BooleanExpression

greaterThanOrEqualTo(String | ObservableStringValue)
.→BooleanExpression

lessThan(String | ObservableStringValue)
.→BooleanExpression

lessThanOrEqualTo(String | ObservableStringValue)
.→BooleanExpression

isEqualTo(String | ObservableStringValue)
.→BooleanExpression

isNotEqualTo(String | ObservableStringValue)
.→BooleanExpression

isEmpty(), isNotEmpty(), isNull(), isNotNull()


.→BooleanExpression

length()
.→IntegerExpression

– BooleanExpression
and(ObservableBooleanValue)
.→BooleanExpression

or(ObservableBooleanValue)
.→BooleanExpression

not()
.→BooleanExpression
26 2 Properties

asString()
.→StringExpression

isEqualTo(ObservableBooleanValue),
isNotEqualTo(ObservableBooleanValue)
.→BooleanExpression

Custom Bindings

Sometimes the binding expressions described in the previous section do not match our needs. In this
case the various static methods from the Bindings class (package javafx.beans.binding)
provide invaluable help. Especially the createObjectBinding() method is really powerful and
can be used to create almost any binding you might think of.
As an example consider a Slider bound to a DoubleProperty via bidirectional binding:
val prop = SimpleDoubleProperty()
// <- could go to ViewModel
val sl2 = Slider(0.0,30.0,20.0).apply{
valueProperty().bindBidirectional(prop)
}

Because the binding is bidirectional, a change of the property’s value would reflect in the slider’s
elongation and vice versa. The property could also go to a ViewModel, where it can be managed by
some data storage, or where other business logic can happen. Back in the view layer, we want the
property to connect to a circle, controlling its fill color. This can be accomplished by a binding object:
val colorBinding:ObservableValue<Color> =
Bindings.createObjectBinding( { ->
Color.color(0.0,0.0,0.0+prop.getValue()/30.0)
}, prop)

which finally can be connected to the circle:


val circ2 = Circle().apply {
radiusProperty().set(20.0)
fillProperty().bind(colorBinding)
}

You can see that inside Bindings.createObjectBinding() any kind of object can be created.
It could just as well be another Double object, using some arbitrary formula.

Note The Bindings class contains many more static helper functions for various binding creations
and calculations. See https://openjfx.io/javadoc/19/javafx.base/javafx/beans/binding/Bindings.html
for details.

About Observable Collections

Java and Kotlin collections lack one important feature needed for frontend development: they have
no built-in mechanism to tell interested parties about additions, changes, or removal of elements. For
this reason JavaFX uses its own collection variants: ObservableSet, ObservableList, and
ObservableMap, all inside package javafx.collections (module javafx.base).
Such observable collections play a very important role throughout JavaFX. Apart from list views,
table views and tree views, there are many more classes that use or return observable collections.
About Observable Collections 27

In this section we talk about list views, just to give you some primary insight into how observable
collections are used inside JavaFX. At this point we don’t investigate such collection related views in
a sound fashion, though. This is left for a later chapter.
First we need to know how to create observable collections. If you look at the API documentation
of ObservableSet, ObservableList or ObservableMap, you can easily see that these are
interfaces. So we feel tempted to look for classes implementing the interfaces. However, there seem
to be no obvious candidates for that, so the question arises: how can we get instances of an observable
set, list or map? The designers of JavaFX decided to provide a factory class for that. This class is
called FXCollections, and you can find it in the same package as the interfaces, javafx.-
collections. The procedure goes as follows:
// Creating empty observable collections. String and
// Int as type parameters are only examples - use
// your own.
val s1 = FXCollections.emptyObservableSet<String>()
val l1 = FXCollections.emptyObservableList<String>()
val m1 = FXCollections.emptyObservableMap<Int,String>()

// Creating observable collections given elements.


// Any number of elements of any single type is allowed.
val s2 = FXCollections.observableSet(1,2,3)
val l2 = FXCollections.observableArrayList(1,2,3)

// Creating observable collections given standard


// collections.
val s3 = FXCollections.observableSet(
mutableSetOf(1,2,3))
val l3 = FXCollections.observableSet(
mutableListOf(1,2,3))
val m3 = FXCollections.observableMap(
mutableMapOf(1 to "a", 2 to "b", 3 to "c"))

Class FXCollections provides many more static factory methods not shown here. For more
details see the API documentation at https://openjfx.io/javadoc/17/javafx.base/javafx/collections/
FXCollections.html.

Note There are also variants dealing with observable fixed size arrays instead of collections. We don’t
treat them in this book, but you can learn more about them here: https://openjfx.io/javadoc/17/javafx.
base/javafx/collections/ObservableArray.html, https://openjfx.io/javadoc/17/javafx.base/javafx/collec
tions/ObservableFloatArray.html and https://openjfx.io/javadoc/17/javafx.base/javafx/collections/Obs
ervableIntegerArray.html

Given an observable collection, for example an ObservableList, it is easy to implement


controls like for example a ListView:
val l = FXCollections.observableArrayList(
"Apple","Peach","Banana")
val listView = ListView(l)
val btn = Button("Change it"){
l.set(1, System.currentTimeMillis().toString())
}

val gp = GridPane().apply {
padding = Insets(5.0)
hgap = 5.0
add( listView, 0,0)
28 2 Properties

add( btn, 0,1)


}

// add gp to the scene...

You can see from this example, that for altering the view contents we don’t have to talk to the
ListView instance. Instead we directly address the observable collection, thus making it easy to
extract the view data model to a different application layer, like for example a ViewModel.
In case we want to react to changes in the observable collection, which could for example happen if
the user entered data into a view that has been made editable beforehand, we have to install a change
listener to the collection. This is not an easy task, because sets, lists and maps behave differently
if elements get added, replaced, removed or shuffled around, and we have to take care of several
elements changing at once by some operation.
The easiest case is a listener for an observable set. You register it via
val os:ObservableSet<Int> = ... // or whatever type
val cl = ... (make a SetChangeListener<Int>)
os.addListener(cl)

Since a SetChangeListener has a single method interface (SAM = Single Abstract Method), we
can also directly use a lambda construct as seen in the following example:
val s3 = FXCollections.observableSet(
mutableSetOf(1,2,3))

s3.addListener { chg:SetChangeListener.Change<out Int> ->


if (chg.wasAdded()) {
println("Added to set: " + chg.elementAdded)
} else if (chg.wasRemoved()) {
println("Removed from set: " + chg.elementRemoved)
}
println("Set after the change: " + chg.set)
}
s3.add(4)
s3.remove(2)

You can see that the listener only tells about single elements being added or removed. For bulk
operations like .addAll(...) the listener simply gets invoked several times.
Just a little more complex are listeners for ObservableMap instances. We need to be informed
about the addition or removal of key/value pairs, but also about just a value change for a given key:
val m3 = FXCollections.observableMap(
mutableMapOf(1 to "a", 2 to "b", 3 to "c"))

m3.addListener { chg:
MapChangeListener.Change<out Int,out String> ->
if (chg.wasRemoved() && chg.wasAdded()) {
println("Replaced in map: (${chg.key}, "+
"${chg.valueRemoved} -> ${chg.valueAdded})")
} else {
if (chg.wasRemoved()) {
println("Removed from map: (${chg.key}, "+
"${chg.valueRemoved})")
} else if (chg.wasAdded()) {
println("Added to map: (${chg.key}, "+
"${chg.valueAdded})")
}
}
}
About Observable Collections 29

m3[4] = "d" // or: m3.put(4,"d")


m3.remove(2)
m3[1] = "x" // or: m3.put(1,"x")

The most important use case of observed collections are observed lists. This is because for ListView
and TableView nodes what exactly is needed are observable lists to hold the data. Not surprisingly,
list change listeners thus are rather elaborated. The current implementation allows for detecting:

. Permutation of elements inside a range.


. Update of elements inside a range.
. Replacement of elements inside a range.
. Removal of elements inside a range.
. Insertion of one or more elements.

Also, contrary to the other listeners described above, the change object provides an iterator you
have to loop through to fetch all changes. The following listing shows an example:
val l3 = FXCollections.observableList(
mutableListOf(1,2,3))

l3.addListener( { chg:
ListChangeListener.Change<out Int> ->
while (chg.next()) {
if (chg.wasPermutated()) {
println("Permutated: " + (chg.from..chg.to-1))
(chg.from..chg.to-1).forEach{ i ->
val newIndex = chg.getPermutation(i)
println("index[${i}] moved "+
"to index[${newIndex}]")
}
} else if (chg.wasUpdated()) {
println("Updated: " + (chg.from..chg.to-1))
println("Updated elements: " + chg.list.
subList(chg.from, chg.to))
} else if (chg.wasReplaced()) {
println("Replaced: " + (chg.from..chg.to-1))
println("Removed Size: " + chg.removedSize)
println("Removed List: " + chg.removed)
println("Added Size: " + chg.addedSize)
println("Added List: " + chg.addedSubList)
} else if (chg.wasRemoved()) {
println("Removed: " + (chg.from..chg.to-1))
println("Removed Size: " + chg.removedSize)
println("Removed List: " + chg.removed)
} else if (chg.wasAdded()) {
println("Added: " + (chg.from..chg.to-1))
println("Added Size: " + chg.addedSize)
println("Added List: " + chg.addedSubList)
}
}
})
l3.addAll(4,5,6)
l3.removeAt(2)
Random documents with unrelated
content Scribd suggests to you:
devant euls. Et conmenchièrent li archier, qui estoient entré en ces
estages, à traire fortement à ceuls qui se tenoient as deffenses; et
traioient si roit et si ouniement que à painnes ne se osoit nuls
amoustrer, se il n’estoit trop fort paveschiés. Entre ces deus
bierefrois qui estoient arestés devant les murs, avoit deus cens
compagnons à tout hauiaus et grans pils de fier pour effondrer le
mur; et jà en avoient des pières assés ostées et rompues, car li
archier qui estoient hault ens ès estages, les deffendoient de ject et
de tret. Fº 101.
P. 81, l. 26: cent.—Mss. A 20 à 22: deux cens. Fº 177 vº.
P. 82, l. 7: haviaus.—Mss. A 15 à 17, 20 à 22: hoiaux, hoyaux.
Fº 123.—Mss. A 23 à 29: houyaulx. Fº 139.
P. 82, l. 8: voir Sup. var. (n. d. t.)

P. 82, l. 10: reparoient.—Mss. A 1 à 7, 11 à 14, 18, 19: repairoient.


Fº 121.—Ms. A 8: rapparoient. Fº 110 vº.—Mss. A 15 à 17:
apparoient. Fº 123.
P. 82, l. 19: le baron de Stanfort.—Ms. B 6: messire Alixandre de
Caumont. Fº 264.

§ 229. P. 82, l. 27: Quant messires.—Ms. d’Amiens: Or vous diray


de monseigneur Agoth des Baux quel cose il fist. Entroes que on
parlementoit et alloit de l’un à l’autre, il se retraist et ses
compaignons dedens le castiel de le Riolle, qui siet à l’un dez léz de
le ville, et y mist grant fuison de pourveanches pour lui tenir un grant
tamps; et quant il fu dedens et chil ossi que il y veut atraire, il avalla
le pont et abaissa le restel et dist bien que il ne se renderoit mies
enssi. Fº 84 vº.
—Ms. de Rome: Par cel estat et asaut euist esté la ville de la Riole
prise, et de fait il ni avoit nul retour, quant li bourgois de la ville
vinrent à mesire Agoth, lor chapitainne, qui point ne s’effreoit de
cose que il veist, et li dissent: «Sire, aiiés avis de nous. Se ces
Englois nous prendent de force, nous sonmes tout mort et nostre
ville courue.»—«Et quel cose volés vous que j’en face?» respondi li
chevaliers.—«Nous volons que vous faites cesser l’asaut et que
vous tretiiés à euls, par quoi nous demorons en paix, car il ne nous
apert confort de nul costé; et se ce ne volés faire, retraiiés vous
dedens le chastiel: il est fors assés, et faites vostre gerre à par vous,
car nous ferons fin à la nostre.» Qant mesires Agos les entendi, si
lor respondi et dist: «Biaus signeurs, grans merchis, vous me
presentés courtoisie, et voirement me retrairai je ou chastiel. Je ne
me voel pas encores rendre.» Adonc se departi li dis mesires Aghos
de lor compagnie, et retraii tous les compagnons de sa carge, et li
bourgois se missent en trettiet deviers le conte Derbi. Qant li contes
Derbi vei que li bourgois de la Riole trettoient, et li chevaliers ne
s’ensonnioit point de lors trettiés, si demanda: «Et où est vostre
capitainne? Pourquoi ne vient il avant en non Dieu?»—«Sire, il est
retrais dedens le chastiel, et ne voelt point estre à nostres
trettiés.»—«Voires, respondi li contes. Voelt il donc faire sa gerre à
par lui? Jamais n’en auera si bon marchié que il euist eu avoecques
vous; et puis que nous avons la ville, nous auerons le chastiel, quoi
que il doie couster.» Fº 101.

§ 250. P. 84, l. 9: Ensi eut.—Ms. d’Amiens: Vous avés bien oy le


tretiet et le composition de chiaux de le Riolle et dou comte Derbi, et
coumment li ville se rendi. Quant li seigneur d’Engleterre virent que
messires Agos s’estoit retrais ou fort, si dissent bien que il n’avoient
riens fait se il laissoient le castiel derrierre, car tantost aroit
reconcquis le ville. Si eurent consseil de l’asegier et de l’assaillir et
de non partir de là, si l’aroient ou par forche ou par amours. Si
l’environnèrent de tous léz et l’assaillirent par pluisseurs foix, mais
peu y fissent, car li castiaux est fors et haux, et si siet sus vive roche.
Endementroex que li comtez Derbi et li baron d’Engleterre et de
Gascoigne seoient devant le fort castiel de le Riolle, vint uns
honnestez anchiens homs, nés et demourans en le Riolle, à
monseigneur Gautier de Mauni, et s’aquinta de lui et li dist: «Sire,
quel grace feriés vous à celui qui vous menroit en l’eglise et ou
propre lieu où li corps de monseigneur vostre père, dont Dieux ait
l’amme, gist et fu jadis ensevellis?» Messires Gautiers leva adonc le
teste et regarda le preudomme, et li dist: «En nom Dieu, amis, je li
feroie grant prouffit.»—«Or en vennés avoecq moy, dist li preudoms,
et je vous y menray droitement, car je fui là au jour qu’il y fu mis et
vous ferai tout sceur de ce que je vous recorde.» Li sires de Mauni,
qui volentiers entendi à ces parolles, se parti de son hostel et s’en
vint avoecques ses gens et le preudomme là où il le mena: che fu en
une eglise moult anchienne qui siet dedens le Riolle; et dedens une
petitte cappelle avoit un marbre à vosure rudement tailliet. «Sire, dist
li preudoms, dessous ce marbre fu ensepvelis messires vos pèrez.
Et faittez lever le tonbel: je croy que en l’autre qui se reclot sus, vous
trouverés escript le nom de lui et le terme qu’il y fu mis.» Adonc
messires Gautiers le fist tantost par ses escuiers ouvrir, et trouva en
verité tout ce que li preudoms li avoit dit. Or vous diray pourquoy ne
coumment li chevaliers fu là ensepvelis, li pères à monseigneur de
Mauny qui estoit de Haynnau. Fos 84 vº et 85.
—Ms. de Rome: Chils trettiés se passa, et orent les Englois la ville
de la Riole, et puis asegièrent le chastiel, liquels est biaus et fors, et
mesire Agot des Baus dedens, et tous ses compagnons qui estoient
Prouvenciel. Et fu li sièges lons et grans, car li chastiaus pour lors
estoit de bonne garde et belle deffense, et si i avoit dedens
chevaliers d’onnour et de vaillance. Or vous recorderai de une
aventure que il avint là à mesire Gautier de Mauni, entrues que il
seoient devant le chastiel de la Riole. Fº 101 vº.

§ 231. P. 85, l. 18: Il y eut.—Ms. d’Amiens: Jadis il y eut un


evesque à Cambray, qui fu gascons et de chiaux de Mirepois en
Gascoingne. Or avint que de son tamps il y eut un très grant
behours et tournoy dehors le chité de Cambray. Là par usage il se
font et feroient, se ungs en y avoit. A che tournoy eut bien cinq cens
chevaliers tournians. Et là y eut li evesquez de Cambray un sien
nepveult, jone chevalier tourniant, richement armés et montés. Chilx
s’adrecha à monseigneur le Borgne de Mauni, père à monseigneur
Gautier et à ses frèrez, qui estoit fors chevaliers, rades et bien
tournyans, et mania tellement le chevalier de Mirepois que oncques
depuis n’eut santé, mès morut: dont li evesques et tous ses linaigez
furent grandement courouchiéz, car il estoit haux homs et gentilz et
riches homs durement. Ceste cose passa; amendisses n’en furent
oncques faittez ne requisez, pour ce que en esbatement de tournoy
et de telz fais d’armes la cose estoit avenue.
Avint un grant tamps apriès que il vint en devotion à monseigneur
le Borgne de Mauni que d’aller en pellerinage à Saint Jaqueme de
Galisse. Si se parti de Haynnau en celle entente; sen allée fu sceue,
et li linages de Mirepoix emfourmés que chilx qui avoit ochis leur
cousin, passoit parmy leur pays. Dont bastirent il et ordonnèrent
pluisseurs aghais sour lui, et le trouvèrent un jour assés priès de le
Riolle. Si l’asaillirent et ochirent et navrèrent mout vilainnement ses
varléz, de quoy li doi en morurent. Apriès che qu’il fu mors, chil de le
Riolle l’alèrent querre et prissent ses chevaux et sen aroy et fissent
de tout argent; et l’ensepvelirent en sainte terre, pour tant qu’il estoit
chevaliers et pellerins, et li fissent son obsèque. Depuis ceste cose
demoura, car si enffant estoient jone au jour qu’il fu ochis. Si
s’avanchièrent depuis par armes et vinrent en eage d’omme, et par
especial messires Gautiers, enssi que vous avés oy comment il s’est
fès et avanchiés. De quoy, quant il fu venus en Gascoingne avoecq
le comte Derbi, bien li souvint de chiaux de Mirepoix qui avoient
ochis son père, dont il le contrevenga assés bien; car il leur ardi
touttez leurs terrez et en mist pluisseurs à fin, ne oncques n’en veult
nul prendre à raenchon, ne à le bataille de Bregerach, ne
d’Auberoche, ne d’ailleurs.
Quant li sirez de Mauni eut congnut clerement que li preudoms li
avoit dit verité, se li fist tantost donner cent escus et deffouir les os
de son père et enbausoummer et mettre en un bel sarqu, et puis
cargier sus un sonmier. Et prist deus frères meneurs et leur fist
delivrer or et argent, et fist ces [os] raporter à Vallenchiennes à Saint
Franchois, c’on dist as Cordeliers; et là de rechief il les fist mettre et
ensepvelir en une cappelle assés priès dou coer. Fº 85.
—Ms. de Rome: Il i eut jadis un evesque à Cambrai qui fu
Gascons, dou linage de ceuls de Beu et de Mirepois. Avint que dou
temps cesti evesque uns très grans tournois se fist devant Cambrai,
et i furent bien cinq cens chevaliers tournoians. Et là ot li dis
evesques un sien neveut, jone chevalier tourniant, ricement armé et
monté. Chils s’adreça à mesire le Borgne de Mauni, père à mesire
Gautier et à ses frères, liquels fu en son temps chevaliers durs, fors,
rades et bien tournoians. Et fu li jones chevaliers gascons tellement
menés et batus que onques depuis il not santé, mais morut. Li sires
de Mauni, qui riens n’i pensoit, ne au penser apertenoit selonch
l’estat et l’ordenance d’armes et l’usage des tournois, ne sai qans
ans apriès, il li prist devotion d’aler ou voiage de Saint Jaqueme en
Galise, et i ala et prist un aultre cemin au retour que il n’euist alé. Et
entendi que li contes de Valois, frères jadis au biau roi Phelippe et
pères à madame de Valois qui fenme fu au conte Guillaume de
Hainnau, tenoit son siège devant la Riole, car pour ces jours elle
estoit englesce; et faisoit guerre li biaus rois Phelippes as Anglois en
Giane pour auqunes disentions de terres, les quelles estoient en
debat des deus rois ensamble.
Chils sires de Mauni vint veoir le conte de Valois qui li fist bonne
chière. Au departement, il li demanda se il voloit riens mander ne
escrire en Hainnau à sa fille. Li contes de Valois dist oil et escripsi. Li
sires de Mauni, nonmé le Borgne, prist congiet et se departi. En cel
estat que il fu là et sejourna un jour, il fu avisés dou linage de ceuls
de Mirepois et de Beu et dou jone chevalier qui mors avoit esté, ensi
que on disoit, par sa coupe; et l’atendirent au dehors des logeis et
l’asallirent et ocirent: dont li contes de Valois fu trop durement
courouchiés et en calenga tout le linage et mist en termes que il
l’avoient mourdrit. Et en furent en grant dangier de lors corps tout
chil qui fait l’avoient, et encores euissent il esté en plus grant, se li
enfant les euissent poursieuvis par parlement de Paris, quoi il
mesissent en termes que il l’avoient fait de bonne gerre; mais, pour
lors, messires Gautiers de Mauni et si frère estoient jone, et aussi
vous savés que, qant il vinrent en congnisance d’onme, la guerre
s’esmeut entre France et Hainnau, et depuis entre France et
Engleterre, par quoi li enfant dou dit Borgne de Mauni n’eurent nulle
action de proceder en plait à l’encontre des Gascons, fors à l’espée,
car il tinrent l’opinion le roi d’Engleterre.
Au retourner au pourpos de la matère desus dite, li contes de
Valois, pour l’amour de gentillèce, fist ensepvelir le dit Borgne de
Mauni en une eglise, au dehors de la ville de la Riole, et li fist faire
son obsèque. Trop bien savoit tout ce messires Gautiers de Mauni,
que il estoit mis et ensepvelis en terre sainte en la Riole ou là priès,
mais il couvenoit que il fesist enqueste à ceuls dou pais, où on l’avoit
mis. Si le fist et tant en enquist que li anciien homme, qui avoient
esté de ce temps, li ensengnièrent et le menèrent droit sus le lieu où
il avoit esté ensepvelis. Se le fist deffouir et prendre les os et mettre
en un sarqu et aporter en l’eglise des Cordeliers, que on dist Saint
François, à Valenchiennes, et de rechief là ensepvelir moult
reveranment, et encores en voit on les ensengnes. Fos 101 et 102.
P. 85, l. 19: de Beu.—Mss. A 20 à 22: du Beu. Fº 179.
P. 86, l. 10: englesce.—Ms. B 6: mais les Franchois le conquirent,
quant il y eulrent bien sis ung an. Fº 265.
P. 86, l. 15: ses lettres.—Mss. A 20 à 22: comment il estoit au dit
conte, car le conte de Vallois estoit là comme roy de France. Fº 179.
P. 86, l. 22: retet.—Mss. A 1 à 7, 11 à 14, 18 à 33: soupeçonnez.
Fº 122 vº.—Ms. A 8: encoulpez. Fº 111 vº.—Mss. A 15 à 17:
arrestez. Fº 124.
P. 86, l. 32: avant.—Les mss. A 1 à 6, 11 à 14, 18, 19 ajoutent: et
si certainement. Fº 122 vº.
P. 87, l. 17: ensepelir.—Ms. B 6: delés madame sa femme, en
l’eglise des Cordeliers. Fº 265.

§ 232. P. 87, l. 22: Or revenrons.—Ms. d’Amiens: Or vous


recorderai dou castiel de la Riolle qui se tint un grant temps contre
les Englès. Et trop bien le deffendi messires Agos des Baux as
Englès, et se tint depuis cinq sepmainnez que la ville eut estet
rendue. Finablement li chevaliers perchut bien que li comtez Derbi
ne se partiroit point si aroit le castiel à se vollenté, et d’autre part il
ne veoit nul secours appairant. Si se laissa encheoir en tretiet parmy
tant que il s’en pooit aller et tout le sien, et pooient porter et mener
tout ce qui leur estoit. Li comtez Derbi leur acorda; il se partirent ensi
que je vous compte et rendirent le castel: dont li Englèz eurent grant
joie, car il estoient tout tannet de tant là sejourner. Et quant li comtes
Derbi l’eut, si le fist remparer, garnir et repourveir, et y mist bon
castellain, un chevalier d’Engleterre qui s’appielloit messire Richart
de Lantonne. Fº 85.
—Ms. de Rome: Tant tint li contes Derbi son siège devant le
chastiel de la Riole, que messires Agos des Baus falli à ses
ententes, car il quidoit que poissance de par le roi de France deuist
là venir pour lever le siège, mais non fist; car ensi que je vous ai jà
dit, li orgoels et la negligense estoient si grandes en l’ostel dou roi
Phelippe, pour ce temps, que on ne faisoit compte de tels coses, ne
de l’aler, ne de l’envoiier. Et pour le temps d’adonc, li saudoiier
estoient si mal paiiet en France que nuls estrangiers ne s’y traioit
volentiers pour demander saudées, ne ossi parellement chil dou
roiaulme. Encores estoient li peril si grant, pour les nobles dou
roiaulme qui de la gerre se ensonnioient, que, qant il avoient
l’aventure de perdre une journée à l’encontre de lors ennemis,
renonmée publique parmi le roiaume de France couroit sur euls, que
il estoient traite, et que par traison il avoient perdu la journée. Et
mieuls lor valoit à morir sus la place que estre pris ne retourner; car
qant il retournoient, il estoient pendu conme traite. Et par tels
violenses et amises de traisons avinrent depuis moult de mesciés
ens ou roiaulme de France et par tous ses menbres, ainsi que vous
orés recorder avant en l’istore.
Qant messires Agos des Baus vei que nuls secours ne li venroit
de France, et si amenrissoient grandement ses pourveances, il
traitta deviers ces signeurs d’Engleterre. Trettiés se porta que ils et li
sien se departirent sauvement, et en pooient porter ce qui lour estoit,
voires seullement devant euls et non autrement; si se departirent et
se traissent viers Toulouse. Et de là mesires Agos s’en retourna en
Prouvence et n’osa venir en France, tant doubta il les crueuses
justices que on i faisoit à petite oqison. Si se tint en Prouvence et
sus le sien, et bien vei et senti que les envies dou roiaulme de
France estoient trop grandes et que il n’i faisoit nul. Fº 102.
P. 87, l. 26: tour.—Mss. A 1 à 6, 23 à 33: court. Fº 122 vº.
P. 87, l. 27: chaingles.—Mss. A 20 à 22: sangles. Fº 180.
P. 88, l. 1: Agos.—Mss. A 15 à 17: Ragot. Fº 124 vº.
P. 88, l. 1: des Baus.—Mss. A 8, 18 à 22: des Vauls. Fº 112.—
Mss. A 23 à 33: des Bans. Fº 140 vº.
P. 88, l. 24: parler au conte Derbi.—Ms. B 6: Sy entra en traitiet
devers les chevaliers du conte tels que messire Richart de Stampfort
et messire Gautier de Mauny: le traitiet se fist par le moien de
messire Alixandre de Caumont. Fº 266.
P. 90, l. 28: le Riolle.—Ms. B 6: Ensy fut la Roille pour che tamps
englesse, et le demora depuis plus de vingt sept ans. Fº 266.

§ 233. P. 91, l. 1: Apriès che.—Ms. d’Amiens: Apriès ce que li


comtez Derbi eut se volenté et fu venus à sen entente de le Riolle,
de le ville et dou castiel, il se parti et toutte sen host, et chevaucha
vers Montpesas, ossi un très fort et biel castiel. Si le concquist par
assaut et par eschiellement, mès mout li cousta de ses archiers,
ainchois qu’il l’ewist. Si y laissa dedens de ses gens et le rafreschi
de pourveanches, puis s’en parti et se traist deviers le ville et le fort
castiel de Mauron. Et quant il furent là venu, il l’assaillirent fortement,
mais il ne le peurent avoir par leur assault; si le gaegnièrent
l’endemain par enghien et par le sens d’un gentil homme dou pays
de Gascoingne, que on clamoit Alixandrez, seigneur de Chaumont.
Car li coens Derbi se desloga et fist samblant d’aller autre part, et se
parti de là à tout sen grant host, et laissa un petit de gens devant le
ville avoecq le conte de Kenfort. Quant chil de la ville et li saudoier
virent si peu de leurs ennemis devant le ville, il lez quidièrent tantost
desconfire et prendre; si yssirent hors pour combattre à ces Englèz.
Quant li Englès les virent venir, il se traissent arrière et fissent
samblant de fuir, et chils lez chachièrent loing enssus de leur ville.
Qant li comtes Derbi vit che, qui estoit embusciés assés priès de là,
il sailli avant et se mist entre lez saudoiiers et le ville, et y entra par
force. Et furent li plus de chiaux qui dehors estoient, tous ochis.
Ensi par cel enghien fu li fors castiaux et la ville de Mauron
gaegnie, et li bourgois de le ville pris et ranchonnet. Apriès fu prise
ossi par enghien et soutilité le grosse ville que on clainme
Villefranche, et fu toutte courue et robée. Depuis le fist li dis comtez
remparer et regarnir et pourveir de tout chou qu’il y besongnoit, et y
laissa un bon chevalier englès que on clammoit monseigneur
Thomas Kok. Ensi chevauchoit li comtes Derbi le pays d’un lés et
d’autre, et n’estoit nulx qui se mesist au devant. Et conqueroient ses
gens villes et castiaux et prendoient gens et lez rançonnoient, et n’y
avoit si petit en leur host qui ne fuist tous cargiés d’or et d’argent.
Fº 85.
—Ms. de Rome: Ensi eut li contes Derbi la ville et le chastiel de la
Riole et le pourvei et rafresci de gens d’armes et d’archiers et de
pourveances, et i laissa messire Jehan de la Souce à chapitainne. Et
puis s’en departirent les Englois et ceminèrent deviers Montpesas.
Elle n’estoit fremée que de pallis. Si considerèrent chil qui dedens
estoient, la poissance des Englois, et conment il avoient pris plus
fortes villes que la lour ne fust vint fois. Si envoiièrent tretier deviers
le conte Derbi, avant que il parvenist à la ville, et se rendirent, salves
lors corps et lors biens. Et puis passèrent oultre, et vinrent devant
Villefrance en Agenois; elle se rendi tantos. Fº 102.
P. 91, l. 18-19: voir Sup. var. (n. d. t.)

P. 91, l. 23: Baucestre.—Mss. A 1 à 6: Lancastre. Fº 124.—Mss. A


7, 11 à 14, 18 à 33: Lancestre. Fº 118 vº.
P. 91, l. 25: Mauron.—Mss. A 1 à 6, 30 à 33: Manron. Fº 124.—
Ms. A 8: Marcion. Fº 112 vº.—Mss. A 15 à 17: Martron. Fº 125 vº.—
Mss. A 18, 19: Mauion. Fº 126 vº.—Ms. B 6: Manton. Fº 267.
P. 92, l. 17: voir Sup. var. (n. d. t.)

P. 92, l. 25: quatre cens.—Ms. B 6: cinq cens. Fº 268.


P. 93, l. 20: cent.—Ms. B 6: soixante. Fº 268.

§ 234. P. 93, l. 29: Quant li contes.—Ms. d’Amiens: Apriès ce que


li comtez Derbi eut fait se vollenté de Villefrance, il s’en ralla vers
Miremont, en raprochant le chité de Bourdiaux, qui est ungs très fors
castiaux et bien seant; si y fu trois jours devant; au quatrimme il se
rendi. Si le prist li comtez et le donna à un sien escuier que on
clammoit Jehan de Bristo. Apriès il prist le castiel que on claimme
Thonis, et apriès le fort castiel de Damassen, et puis se traist deviers
le chité d’Anghouloime et l’asega, mès elle fu assés tost rendue; si y
mist dedens grant fuisson de gens d’armes et d’archiers, pour le
garder, avoecq les bourgois. Quant li comtez eut ordonné de le chité
d’Anghouloime che que bon l’en sambla, il se traist par devant
Blaves qui est une très forte ville et où la rivière de Garonne l’enclot
par derière. Si y basti et mist le siège par devant. Et y sist un grant
temps et y fist livrer tamaint assault, mès peu y concquist; car la ville
estoit forte et bien garnie et pourveue de bonnes gens d’armez. Et
par especial, il y avoit deux chevaliers de Poito, vaillans hommez
durement, que li roys de Franche y avoit envoiiés, monseigneur
Guichart d’Angle et monseigneur Bouchikau, qui le gardèrent et
deffendirent si bien avoecq leurs compaignons que il n’y prissent nul
dammaige. Fº 85 vº.
—Ms. de Rome: Et puis s’en vinrent devant la ville de Blaves,
laquelle pour lors estoit françoise, et sciet à sept lieuves l’aige de la
Geronde de la cité priès de Bourdiaus, il n’i a que la rivière entre
deus. Si bastirent là les Englois lor siège, et dissent que point ne
s’en partiroient si l’auroient à lor volenté, se poisance de roi de
France ne venoit si grande que il ne peuissent contrester à
l’encontre. Tant furent les Englois devant Blaves que chil qui dedens
estoient, se tanèrent, car il estoient asegiet par terre et par la rivière
de la Geronde, laquelle bat et fiert as murs de la ville; si se tourna
englesce, et se missent en l’obeisance dou roi d’Engleterre. Ensi
eurent les Englois Blaves, dont il furent moult resjoy, car elle lor avoit
porté moult de contraire et portoit encores tous les jours, jusques à
tant que elle fu pour euls. Si i ordonna li contes Derbi, avant que il
s’en partesist, bon chapitainne, gens d’armes et archiers pour le
garder. Et puis ils et ses gens, petit à petit, rapasèrent as barges et à
bastiaus la rivière de la Geronde et retournèrent à Bourdiaus, et là
se tinrent et s’i rafresqirent. Et lor fu avis que, pour celle saison, il
avoient assés fait, et se tenroient là, jusques à tant que il oroient
aultres nouvelles. Si envoia li contes Derbi ses honmes par les
garnisons, tant pour entendre as lieus remparer, que pour garder les
frontières, et que nuls mauvais trettiés ne se fesist des villes et des
castiaus que conquis avoient as François. Nous nos soufferons un
petit à parler de euls, et parlerons d’aultres avenues qui avinrent en
France et en Flandre. Fº 102 vº.
P. 93, l. 30: Miremont.—Mss. A 15 à 17: Miraumont. Fº 126.
Voir aussi Sup. var. (n. d. t.)

P. 94, l. 1: voir Sup. var (n. d. t.)

P. 94, l. 4: Bristo.—Mss. A 7: Brisco. Fº 119.—Mss. A 15 à 17:


Briston. Fº 126.
P. 94, l. 5: Garone.—Ms. B 6: Geronde. Fº 269.
P. 94, l. 6: Thonins.—Mss. A 1 à 9, 18 à 33: Thonis. Fº 124 vº.—
Mss. A 11 à 14: Thours. Fº 119.—Mss. A 15 à 17: Channis. Fº 126.
P. 94, l. 6 et 7: Damasen.—Mss. A 1 à 6, 11 à 14, 18, 19:
Damensi. Fº 124 vº.—Mss. A 20 à 22: Damancy. Fº 182.—Ms. B 6:
Damasson en Angolesmois. Fº 269.
P. 94, l. 9: d’Angouloime.—Ms. B 6: Et ensy concqueroit le conte
Derby en la basse Gascongne chités, villes et chastieaulx, et faisoit
rendre à luy et mettre en l’obeysanche du roy d’Engleterre son
signeur. Et se ne ly alloit nul au devant; car, ensy que vous savés,
l’anée precedente tous les barons de Gascongne franchois avoient
esté mort ou pris devant Auberoche: pour coy nulle recouveranche
ne se povoit mettre sus ou pais des gentilz hommes, car encore
estoient le plus prisonniers as Englès qui ne se povoient armer.
Fº 269.
P. 94, l. 16: vingt quatre.—Ms. B 6: douze. Fº 270.
P. 94, l. 27: Blaives.—Mss. A 1 à 6, 20 à 29: Blanes, Blaines.
Fº 124 vº.—Mss. A 7 à 14: Blaves. Fº 119.—Mss. A 18, 19: Bleves.
Fº 127.—Mss. A 15 à 17: Blaives. Fº 126.
P. 94, l. 29: Guichart.—Mss. A 20 à 22: Richart. Fº 182 vº.
P. 94, l. 29: d’Angle.—Ms. A 8: d’Engle. Fº 119.
P. 95, l. 1: Rochewart.—Mss. A 1 à 6: Rouchechouart. Fº 124 vº.—
Ms. A 7: Rochouart. Fº 119.—Ms. A 8: Richechouart. Fº 113 vº.—
Mss. A 11 à 33: Rochechouart. Fº 119 vº.
P. 95, l. 3: Entrues.—Ms. B 6: Le siège pendant devant Blaves, le
conte de Kenfort à tout deux cens lances s’en vint devant Mirabiel et
courut le pays environ Ausnay et entra en Saintonge, et puis
retourna en l’ost et amena grant proie. Fº 271.
P. 95, l. 9: Mirabiel.—Mss. A 1 à 6: Mirebel. Fº 124 vº.—Mss. A 7 à
33: Mirabel. Fº 119 vº.
P. 95, l. 10: Ausnay.—Mss. A 15 à 17: Aunoy. Fº 126 vº.—Mss. A
20 à 22: Aulnay. Fº 182 vº.—Mss. A 23 à 29: Ansny. Fº 143.—Mss. A
30 à 33: Ausny. Fº 175.

§ 235. P. 95, l. 13: Ce siège pendant.—Ms. d’Amiens: Quant li


seigneur d’Engleterre eurent là sis un grant tamps, et que li yviers
les aprochoit, et que riens à Blaves ne faisoient, il se deslogièrent et
vinrent devant un castel que on claimme Bourch desoubs Blaves, et
l’assegièrent et y fissent pluisseurs assaux. En le fin tant l’assaillirent
que il le prissent et le rappareillièrent bien et fort, et y missent
dedens deux cens archiers pour le garder. Et en fissent castiellain un
bon escuier que on apelloit Jen Dancastre. Et puis rappassèrent la
Garone et s’en revinrent à Bourdiaux, che fu environ le Saint Michiel
l’an mil trois cens quarante cinq.
Au voir dire, moult furent honnerables et pourfitables ces deux
saisons pour le comte Derbi et ses gens. Et tant y gaegnièrent en
pluisseurs mannierrez que li plus povre en furent riche. Et ne
faisoient compte li varlet ne d’or ne d’argent, tant en estoient rempli.
Yaux revenu à Bourdiaux, il se departirent, et en alla chacuns en se
garnison. Et li comtez Derbi et messires Gautiers de Mauni se tinrent
à Bourdiaux. Fº 85 vº.
P. 95, l. 18: obligiet.—Les mss. A 1 à 6, 11 à 14, 18 à 22 ajoutent:
au roy d’Angleterre. Fº 125.
P. 95, l. 27: Norvich.—Mss. A 8, 9: Morvich. Fº 113 vº.—Mss. A 20
à 22: Norwich. Fº 183.
P. 96, l. 16 à 23: Or... devant.—Cet alinéa manque dans les mss.
A 23 à 33. Fº 143.
P. 96, l. 21 à 23: en celle... devant.—Mss. A 1 à 6: en celle mesme
saison et année. Fº 125.—Ms. A 8: en celle meisme saison et année
de devant. Fº 114.—Mss. A 11 à 14: en celle mesme année.
Fº 119 vº.—Mss. A 7, 18 à 22: en celle meisme anée et la saison
devant. Fº 119 vº.
P. 95 et 96: Ce siège... devant.—Le § 235 manque dans les mss.
A 15 à 17. Fº 126 vº.

§ 236. P. 96, l. 24: En ce tamps.—Ms. d’Amiens: En celle saison


eschei en le indination et haynne trop grandement dou roy Phelippe
de Franche ungs grans banerès de Normendie et de grant linage,
messire Ghodefroit de Harcourt. Et le couvint soudainnement wuidier
et partir hors dou royaumme de Franche; car se li roys l’ewist tenut,
il n’en ewist nient fait mains qu’il fist faire dou seigneur de Clichon et
des autrez qui furent decollet à Paris. Si se parti messires Godeffroix
au plus tost qu’il peult, et s’en vint en Braibant où il avoit belle
revenue; et si estoit li dus Jehans, ses cousins. Se le festia et le tint
ung tamps dallés lui. En le fin, il se parti et s’en alla en Engleterre
deviers le roy, qui le vit vollentiers et le retint tantost à une grant
cantitet de gens et de chevaux, et li donna belle terre et bonne pour
son estat et le fist de son consseil. Fº 86.
—Ms. de Rome: En che temps et en celle meisme saison eschei
en le indination et haine trop grandement dou roi de France, mesires
Godefrois de Harcourt, li uns des grans barons de toute la
Normendie, frères au conte de Harcourt et sires de Saint Saulveur le
Visconte et de pluisseurs villes en Normendie. Et ne vous sçai pas à
dire la cause pourquoi la haine vint, mais elle fu si grande que, se li
rois de France l’euist tenu en son aïr, il l’euist fait morir
honteusement. Et couvint le dit mesire Godefroi tapir et fuir et issir
dou roiaulme de France. Et ala en Engleterre deviers le roi
Edouwart, et se offri à lui et mist en obeisance, ensi conme messires
Robers d’Artois avoit fait jadis, ne nuls ne li pot onques faire sa paix.
Li rois d’Engleterre le rechut et le retint dalés lui, et li donna assés
pour tenir son estat. Fº 102 vº.
P. 96, l. 28: Harcourt.—Mss. A 11 à 14: par l’ennortement du sire
de Saint Sauveur le Viconte et de plusieurs seigneurs de
Normendie. Fº 120.
P. 96, l. 29: Saint Salveur.—Mss. A 1 à 33: Saint Sauveur. Fº 125.
P. 97, l. 1: et tout par amise et par envie.—Mss. A 11 à 14, 18 à
33: tout par envie. Fº 120.—Mss. A 15 à 17: par mauvaise envie.
Fº 126 vº.
P. 97, l. 10 et 15: voir Sup. var. (n. d. t.)

P. 97, l. 16 et 17: mès avoit... pourfis.—Mss. A 11 à 14: car le roy


avoit saisi toute la terre que le dit messire Geoffroy tenoit en la terre
de Constentin et en faisoit lever les prouffiz. Fº 120.
P. 97, l. 16: toute sa terre.—Mss. A 20 à 22: toutes ses terres.
Fº 183 vº.
P. 97, l. 20: priier.—Ms. B 6: Quant il eut là esté ung terme dalés le
duc son cousin, qui recheu l’avoit moult liement, il prist congiet et
vint en Flandres; et entra en mer à l’Escluse, et fist tant qu’il vint en
Engleterre devers le roy qui lui fist grant feste. Messires Godeffrois
s’acointa si bien du roy que le roy le retint de son ostel et de son
consail pour l’un des especiaulx, et lui donna cinq cens mars de
rente par an assigné moult bien en Engleterre. Fº 272.

§ 237. P. 97, l. 25: En ce temps.—Ms. d’Amiens: Or parlerons ung


petit dou roy d’Engleterre et de Jaquemon d’Artevelle, qui gouvrena
bien par l’espasse de neuf ans les Flammens; et en fu, ensi que
vous avés chydessus oy, si souverains que il y a eu en Flandrez peu
de comtez qui mieux aient eut les Flammens en leur vollenté de lui
tant qu’il dura. Chilx d’Artevelle estoit durement bien dou roy
d’Engleterre. Et le tenoit li roys mout à amour pour le grant prouffit
que il en atendoit, car d’Artevelle li proumetoit que il le feroit
seigneur de Flandrez et le donroit à son aisnet fil, et en feroit on une
ducé. Et sus ceste entension li roys englèz avoit fait ung grant
appareil de nés et de vaissiaux sus le Tamise, et mandéz grant
fuisson de barons et de chevaliers de son pays; et s’en devoit venir
jeuuer en Flandrez et y devoit amener son fil le jone prinche de
Gallez, et estoit jà meus, quant les nouvellez li vinrent que chil de
Gand, par leur outraige, avoient tuet che d’Artevelle, son grant amit.
Fº 85 vº.
—Ms. de Rome: En ce temps resgnoit encores ou pais de
Flandres, en grande prosperité et poissance, chils bourgois de
Gand, Jacquemes d’Artevelle, liquels tenoit à amour le roi
d’Engleterre, ce que il pooit, car tous jours se doubtoit il des
Flamens, car il les sentoit muables. A considerer raison, il acquist le
povre conclusion que il ot, ensi que je vous dirai. Il voloit de tous
poins deshireter de la conté de Flandres le conte Lois l’escachiet et
Lois de Male, son fil, et voloit le roi d’Engleterre metre en l’iretage de
Flandres. Et disoit chils Jaquemes d’Artevelle que on feroit de
Flandres une ducé, et en seroit dus li princes de Galles. Et sus cel
estat en ce temps, il fist venir le roi d’Engleterre, son chier compère,
à l’Escluse; et qant li rois fu là venus, point n’issi de ses vassiaus.
Les bonnes villes de Flandres, c’est à entendre les consauls,
l’alèrent veoir à l’Escluse et conjoir, et li offrirent tout le pais ouviert à
li et à ses gens à son conmandement; et li priièrent que il vosist venir
à Bruges et à Gaind, et que partout on li feroit bonne chière. Li rois,
en euls remerchiant, respondi à ce moult doucement et dist que,
pour l’heure, il n’estoit point venus pour descendre à terre. A toutes
ces paroles estoit chils Jaquemes d’Artevelle.
Assés tos apriès, se fist uns parlemens ens ou vassiel dou roi, qui
estoit moult grans et moult biaus, que on nonmoit Cristofle, et furent
là tous les consauls des bonnes villes de Flandres. Là promeut
Jaquemes d’Artevelle les paroles desus dittes et remoustra par
pluisseurs raisons, aournées de biaus langage, que cose utille estoit
de recevoir le prince de Galles à signeur, et que de Flandres on
feroit une ducée, et se tenroit li dis dus et princes ou pais et
gouvreneroit la terre et le pais de Flandre en tous bons usages, et
tenroit justice et raison à tout honme; et prioit Jaques d’Artevelle que
de ce, les bonnes villes qui là estoient se vosissent consillier et faire
ent response. Adonc regardèrent il tous li uns l’autre, et ne sceurent
que dire. Toutes fois il demandèrent consel de parler ensamble; on
lor donna. Il parlèrent tout à un, et fu la response telle: «Jaquemes,
nous avons bien oï ce que vous avés dit; et qant nous venimes ichi,
nous ne savions pas que vous nous deuissiés aparler de ceste
matère, et nous est assés nouvelle. Et nous ne poons pas faire cechi
de nous tant seullement: il couvient que tous li pais de Flandres s’i
asente; et qant là sera venu, que on voie et congnoise les rebelles
qui à ce ne se vodront acorder, et que il soient bani publiquement et
perdent ce que ou pais de Flandres à present il i tiennent, sans
esperance de jamais ravoir, ne i retourner. Ensi se pora faire chils
hiretages segurement, car, tant que avons qui chi sonmes, nous
volons bien à signeur, puis que il est à ce promeus, le prinche de
Galles, sauf et reservé les conditions desus dittes.» Ceste response
souffi très grandement au roi et à son consel; mais il fu demandé as
bonnes villes de Flandres qui avoient respondu, qant li rois se poroit
certefiier de la response. Euls par acord prissent un mois de jour; on
lor donna. Et disnèrent avoecques le roi en son vassiel meismes, et
puis se departirent et retournèrent, casquns sus son lieu, les auquns
tous abus et courouchiés de ces nouvelletés que il avoient oy, quoi
que il euissent respondu à la plaisance dou roi et de d’Artevelle. Et
leur sambloit dure cose et estragne de deshireter lor signeur; et se il
faisoient ce, à tousjours mès il seroient tenu et reputé pour traittes et
infames. Nequedent, d’Artevelle estoit tant doubtés et cremeus ou
pais de Flandres que, au fort, nuls ne l’euist osé courouchier, ne
desdire de ses volentés. Encores demora Jaques d’Artevelle dalés
le roi sus sa navie à l’Escluse, depuis que li aultre furent parti.
Or montèrent grandes murmurations parmi la conté de Flandres,
qant les nouvelles s’espardirent que Jaquemes d’Artevelle avoit jeté
sa visée à ce que li princes de Gales seroit sires de Flandres, et que
on en feroit une ducée. Li auqun disoient, qui amoient le roi
d’Engleterre: «Ce sera bien fait.» Et li aultre disoient le contraire, et
que ce seroit damages, blames et traison trop grande à deshireter
son signeur. Et en avoient les bonnes gens pité, et plus pour la
cause dou fil, le conte Lois de Male, que il n’euissent pour le père,
car ils lor avoit esté crueuls, hausters, durs et mervilleus. Et pour tels
causes l’avoient ils bouté hors de Flandres, mais ils gardoient Lois,
le jone fils, et disoient que il le nouriroient à lor manière, et seroit
mieuls abuvrés de conditions flamenges que son père n’euist esté.
Li dus Jehans de Braibant, pour le temps d’adonc, avoit une jone fille
à marier, si ques conme sages et imaginatis que il fu et moult
soubtieus, il avoit jetté sa visée à che que uns mariages seroit trop
bien pris et fais de sa fille et dou fil le conte de Flandres. Et le
concordoit assés le conte de Flandres, mais il n’estoit pas sires ne
mestres de son fil: ançois le tenoient et gardoient li Flamenc, et le
nourissoient sus bonnes gardes, et ne le laissoient point issir de la
ville de Gant. Li dus de Braibant consideroit bien les coses à venir, et
conment Jaquemes d’Artevelle pour ces jours estoit si grans en
Flandres que par lui estoit tout fait, et sans lui n’estoit riens fait; et fu
enfourmés de ces nouvelles conment li rois d’Engleterre estoit à
l’Escluse et gissoit là à l’ancre, et procuroit, et Jaquemes d’Artevelle
pour lui, que ses fils, li princes de Galles, fust dus de Flandres. Si se
doubta li dis dus de Braibant que toutes cez coses n’avenissent, qui
trop legierement pooient avenir, et avisa que il i meteroit un tel touel
que il romperoit et briseroit tout.
Et c’est ce qui avint en la ville de Gant, les jours courans que li
rois d’Engleterre se tenoit en sa navie devant l’Escluse, et atendoit la
response de ceuls dou pais de Flandres. Une disension s’esmut très
grande en la ville de Gant, des tisserans de draps à l’encontre de
Jaqueme d’Artevelle, et tout par le promotion et esquoel de lor doiien
qui se nonmoit Tomas Denis. Et voelt on bien dire que li dus de
Braibant fu cause de ceste aventure, car chil tisserant, par
l’information de lor doiien, vinrent un jour plus de quatre cens devant
l’ostel d’Artevelle, et l’environnèrent devant et derrière, et
moustrèrent que de force il voloient entrer dedens. Quant les varlès
de ce d’Artevelle les veirent ensi venus, si furent tout esmervilliet
que il demandoient, car il n’avoient point acoustumé que chil de
Gand, ne aultres gens venissent ensi de fait et en cel estat parler à
lor mestre et voloir efforchier la maison. Si conmenchièrent à parler
rudement à euls et voloir metre hors à force, mais il ne peurent;
avant furent batu et vilené et blecié. Jaques d’Artevelle estoit enclos
en sa cambre, et avoit oy la grignour partie des paroles et dou
hustin. Si vint à une fenestre qui regardoit sus une rue où toutes ces
gens estoient asamblé; se lor demanda: «Bonnes gens, quel cose
vous fault? Pourquoi estes vous si esmeus?» Il respondirent: «Nous
volons parler à vous. Venés çà jus.» Donc respondi Jaques et dist:
«Et se je estoie là, que voriiés vous dire?»—«Nous volons que tu
nous rendes compte dou grant tresor de Flandres, que tu as eu et
levé, depuis sept ans, à ta volenté, et nous di quel cose tu en as fait,
ne où tu l’a[s] mis.» Donc respondi Jaquemes d’Artevelle, qui bien
considera que les coses aloient diversement et hors des rieulles
acoustumés, aultrement que il ne soloient estre, et les quida apaisier
de douces paroles et dist: «Bonnes gens, retraiiés vous casquns en
son hostel, et dedens trois jours je vous appellerai et serai pourveus
de vous rendre si bon compte, que vous en serés tout conteut.» Il
respondirent de une vois: «Nous ne volons point tant atendre, mès
vieng hors de ton hostel compter à nous,» Jaquemes d’Artevelle
considera bien tantos que les coses aloient mal, et que il estoit en
peril de sa vie; si dist: «Signeur, signeur, tenés vous là, je irai tantos
parler à vous.» A ces mos il se tinrent tout quoi, et il issi hors de sa
cambre et vint viers son estable et ses cevaus, et quida monter sus
et partir par derrière et aler sa voie, mais il ne pot, car l’ostel estoit si
environnés de tous lés que tantos il fu aperceus et veus quel cose il
voloit faire; et fu acusés de ceuls qui gardoient l’uis à ceuls qui
estoient à la porte devant. Donc s’esleva grans tumultes entre iaus,
et rompirent de force les huis et passèrent tout oultre, et vinrent en
l’estable et trouvèrent Jaquemon d’Artevelle qui s’ordonnoit pour
monter et aler sa voie. Tantos de fait il l’asallirent; et li donna chils
Thomas Denis, li doiiens des tisserans, le premier cop de une hace,
en la teste, par quoi il l’abati. Se li avoit Jaques d’Artevelle fait
pluisseurs biens, et l’avoit mis en l’office dou doiainné des telliers, et
si estoit son compère. Nequedent, toutes ces coses et afinités furent
oubliies et misses arrière. Et fu là ochis Jaques d’Artevelle
mescanment, qui tant avoit eu d’estat, d’onnour et de prosperités en
Flandres; ne on ne trouva onques en Gant honme ne justice qui en
vosist prendre ne lever amende. Ensi vont les fortunes de ce monde;
ne nuls ne se puet ne doit confiier, se sages est, trop grandement
ens ès prosperités de ce monde. Fos 103 et 104.
P. 98, l. 16: preeçoit.—Les mss. A 1 à 33 ajoutent: sa querelle.
Fº 125 vº.
P. 98, l. 18 à 23: d’Engleterre... et dit ensi.—Mss. A 1 à 6, 11 à 14,
18, 19: en lui donnant en mariage la fille du conte Loys de Flandres,
en faisant de la conté duchié, dont les Flamens avoient respondu
d’un commun accort et dit ainsi. Fº 125 vº.—Mss. A 20 à 22: pour
adheriter le filz au roy d’Angleterre. Si luy respondirent tous d’un
commun accord. Fº 184. Voir aussi Sup. var. (n. d. t.)
P. 99, 100, 101, 102: voir Sup. var. (n. d. t.)

P. 103, l. 4: teliers.—Ms. A 8: cellier. Fº 115 vº.—Mss. A 15 à 17:


sellier. Fº 128.
P. 103, l. 6: voir Sup. var. (n. d. t.)
§ 238. P. 103, l. 17: Quant li rois.—Ms. d’Amiens: De quoy li roys
fu si courouchiés et si mautalentis sus les Flammens que il lez volloit
gueriier; et leur manda que le mort de son compère d’Artevelle et qui
si sagement les avoit gouvrennés, il leur feroit comparer chierement.
Et retourna li roys à Londrez et n’ala adonc plus avant. Chil de
Bruges, d’Ippre, de Courtray, de Popringhe et dez autrez bonnez
villez de Flandrez se doubtèrent durement dou roy englèz que il ne
leur fesist contraire pour la mort d’Artevelle. Si se vinrent à lui
escuzer, et li dissent que de sa mort il n’estoient en rienz coupablez,
et que, quant il li plairoit, il le feroient amender chyaux de Gand
tellement que bien deveroit souffire, et que jà pour ce il n’en seroit le
mains fors en Flandrez, ne li comtez plus avanchiéz, mais li tenroient
tous lez couvens et proummesses que juret li avoient. Par ensi se
rappaissa ung peu li roys d’Engleterre, et mist en nuncalloir le mort
Jaquemon d’Artevelle, et depuis tint à amour grandement lez
Flammens. Fº 85 vº.
—Ms. de Rome: Qant li rois d’Engleterre, qui se tenoit à l’Escluse
en sa navie et estoit tenus tout le temps, attendans la response des
consauls des bonnes villes de Flandres, entendi que chil de Gant
avoient ocis Jaquemon d’Artevelle, son grant amic et son chier
compère, vous poés bien croire et sçavoir que il fu courouciés et
sautmoutonnés oultre mesure. Et fist tantos desancrer sa navie et
tirer les voilles amont, et se departi de devant l’Escluse; et rentra en
mer en maneçant grandement les Flamens. Et dist et jura que
jamais il n’entenderoit à aultre cose, si lor aueroit si remoustré
acertes que il lor en souvenroit à tous jours mais, et retourna arrière
en Engleterre. Qant les nouvelles furent esparses parmi le pais et
les bonnes villes de Flandres que d’Artevelle estoit mors, et que chil
de Gant l’avoient ocis, si en furent li pluisseur moult tourblé pour le
pourfit conmun dou pais de Flandres, et imaginèrent que li rois
d’Engleterre, outre mesure, seroit moult courouciés, et que li pais de
Flandres le poroit bien trop cierement comparer; si regardèrent que
generaument il s’envoieroient escuser, ensi que il fissent. Et
passèrent douse honmes notables oultre en Engleterre, et fissent
tant parmi un bon moiien que il trouvèrent ou consel dou roi, que li
rois s’apaisa et mist en oubli d’Artevelle, car il fu ensi dit au roi:
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

ebookmass.com

You might also like