Skip to content

Commit

Permalink
Potential fix for notifications created before area is shown
Browse files Browse the repository at this point in the history
  • Loading branch information
Emil Forslund committed Apr 4, 2016
1 parent 1ecf228 commit c073d24
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 62 deletions.
22 changes: 22 additions & 0 deletions src/main/java/com/speedment/component/UserInterfaceComponent.java
Expand Up @@ -23,6 +23,7 @@
import com.speedment.ui.config.DocumentProperty;
import com.speedment.internal.ui.controller.ProjectTreeController;
import com.speedment.internal.ui.util.OutputUtil;
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon;
import java.util.Optional;
import java.util.stream.Stream;
import javafx.collections.ObservableList;
Expand All @@ -33,6 +34,7 @@
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import org.controlsfx.control.PropertySheet;

Expand Down Expand Up @@ -100,6 +102,8 @@ default Class<UserInterfaceComponent> getComponentClass() {
*/
ObservableList<Node> getOutputMessages();



/**
* Returns a stream of all the css-file that should be used to style the UI.
*
Expand Down Expand Up @@ -168,6 +172,24 @@ static void apply(UISession session, Scene scene) {
*/
Brand getBrand();

/**
* Container for the fields required to show a notification in the UI.
*/
interface Notification {
FontAwesomeIcon icon();
String text();
Color color();
Runnable onClose();
}

/**
* Returns an observable list of the notifications that has yet to be shown
* in the UI.
*
* @return the observable list of notifications
*/
ObservableList<Notification> getNotifications();

/**
* Installs a new context menu builder that will be used in the
* {@link ProjectTreeController} of the GUI. This is useful for plugins
Expand Down
Expand Up @@ -18,7 +18,6 @@

import com.speedment.Speedment;
import com.speedment.SpeedmentVersion;
import com.speedment.component.Component;
import com.speedment.component.UserInterfaceComponent;
import com.speedment.config.db.trait.HasMainInterface;
import com.speedment.exception.SpeedmentException;
Expand Down Expand Up @@ -58,6 +57,7 @@ public final class UserInterfaceComponentImpl extends InternalOpenSourceComponen

private final ObservableList<PropertySheet.Item> properties;
private final ObservableList<Node> outputMessages;
private final ObservableList<Notification> notifications;
private final ObservableList<TreeItem<DocumentProperty>> selectedTreeItems;
private final Map<Class<?>, List<UserInterfaceComponent.ContextMenuBuilder<?>>> contextMenuBuilders;
private final List<String> stylesheets;
Expand All @@ -68,6 +68,7 @@ public UserInterfaceComponentImpl(Speedment speedment) {
super(speedment);
properties = observableArrayList();
outputMessages = observableArrayList();
notifications = observableArrayList();
selectedTreeItems = observableArrayList();
contextMenuBuilders = new ConcurrentHashMap<>();
stylesheets = new CopyOnWriteArrayList<>(DEFAULT_STYLESHEETS);
Expand Down Expand Up @@ -120,6 +121,11 @@ public UISession getUISession() throws SpeedmentException {
);
} else return session;
}

@Override
public ObservableList<Notification> getNotifications() {
return notifications;
}

@Override
public <DOC extends DocumentProperty & HasMainInterface> void installContextMenu(Class<? extends DOC> nodeType, ContextMenuBuilder<DOC> menuBuilder) {
Expand Down
58 changes: 49 additions & 9 deletions src/main/java/com/speedment/internal/ui/UISession.java
Expand Up @@ -26,6 +26,7 @@
import com.speedment.exception.SpeedmentException;
import com.speedment.code.TranslatorManager;
import com.speedment.component.UserInterfaceComponent.Brand;
import com.speedment.component.UserInterfaceComponent.Notification;
import com.speedment.internal.ui.config.ProjectProperty; // Exposes internal -> To if and expose all *Property and Mutators
import com.speedment.internal.logging.Logger;
import com.speedment.internal.logging.LoggerManager;
Expand Down Expand Up @@ -86,6 +87,7 @@
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView;
import static java.util.Objects.requireNonNull;
import java.util.concurrent.ExecutionException;
import javafx.collections.ObservableList;
import javafx.scene.control.Button;
import javafx.scene.paint.Color;

Expand Down Expand Up @@ -126,6 +128,7 @@ public enum ReuseStage {
private final String defaultConfigLocation;
private final ProjectProperty project;
private final PropertySheetFactory propertySheetFactory;
private final ObservableList<Notification> notifications;

private File currentlyOpenFile = null;

Expand All @@ -135,12 +138,14 @@ public UISession(Speedment speedment, Application application, Stage stage, Stri

public UISession(Speedment speedment, Application application, Stage stage, String defaultConfigLocation, Project project) {

this.speedment = requireNonNull(speedment);
this.application = requireNonNull(application);
this.stage = requireNonNull(stage);
this.speedment = requireNonNull(speedment);
this.application = requireNonNull(application);
this.stage = requireNonNull(stage);
this.defaultConfigLocation = requireNonNull(defaultConfigLocation);
this.project = new ProjectProperty();
this.propertySheetFactory = new PropertySheetFactory();
this.notifications =
speedment.getUserInterfaceComponent().getNotifications();

speedment.getUserInterfaceComponent().setUISession(this);

Expand Down Expand Up @@ -597,28 +602,63 @@ private void showProgressDialog(String title, ProgressMeasure progress, Completa
}
}

private final static class NotificationImpl implements Notification {

private final String message;
private final FontAwesomeIcon icon;
private final Color color;
private final Runnable onClose;

public NotificationImpl(String message, FontAwesomeIcon icon, Color color, Runnable onClose) {
this.message = requireNonNull(message);
this.icon = requireNonNull(icon);
this.color = requireNonNull(color);
this.onClose = requireNonNull(onClose);
}

@Override
public String text() {
return message;
}

@Override
public FontAwesomeIcon icon() {
return icon;
}

@Override
public Color color() {
return color;
}

@Override
public Runnable onClose() {
return onClose;
}
}

public void showNotification(String message) {
NotificationController.showNotification(this, message);
showNotification(message, FontAwesomeIcon.EXCLAMATION);
}

public void showNotification(String message, FontAwesomeIcon icon) {
NotificationController.showNotification(this, message, icon);
showNotification(message, icon, NotificationController.BLUE);
}

public void showNotification(String message, Runnable action) {
NotificationController.showNotification(this, message, action);
showNotification(message, FontAwesomeIcon.EXCLAMATION, NotificationController.BLUE, action);
}

public void showNotification(String message, Color color) {
NotificationController.showNotification(this, message, color);
showNotification(message, FontAwesomeIcon.EXCLAMATION, color);
}

public void showNotification(String message, FontAwesomeIcon icon, Color color) {
NotificationController.showNotification(this, message, icon, color, () -> {});
showNotification(message, icon, color, () -> {});
}

public void showNotification(String message, FontAwesomeIcon icon, Color color, Runnable action) {
NotificationController.showNotification(this, message, icon, color, action);
notifications.add(new NotificationImpl(message, icon, color, action));
}

public <DOC extends DocumentProperty> boolean loadFromDatabase(DbmsProperty dbms, String schemaName) {
Expand Down
Expand Up @@ -42,12 +42,6 @@
import javafx.scene.image.ImageView;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining;

/**
*
Expand Down Expand Up @@ -104,8 +98,8 @@ public void initialize(URL location, ResourceBundle resources) {
public static void createAndShow(UISession session) {
final Stage dialog = new Stage();

final Parent root = Loader.create(session, "About", AboutController::new, control -> {
control.dialog = dialog;
final Parent root = Loader.create(session, "About", control -> {
((AboutController) control).dialog = dialog;
});

final Brand brand = session.getSpeedment().getUserInterfaceComponent().getBrand();
Expand Down
Expand Up @@ -54,9 +54,6 @@
import javafx.scene.control.TreeView;
import javafx.scene.image.Image;
import static java.util.Objects.requireNonNull;
import static java.util.Objects.requireNonNull;
import static java.util.Objects.requireNonNull;
import static java.util.Objects.requireNonNull;

/**
*
Expand Down Expand Up @@ -300,8 +297,8 @@ private SoftwareItem createSoftwareItem(Software software) {
public static void createAndShow(UISession session) {
final Stage dialog = new Stage();

final Parent root = Loader.create(session, "Components", ComponentsController::new, control -> {
control.dialog = dialog;
final Parent root = Loader.create(session, "Components", control -> {
((ComponentsController) control).dialog = dialog;
});

final UserInterfaceComponent.Brand brand = session.getSpeedment().getUserInterfaceComponent().getBrand();
Expand Down
Expand Up @@ -16,9 +16,14 @@
*/
package com.speedment.internal.ui.controller;

import com.speedment.component.UserInterfaceComponent.Notification;
import com.speedment.internal.ui.UISession;
import com.speedment.internal.ui.util.LayoutAnimator;
import java.net.URL;
import static java.util.Objects.requireNonNull;
import java.util.ResourceBundle;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.FlowPane;
Expand All @@ -31,11 +36,13 @@
*/
public class NotificationAreaController implements Initializable {

private final UISession session;
private final LayoutAnimator animator;
private @FXML FlowPane notificationArea;

public NotificationAreaController() {
animator = new LayoutAnimator();
public NotificationAreaController(UISession session) {
this.session = requireNonNull(session);
this.animator = new LayoutAnimator();
}

/**
Expand All @@ -44,5 +51,31 @@ public NotificationAreaController() {
@Override
public void initialize(URL url, ResourceBundle rb) {
animator.observe(notificationArea.getChildren());

final ObservableList<Notification> notifications = session.getSpeedment()
.getUserInterfaceComponent()
.getNotifications();

notifications.addListener((ListChangeListener.Change<? extends Notification> change) -> {
while (change.next()) {
if (change.wasAdded()) {
change.getAddedSubList().forEach(n -> {
NotificationController.showNotification(
session, n.text(), n.icon(), n.color(), n.onClose()
);

notifications.remove(n);
});
}
}
});

while (!notifications.isEmpty()) {
final Notification n = notifications.get(0);
NotificationController.showNotification(
session, n.text(), n.icon(), n.color(), n.onClose()
);
notifications.remove(0);
}
}
}
Expand Up @@ -103,31 +103,17 @@ public void initialize(URL url, ResourceBundle rb) {
seq.play();
}
}

public static void showNotification(UISession session, String message) {
showNotification(session, message, DEFAULT_ICON);
}

public static void showNotification(UISession session, String message, Color color) {
showNotification(session, message, DEFAULT_ICON, color, () -> {});
}

public static void showNotification(UISession session, String message, FontAwesomeIcon icon) {
showNotification(session, message, icon, DEFAULT_COLOR, () -> {});
}

public static void showNotification(UISession session, String message, Runnable onClose) {
showNotification(session, message, DEFAULT_ICON, DEFAULT_COLOR, onClose);
}

public static void showNotification(UISession session, String message, FontAwesomeIcon icon, Color color, Runnable onClose) {

static void showNotification(UISession session, String message, FontAwesomeIcon icon, Color color, Runnable onClose) {
final FlowPane area = (FlowPane) session.getStage().getScene().lookup(NOTIFICATION_AREA_ID);

if (area == null) {
throw new SpeedmentException(
session.showError(
"Error Creating Notification",
"Could not find the '" + NOTIFICATION_AREA_ID +
"' node in the JavaFX scene."
);
return;
}

final FXMLLoader loader = new FXMLLoader(NotificationController.class.getResource(NOTIFICATION_FXML));
Expand Down

0 comments on commit c073d24

Please sign in to comment.