diff --git a/README.md b/README.md index b71b8cc..0df7039 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# habfx-ui +# HABFX-UI openHAB2 javaFX User Interface HABFX-UI is an OpenHAB2 client.
diff --git a/src/main/java/com/ben12/openhab/controller/impl/GroupController.java b/src/main/java/com/ben12/openhab/controller/impl/GroupController.java index c875acf..c95d10f 100644 --- a/src/main/java/com/ben12/openhab/controller/impl/GroupController.java +++ b/src/main/java/com/ben12/openhab/controller/impl/GroupController.java @@ -17,15 +17,32 @@ package com.ben12.openhab.controller.impl; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.swing.event.ChangeListener; +import javax.ws.rs.client.InvocationCallback; + import com.ben12.openhab.controller.MainViewController; +import com.ben12.openhab.model.Item; import com.ben12.openhab.model.Page; import com.ben12.openhab.model.Widget; +import com.ben12.openhab.model.util.BeanCopy; +import com.ben12.openhab.rest.OpenHabRestClient; +import javafx.application.Platform; +import javafx.collections.FXCollections; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; import javafx.scene.layout.Region; public class GroupController extends WidgetController { - private PageController pageController; + private PageController pageController; + + private ObservableList members; public GroupController(final Page parent) { @@ -39,6 +56,65 @@ public void init(final Widget widget, final MainViewController pMainViewControll pageController = new PageController(); pageController.init(getWidget().getLinkedPage(), getMainViewController()); + + final ChangeListener memberChangeHandler = e -> reload(); + + final OpenHabRestClient restClient = getMainViewController().getRestClient(); + final Map itemChangeHandlers = new HashMap<>(); + + members = FXCollections.observableArrayList(); + members.addListener((ListChangeListener) c -> { + while (c.next()) + { + if (c.wasRemoved()) + { + for (final Item item : c.getRemoved()) + { + final ItemChangeHandler handler = itemChangeHandlers.remove(item.getName()); + if (handler != null) + { + handler.release(); + } + } + } + if (c.wasAdded()) + { + for (final Item item : c.getAddedSubList()) + { + itemChangeHandlers.computeIfAbsent(item.getName(), + itemName -> new ItemChangeHandler(restClient, itemName, memberChangeHandler)); + } + } + } + }); + + loadMembers(); + } + + public void loadMembers() + { + final OpenHabRestClient restClient = getMainViewController().getRestClient(); + restClient.item(getWidget().getItem().getName(), new InvocationCallback() + { + @Override + public void failed(final Throwable throwable) + { + Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Cannot load group members", throwable); + } + + @Override + public void completed(final Item response) + { + Platform.runLater(() -> BeanCopy.copy(response.getMembers(), members, Item::getName)); + } + }); + } + + @Override + public void reload() + { + super.reload(); + loadMembers(); } @Override diff --git a/src/main/java/com/ben12/openhab/controller/impl/PageController.java b/src/main/java/com/ben12/openhab/controller/impl/PageController.java index c7e82f1..f360d2b 100644 --- a/src/main/java/com/ben12/openhab/controller/impl/PageController.java +++ b/src/main/java/com/ben12/openhab/controller/impl/PageController.java @@ -27,6 +27,8 @@ import com.ben12.openhab.model.Widget; import com.ben12.openhab.ui.FullWidthTilePane; +import javafx.beans.binding.Bindings; +import javafx.beans.binding.StringBinding; import javafx.beans.value.ObservableValue; import javafx.collections.ListChangeListener.Change; import javafx.geometry.Bounds; @@ -42,6 +44,8 @@ public class PageController implements ContentController private Label title; + private StringBinding titleProperty; + private Page page; private Pane pane; @@ -54,7 +58,7 @@ public void init(final Page data, final MainViewController pMainViewController) title = new Label(); title.getStyleClass().add("title"); - title.textProperty().bind(page.titleProperty()); + title.textProperty().bind(titleProperty()); title.heightProperty().addListener((e, o, n) -> { final Text textUtil = new Text(title.getText()); @@ -123,6 +127,19 @@ public void changed(final ObservableValue observable, final Bo .collect(Collectors.toList())); } + protected StringBinding titleProperty() + { + if (titleProperty == null) + { + titleProperty = Bindings.createStringBinding(() -> { + String label = page.getTitle(); + label = label.replaceFirst("\\[(.*?)\\]$", "$1"); + return label; + }, page.titleProperty()); + } + return titleProperty; + } + @Override public void reload() { diff --git a/src/main/java/com/ben12/openhab/controller/impl/WidgetController.java b/src/main/java/com/ben12/openhab/controller/impl/WidgetController.java index 2cf02a8..63970a6 100644 --- a/src/main/java/com/ben12/openhab/controller/impl/WidgetController.java +++ b/src/main/java/com/ben12/openhab/controller/impl/WidgetController.java @@ -290,14 +290,14 @@ protected StringBinding labelProperty() { labelProperty = Bindings.createStringBinding(() -> { String label = widget.getLabel(); - label = label.replaceFirst("\\s*\\[(.*?)\\]$", ""); + label = label.replaceFirst("\\s*\\[.*?\\]$", ""); return label; }, widget.labelProperty()); } return labelProperty; } - public ObjectExpression labelStyleProperty() + protected ObjectExpression labelStyleProperty() { if (labelStyleProperty == null) { @@ -314,7 +314,7 @@ public ObjectExpression labelStyleProperty() return labelStyleProperty; } - public StringBinding valueProperty() + protected StringBinding valueProperty() { if (valueProperty == null) { @@ -327,7 +327,7 @@ public StringBinding valueProperty() return valueProperty; } - public ObjectExpression valueStyleProperty() + protected ObjectExpression valueStyleProperty() { if (valueStyleProperty == null) { @@ -344,7 +344,7 @@ public ObjectExpression valueStyleProperty() return valueStyleProperty; } - private static class ItemChangeHandler extends WeakReference implements ChangeListener + protected static class ItemChangeHandler extends WeakReference implements ChangeListener { private final String itemName; diff --git a/src/main/java/com/ben12/openhab/model/GroupItem.java b/src/main/java/com/ben12/openhab/model/GroupItem.java deleted file mode 100644 index 297eb6e..0000000 --- a/src/main/java/com/ben12/openhab/model/GroupItem.java +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2016 Benoît Moreau (ben.12) -// -// This file is part of HABFX-UI (openHAB javaFX User Interface). -// -// HABFX-UI is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// HABFX-UI is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with HABFX-UI. If not, see . - -package com.ben12.openhab.model; - -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -import com.ben12.openhab.model.util.BeanCopy; - -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; - -/** - * This is a java bean that is used with JAXB to serialize group items - * to XML or JSON. - * - * @author Kai Kreuzer - * @since 0.8.0 - */ -@XmlRootElement(name = "item") -@XmlAccessorType(XmlAccessType.PROPERTY) -public class GroupItem extends Item -{ - public final ObservableList members = FXCollections.observableArrayList(); - - public ObservableList membersProperty() - { - return members; - } - - @XmlElement - public List getMembers() - { - return members; - } - - public void setMembers(final List pMembers) - { - if (members != pMembers) - { - BeanCopy.copy(pMembers, members, Item::getName); - } - } -} diff --git a/src/main/java/com/ben12/openhab/model/Item.java b/src/main/java/com/ben12/openhab/model/Item.java index 72f58ab..a70709d 100644 --- a/src/main/java/com/ben12/openhab/model/Item.java +++ b/src/main/java/com/ben12/openhab/model/Item.java @@ -17,15 +17,21 @@ package com.ben12.openhab.model; +import java.util.List; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import com.ben12.openhab.model.util.BeanCopy; + import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; /** * This is a java bean that is used with JAXB to serialize items @@ -48,6 +54,8 @@ public class Item implements Linked private final StringProperty link = new SimpleStringProperty(); + public final ObservableList members = FXCollections.observableArrayList(); + public final StringProperty typeProperty() { return type; @@ -129,4 +137,23 @@ public final void setLink(final String link) { linkProperty().set(link); } + + public ObservableList membersProperty() + { + return members; + } + + @XmlElement + public List getMembers() + { + return members; + } + + public void setMembers(final List pMembers) + { + if (members != pMembers) + { + BeanCopy.copy(pMembers, members, Item::getName); + } + } } diff --git a/src/main/java/com/ben12/openhab/model/util/BeanCopy.java b/src/main/java/com/ben12/openhab/model/util/BeanCopy.java index 10bbc63..bff3ea9 100644 --- a/src/main/java/com/ben12/openhab/model/util/BeanCopy.java +++ b/src/main/java/com/ben12/openhab/model/util/BeanCopy.java @@ -20,7 +20,6 @@ import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Objects; -import java.util.concurrent.CountDownLatch; import java.util.function.Function; import java.util.logging.Level; import java.util.logging.Logger; @@ -30,7 +29,7 @@ import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.WrapDynaBean; -import javafx.application.Platform; +import jfxtras.util.PlatformUtil; public class BeanCopy extends WrapDynaBean { @@ -80,24 +79,16 @@ public static void copy(final List source, final List destination, fin public static void copy(final Object source, final Object destination) { - try - { - if (!Platform.isFxApplicationThread()) + PlatformUtil.runAndWait(() -> { + try { - final CountDownLatch done = new CountDownLatch(1); - Platform.runLater(() -> { - copy(source, destination); - done.countDown(); - }); - done.await(); - return; + BeanUtils.copyProperties(wrap(destination), source); } - BeanUtils.copyProperties(wrap(destination), source); - } - catch (final Exception e) - { - LOGGER.log(Level.SEVERE, "Cannot copy bean", e); - } + catch (final Exception e) + { + LOGGER.log(Level.SEVERE, "Cannot copy bean", e); + } + }); } private static BeanCopy wrap(final Object value) diff --git a/src/main/java/com/ben12/openhab/rest/OpenHabRestClient.java b/src/main/java/com/ben12/openhab/rest/OpenHabRestClient.java index 009a5e3..6120068 100644 --- a/src/main/java/com/ben12/openhab/rest/OpenHabRestClient.java +++ b/src/main/java/com/ben12/openhab/rest/OpenHabRestClient.java @@ -288,7 +288,7 @@ public void completed(final Response response) public void addItemStateChangeListener(final String itemName, final ChangeListener l) { final String key = String.format(EVENT_KEY, itemName); - listeners.computeIfAbsent(key, k -> new ArrayList<>()).add(l); + listeners.computeIfAbsent(key, k -> new ArrayList<>(1)).add(l); } public void removeItemStateChangeListener(final String itemName, final ChangeListener l)