Hello World!
I would like to share my learning journey with JavaFX by demonstrating a small project in the form of a 'dock'. The goal of this project is to create a bar at the bottom of the screen where program icons can be placed and launched directly.
Project idea
I came across this project as part of the Udemy course 'JavaFX - Creating Java programs with interfaces / GUIs'.
I developed my own interpretation and expanded and improved the project according to my ideas.
Before starting
- Java Version: openjdk 22
- IDE: IntelliJ Community Edition
- Build Tool: Maven
Create Project
Creating a JavaFX project in IntelliJ is easy.
Project Structure
I'm following the MVC architecture, with separate packages for the model, view, and controller.
public class App extends Application {
public void start(Stage stage) throws IOException {
//MVC
MyView view = new MyView();
MyController controller = new MyController(view);
//JavaFX
Scene scene = new Scene(view.getRoot(), 520, 240);
stage.setTitle("Hello World!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
View
public class MyView {
private Group root = new Group();
private ImageView imageViewDock;
private final String[] icons = {"Browser.png", "IDE.png", "Mail.png", "Text.png" };
private ArrayList<IconImageView> iconsList = new ArrayList<>();
public MyView() {
Image image = new Image(getClass().getResourceAsStream("/images/Dock.png"));
//Dock
imageViewDock = new ImageView(image);
imageViewDock.setTranslateX(12);
imageViewDock.setTranslateY(100);
root.getChildren().add(imageViewDock);
for(int i = 0; i < icons.length; i++){
IconImageView icon = new IconImageView(icons[i]);
icon.setTranslateX(90+80 * i);
icon.setTranslateY(100);
icon.setEffect(new Reflection());
root.getChildren().add(icon);
iconsList.add(icon);
}
}
I use the Group
layout as the root element for my scene. Then I create an ImageView
that contains my image for the dock.
Using a for loop, I created the icons and added them to the dock.
Icons
public class IconImageView extends ImageView {
String path = "";
public IconImageView(String path) {
this.path = path;
Image image = new Image(getClass().getResourceAsStream("/images/" + this.path +""));
this.setImage(image);
this.setScaleY(0.8);
this.setScaleX(0.8);
For the icons, I created a custom IconImageView class where I defined default values and zoom in/out effects.
Controller
public class MyController {
private MyView view;
public MyController(MyView view) {
this.view = view;
DockHandler dockHandler = new DockHandler();
//Add Event Handler, exit by 2 clicks
this.view.getImageViewDock().setOnMouseClicked(dockHandler.getMouseEventEventHandler());
//Add Event Handler Icons
ArrayList<IconImageView> iconsList = view.getIconsList();
for ( int i = 0; i < iconsList.size(); i++){
iconsList.get(i).setOnMouseClicked(new IconHandler(iconsList.get(i).getPath()).getEventHandler());
}
}
}
The controller connects my view with the model classes. The dockHandler terminates the program when you double-click on the dock.
IconHandler
public IconHandler(String path) {
eventHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
//Query operating system
String os = System.getProperty("os.name").toLowerCase();
if (path.equals("Browser.png")){
System.out.println("Browser");
if(os.contains("win")){
String path = "C:\\Program Files\\Mozilla Firefox\\firefox.exe" ;
startProgramm(path);
}else if (os.contains("mac")) {
String path = "open /Applications/Firefox.app" ;
startProgramm(path);
}else {
System.out.println("Unsupported operating system");
}
} else if
In IconHandler, check which operating system is used and then open the application for Mac or Windows.
App
//Transparent
scene.setFill(Color.TRANSPARENT);
stage.initStyle(StageStyle.TRANSPARENT);
stage.show();
//Position
//Screen Size
Rectangle2D screenSize = Screen.getPrimary().getVisualBounds();
double x = (screenSize.getWidth() - stage.getWidth()) / 2;
double y = screenSize.getHeight() - stage.getHeight() - 40;
stage.setX(x);
stage.setY(y);
}
Finally, I implemented transparency and positioned the dock correctly on the screen.
Future
Currently, some elements, such as paths and images, are still hard-coded. I plan to improve these areas to allow new icons to be added dynamically.
Conclusion
Thank you for reading this far! I'm still new to writing articles and have a lot to learn. I appreciate any feedback you may have. May the Force be with you. 😊
Top comments (0)