001package fi.jyu.mit.fxgui;
002
003import java.util.ArrayList;
004import java.util.List;
005import java.util.function.Predicate;
006
007import javafx.scene.Node;
008import javafx.scene.layout.Pane;
009
010/**
011 * Apufunktioita JavaFX-olioiden käsittelyyn
012 * @author vesal
013 * @version 6.3.2016
014 */
015public class Functions {
016    /**
017     * Etsii kaikki ehdot täyttävät elementit containerin sisältä 
018     * @param parent containeri, josta etsitään.  Tätä ei lisätä listaan vaikka täyttäisi ehdon
019     * @param type mitä tyyppiä elementin on oltavat, esimerkksi Label.class
020     *             jos halutaan kaikki, voi käyttää Node.class
021     * @param condition ehto, jolla elementti hyväksytään, esimerkkisi n -> "HA".equals(n.getId())
022     * @param recursive etsitäänkö rekursiivisesti
023     * @return lista ehdon täyttävistä elementeistä
024     */
025    @SuppressWarnings("unchecked")
026    public static <T> List<T> getNodes(Node parent, Class<T> type, Predicate<Node> condition, boolean recursive) {
027        List<T> elements = new ArrayList<>();
028            
029        if ( !(parent instanceof Pane) ) return elements;
030        
031        for (Node node : ((Pane)parent).getChildren()) {
032            if (type.isAssignableFrom(node.getClass()) && condition != null && condition.test(node) ) 
033                elements.add((T) node);
034            if (node instanceof Pane && recursive) 
035                elements.addAll(getNodes((Pane) node, type, condition, recursive));
036        }
037        return elements;
038    }
039    
040    
041    /**
042     * Etsii ensimmäisen ehdon täyttävän elementin containerin sisältä 
043     * @param parent containeri, josta etsitään.  Tätä ei palauteta vaikka täyttäisi ehdon
044     * @param type mitä tyyppiä elementin on oltavat, esimerkksi Label.class
045     *             jos halutaan kaikki, voi käyttää Node.class
046     * @param condition ehto, jolla elementti hyväksytään, esimerkkisi n -> "HA".equals(n.getId())
047     * @param recursive etsitäänkö rekursiivisesti
048     * @return ehdon täyttävä elementti tai null jos ei löydy
049     */
050    @SuppressWarnings("unchecked")
051    public static <T> T getNode(Node parent, Class<T> type, Predicate<Node> condition, boolean recursive) {
052        if ( !(parent instanceof Pane) ) return null;
053        
054        for (Node node : ((Pane)parent).getChildren()) {
055            if (type.isAssignableFrom(node.getClass()) && condition != null && condition.test(node) ) 
056                return (T)node;
057            if (node instanceof Pane && recursive) { 
058                T result = getNode((Pane) node, type, condition, recursive);
059                if ( result != null ) return result;
060            }    
061        }
062        return null;
063    }
064
065}