All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.dlsc.gemsfx.demo.InfoCenterApp Maven / Gradle / Ivy
package com.dlsc.gemsfx.demo;
import com.dlsc.gemsfx.infocenter.InfoCenterPane;
import com.dlsc.gemsfx.infocenter.InfoCenterView;
import com.dlsc.gemsfx.infocenter.Notification;
import com.dlsc.gemsfx.infocenter.Notification.OnClickBehaviour;
import com.dlsc.gemsfx.infocenter.NotificationAction;
import com.dlsc.gemsfx.infocenter.NotificationGroup;
import com.dlsc.gemsfx.infocenter.NotificationView;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ToggleButton;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundImage;
import javafx.scene.layout.BackgroundPosition;
import javafx.scene.layout.BackgroundRepeat;
import javafx.scene.layout.BackgroundSize;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.scenicview.ScenicView;
import java.io.IOException;
import java.io.InputStream;
import java.time.ZonedDateTime;
import java.util.Objects;
public class InfoCenterApp extends Application {
private static final Image SLACK_IMAGE = loadResourceImage("notification/slack.png");
private static final Image CALENDAR_IMAGE = loadResourceImage("notification/calendar.png");
private static final Image MAP_IMAGE = loadResourceImage("notification/map.png");
private static final Image MAIL_IMAGE = loadResourceImage("notification/mail.png");
private final InfoCenterPane infoCenterPane = new InfoCenterPane();
private final NotificationGroup mailGroup = new NotificationGroup<>("Mail");
private final NotificationGroup slackGroup = new NotificationGroup<>("Slack");
private final NotificationGroup calendarGroup = new NotificationGroup<>("Calendar");
@Override
public void start(Stage stage) {
slackGroup.setSortOrder(0);
calendarGroup.setSortOrder(1);
mailGroup.setSortOrder(2);
slackGroup.maximumNumberOfNotificationsProperty().bind(Bindings.createIntegerBinding(() -> slackGroup.isPinned() ? 3 : 10, slackGroup.pinnedProperty()));
calendarGroup.maximumNumberOfNotificationsProperty().bind(Bindings.createIntegerBinding(() -> calendarGroup.isPinned() ? 3 : 10, calendarGroup.pinnedProperty()));
mailGroup.maximumNumberOfNotificationsProperty().bind(Bindings.createIntegerBinding(() -> mailGroup.isPinned() ? 3 : 10, mailGroup.pinnedProperty()));
slackGroup.setViewFactory(n -> {
NotificationView view = new NotificationView<>(n);
view.setGraphic(createImageView(SLACK_IMAGE));
return view;
});
calendarGroup.setViewFactory(n -> {
NotificationView view = new NotificationView<>(n);
view.setGraphic(createImageView(CALENDAR_IMAGE));
Region region = new Region();
region.setMinHeight(200);
region.setBackground(new Background(new BackgroundImage(MAP_IMAGE, BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER, new BackgroundSize(100, 100, true, true, false, true))));
StackPane stackPane = new StackPane(region);
stackPane.setStyle("-fx-border-color: grey;");
view.setContent(stackPane);
return view;
});
mailGroup.setViewFactory(n -> {
NotificationView view = new NotificationView<>(n);
view.setGraphic(createImageView(MAIL_IMAGE));
return view;
});
InfoCenterView infoCenterView = infoCenterPane.getInfoCenterView();
infoCenterView.getGroups().setAll(mailGroup, slackGroup, calendarGroup);
for (int i = 0; i < 10; i++) {
assignNotification(createNotification(true));
}
Button randomNotification = new Button("Random Notification (Current Time)");
randomNotification.setOnAction(evt -> assignNotification(createNotification(false)));
randomNotification.setMaxWidth(Double.MAX_VALUE);
Button manyNotifications = new Button("Many Notifications (Random Times)");
manyNotifications.setOnAction(evt -> {
for (int i = 0; i < 10; i++) {
assignNotification(createNotification(true));
}
});
manyNotifications.setMaxWidth(Double.MAX_VALUE);
Button clearAll = new Button("Clear All");
clearAll.setOnAction(evt -> infoCenterView.clearAll());
clearAll.setMaxWidth(Double.MAX_VALUE);
Button showNotifications = new Button("Show Info Center");
showNotifications.setOnAction(evt -> infoCenterPane.setShowInfoCenter(true));
showNotifications.setMaxWidth(Double.MAX_VALUE);
Button hideNotifications = new Button("Hide Info Center");
hideNotifications.setOnAction(evt -> infoCenterPane.setShowInfoCenter(false));
hideNotifications.setMaxWidth(Double.MAX_VALUE);
ToggleButton pinNotifications = new ToggleButton("Pin Info Center");
pinNotifications.selectedProperty().bindBidirectional(infoCenterPane.pinnedProperty());
pinNotifications.setMaxWidth(Double.MAX_VALUE);
ToggleButton autoOpenGroups = new ToggleButton("Auto Open Groups");
autoOpenGroups.selectedProperty().bindBidirectional(infoCenterPane.getInfoCenterView().autoOpenGroupProperty());
autoOpenGroups.setMaxWidth(Double.MAX_VALUE);
ToggleButton transparentButton = new ToggleButton("Make Transparent");
transparentButton.setMaxWidth(Double.MAX_VALUE);
transparentButton.selectedProperty().bindBidirectional(infoCenterView.transparentProperty());
Button scenicView = new Button("Scenic View");
scenicView.setOnAction(evt -> ScenicView.show(infoCenterView.getScene()));
scenicView.setMaxWidth(Double.MAX_VALUE);
Label counterLabel = new Label();
counterLabel.setStyle("-fx-text-fill: white;");
counterLabel.textProperty().bind(Bindings.createStringBinding(() -> "Count: " + infoCenterView.getUnmodifiableNotifications().size(), infoCenterView.getUnmodifiableNotifications()));
VBox buttonBox = new VBox(10, showNotifications, hideNotifications, pinNotifications, autoOpenGroups, randomNotification, manyNotifications, clearAll, transparentButton, scenicView, counterLabel);
buttonBox.getStyleClass().add("button-box");
buttonBox.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
buttonBox.setTranslateX(50);
buttonBox.setTranslateY(50);
StackPane.setAlignment(buttonBox, Pos.TOP_LEFT);
StackPane background = new StackPane(buttonBox);
background.getStyleClass().add("background");
infoCenterPane.setContent(background);
infoCenterPane.getStylesheets().add(Objects.requireNonNull(InfoCenterApp.class.getResource("notification/scene.css")).toExternalForm());
/*
* Note:
* It is advised not to use InfoCenterPane as the root of a Scene to avoid occasional ghost images on Windows systems.
* This issue does not occur on macOS, suggesting a platform-specific JavaFX rendering bug.
*
* As a recommended solution, wrap InfoCenterPane in a StackPane or another suitable container to resolve this issue.
*/
StackPane root = new StackPane(infoCenterPane);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setWidth(1000);
stage.setHeight(800);
stage.centerOnScreen();
stage.setTitle("InfoCenter");
stage.show();
}
private void assignNotification(Notification> notification) {
if (notification instanceof MailNotification) {
mailGroup.getNotifications().add((MailNotification) notification);
} else if (notification instanceof CalendarNotification) {
calendarGroup.getNotifications().add((CalendarNotification) notification);
} else if (notification instanceof SlackNotification) {
slackGroup.getNotifications().add((SlackNotification) notification);
}
}
private static ImageView createImageView(Image image) {
ImageView imageView = new ImageView(image);
imageView.setFitWidth(42);
imageView.setFitHeight(42);
imageView.setPreserveRatio(true);
return imageView;
}
private Notification> createNotification(boolean randomizeTimeStamp) {
Notification notification;
switch ((int) (Math.random() * 3)) {
case 0:
notification = createMailNotification();
break;
case 1:
notification = new SlackNotification("DLSC GmbH\nDirk Lemmermann", "Please send the material I requested.");
break;
case 2:
default:
notification = new CalendarNotification("Calendar", "Meeting with shareholders");
}
if (randomizeTimeStamp) {
notification.setDateTime(createTimeStamp());
}
return notification;
}
private MailNotification createMailNotification() {
Mail mail = new Mail("Purchase Order #8774911", "Dear Mr. Smith, the following order has been received by our service counter.", ZonedDateTime.now());
MailNotification mailNotification = new MailNotification(mail);
NotificationAction openMailAction = new NotificationAction<>("Open", (notification) -> {
Alert alert = new Alert(Alert.AlertType.INFORMATION, "Opening Mail ...");
alert.initOwner(infoCenterPane.getScene().getWindow());
alert.show();
return OnClickBehaviour.HIDE_AND_REMOVE;
});
NotificationAction deleteMailAction = new NotificationAction<>("Delete", (notification) -> {
Alert alert = new Alert(Alert.AlertType.INFORMATION, "Deleting Mail ...");
alert.initOwner(infoCenterPane.getScene().getWindow());
alert.show();
return OnClickBehaviour.HIDE_AND_REMOVE;
});
mailNotification.getActions().add(openMailAction);
mailNotification.getActions().add(deleteMailAction);
return mailNotification;
}
private ZonedDateTime createTimeStamp() {
ZonedDateTime time = ZonedDateTime.now();
time = time.minusDays((int) (Math.random() * 2));
time = time.minusMinutes((int) (Math.random() * 30));
time = time.minusSeconds((int) (Math.random() * 45));
return time;
}
public static class CalendarNotification extends Notification {
public CalendarNotification(String title, String description) {
super(title, description);
setOnClick(notification -> OnClickBehaviour.HIDE_AND_REMOVE);
}
}
public static class SlackNotification extends Notification {
public SlackNotification(String title, String description) {
super(title, description);
setOnClick(notification -> OnClickBehaviour.REMOVE);
}
}
public static class MailNotification extends Notification {
public MailNotification(Mail mail) {
super(mail.getTitle(), mail.getDescription(), mail.getDateTime());
setUserObject(mail);
setOnClick(notification -> OnClickBehaviour.NONE);
}
}
public static class Mail {
private String title;
private String description;
private ZonedDateTime dateTime;
public Mail(String title, String description, ZonedDateTime dateTime) {
this.title = title;
this.description = description;
this.dateTime = dateTime;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public ZonedDateTime getDateTime() {
return dateTime;
}
public void setDateTime(ZonedDateTime dateTime) {
this.dateTime = dateTime;
}
}
/**
* Loads an image from a specified resource path.
* This method ensures that the resource stream is properly closed after the image is loaded.
*
* @param path the resource path relative to the class location
* @return Image loaded from the specified path
* @throws RuntimeException if an I/O error occurs or the resource cannot be found
*/
private static Image loadResourceImage(String path) {
try (InputStream is = Objects.requireNonNull(InfoCenterApp.class.getResourceAsStream(path))) {
return new Image(is);
} catch (IOException e) {
throw new RuntimeException("Error loading image from path: " + path, e);
} catch (NullPointerException e) {
throw new IllegalArgumentException("Resource not found: " + path, e);
}
}
public static void main(String[] args) {
launch();
}
}