782 if (getContentBias() == Orientation.HORIZONTAL) { 783 return getInsets().getLeft() + getTileWidth() + getInsets().getRight(); 784 } 785 return computePrefWidth(height); 786 } 787 788 @Override protected double computeMinHeight(double width) { 789 if (getContentBias() == Orientation.VERTICAL) { 790 return getInsets().getTop() + getTileHeight() + getInsets().getBottom(); 791 } 792 return computePrefHeight(width); 793 } 794 795 @Override protected double computePrefWidth(double forHeight) { 796 List<Node> managed = getManagedChildren(); 797 final Insets insets = getInsets(); 798 int prefCols = 0; 799 if (forHeight != -1) { 800 // first compute number of rows that will fit in given height and 801 // compute pref columns from that 802 int prefRows = computeRows(forHeight - snapSpace(insets.getTop()) - snapSpace(insets.getBottom()), getTileHeight()); 803 prefCols = computeOther(managed.size(), prefRows); 804 } else { 805 prefCols = getOrientation() == HORIZONTAL? getPrefColumns() : computeOther(managed.size(), getPrefRows()); 806 } 807 return snapSpace(insets.getLeft()) + 808 computeContentWidth(prefCols, getTileWidth()) + 809 snapSpace(insets.getRight()); 810 } 811 812 @Override protected double computePrefHeight(double forWidth) { 813 List<Node> managed = getManagedChildren(); 814 final Insets insets = getInsets(); 815 int prefRows = 0; 816 if (forWidth != -1) { 817 // first compute number of columns that will fit in given width and 818 // compute pref rows from that 819 int prefCols = computeColumns(forWidth - snapSpace(insets.getLeft()) - snapSpace(insets.getRight()), getTileWidth()); 820 prefRows = computeOther(managed.size(), prefCols); 821 } else { 822 prefRows = getOrientation() == HORIZONTAL? computeOther(managed.size(), getPrefColumns()) : getPrefRows(); 823 } 824 return snapSpace(insets.getTop()) + 825 computeContentHeight(prefRows, getTileHeight()) + 826 snapSpace(insets.getBottom()); 827 } 828 829 private double computeTileWidth() { 830 List<Node> managed = getManagedChildren(); 831 double preftilewidth = getPrefTileWidth(); 832 if (preftilewidth == USE_COMPUTED_SIZE) { 833 double h = -1; 834 boolean vertBias = false; 835 for (int i = 0, size = managed.size(); i < size; i++) { 836 Node child = managed.get(i); 837 if (child.getContentBias() == VERTICAL) { 838 vertBias = true; 839 break; 840 } 841 } 842 if (vertBias) { 843 // widest may depend on height of tile 844 h = computeMaxPrefAreaHeight(managed, marginAccessor, -1, getTileAlignmentInternal().getVpos()); 845 } 846 return snapSize(computeMaxPrefAreaWidth(managed, marginAccessor, h, true)); 847 } 848 return snapSize(preftilewidth); 849 } 850 851 private double computeTileHeight() { 852 List<Node> managed = getManagedChildren(); 853 double preftileheight = getPrefTileHeight(); 854 if (preftileheight == USE_COMPUTED_SIZE) { 855 double w = -1; 856 boolean horizBias = false; 857 for (int i = 0, size = managed.size(); i < size; i++) { 858 Node child = managed.get(i); 859 if (child.getContentBias() == Orientation.HORIZONTAL) { 860 horizBias = true; 861 break; 862 } 863 } 864 if (horizBias) { 865 // tallest may depend on width of tile 866 w = computeMaxPrefAreaWidth(managed, marginAccessor); 867 } 868 return snapSize(computeMaxPrefAreaHeight(managed, marginAccessor, w, getTileAlignmentInternal().getVpos())); 869 } 870 return snapSize(preftileheight); 871 } 872 873 private int computeOther(int numNodes, int numCells) { 874 double other = (double)numNodes/(double)Math.max(1, numCells); 875 return (int)Math.ceil(other); 876 } 877 878 private int computeColumns(double width, double tilewidth) { 879 return Math.max(1,(int)((width + snapSpace(getHgap())) / (tilewidth + snapSpace(getHgap())))); 880 } 881 882 private int computeRows(double height, double tileheight) { 883 return Math.max(1, (int)((height + snapSpace(getVgap())) / (tileheight + snapSpace(getVgap())))); 884 } 885 886 private double computeContentWidth(int columns, double tilewidth) { 887 if (columns == 0) return 0; 888 return columns * tilewidth + (columns - 1) * snapSpace(getHgap()); 889 } 890 891 private double computeContentHeight(int rows, double tileheight) { 892 if (rows == 0) return 0; 893 return rows * tileheight + (rows - 1) * snapSpace(getVgap()); 894 } 895 896 @Override protected void layoutChildren() { 897 List<Node> managed = getManagedChildren(); 898 HPos hpos = getAlignmentInternal().getHpos(); 899 VPos vpos = getAlignmentInternal().getVpos(); 900 double width = getWidth(); 901 double height = getHeight(); 902 double top = snapSpace(getInsets().getTop()); 903 double left = snapSpace(getInsets().getLeft()); 904 double bottom = snapSpace(getInsets().getBottom()); 905 double right = snapSpace(getInsets().getRight()); 906 double vgap = snapSpace(getVgap()); 907 double hgap = snapSpace(getHgap()); 908 double insideWidth = width - left - right; 909 double insideHeight = height - top - bottom; 910 911 double tileWidth = getTileWidth() > insideWidth ? insideWidth : getTileWidth(); 912 double tileHeight = getTileHeight() > insideHeight ? insideHeight : getTileHeight(); 913 914 int lastRowRemainder = 0; 915 int lastColumnRemainder = 0; 916 if (getOrientation() == HORIZONTAL) { 917 actualColumns = computeColumns(insideWidth, tileWidth); 918 actualRows = computeOther(managed.size(), actualColumns); 919 // remainder will be 0 if last row is filled 920 lastRowRemainder = hpos != HPos.LEFT? 921 actualColumns - (actualColumns*actualRows - managed.size()) : 0; 922 } else { 923 // vertical 924 actualRows = computeRows(insideHeight, tileHeight); 925 actualColumns = computeOther(managed.size(), actualRows); 926 // remainder will be 0 if last column is filled 927 lastColumnRemainder = vpos != VPos.TOP? | 782 if (getContentBias() == Orientation.HORIZONTAL) { 783 return getInsets().getLeft() + getTileWidth() + getInsets().getRight(); 784 } 785 return computePrefWidth(height); 786 } 787 788 @Override protected double computeMinHeight(double width) { 789 if (getContentBias() == Orientation.VERTICAL) { 790 return getInsets().getTop() + getTileHeight() + getInsets().getBottom(); 791 } 792 return computePrefHeight(width); 793 } 794 795 @Override protected double computePrefWidth(double forHeight) { 796 List<Node> managed = getManagedChildren(); 797 final Insets insets = getInsets(); 798 int prefCols = 0; 799 if (forHeight != -1) { 800 // first compute number of rows that will fit in given height and 801 // compute pref columns from that 802 int prefRows = computeRows(forHeight - snapSpaceY(insets.getTop()) - snapSpaceY(insets.getBottom()), getTileHeight()); 803 prefCols = computeOther(managed.size(), prefRows); 804 } else { 805 prefCols = getOrientation() == HORIZONTAL? getPrefColumns() : computeOther(managed.size(), getPrefRows()); 806 } 807 return snapSpaceX(insets.getLeft()) + 808 computeContentWidth(prefCols, getTileWidth()) + 809 snapSpaceX(insets.getRight()); 810 } 811 812 @Override protected double computePrefHeight(double forWidth) { 813 List<Node> managed = getManagedChildren(); 814 final Insets insets = getInsets(); 815 int prefRows = 0; 816 if (forWidth != -1) { 817 // first compute number of columns that will fit in given width and 818 // compute pref rows from that 819 int prefCols = computeColumns(forWidth - snapSpaceX(insets.getLeft()) - snapSpaceX(insets.getRight()), getTileWidth()); 820 prefRows = computeOther(managed.size(), prefCols); 821 } else { 822 prefRows = getOrientation() == HORIZONTAL? computeOther(managed.size(), getPrefColumns()) : getPrefRows(); 823 } 824 return snapSpaceY(insets.getTop()) + 825 computeContentHeight(prefRows, getTileHeight()) + 826 snapSpaceY(insets.getBottom()); 827 } 828 829 private double computeTileWidth() { 830 List<Node> managed = getManagedChildren(); 831 double preftilewidth = getPrefTileWidth(); 832 if (preftilewidth == USE_COMPUTED_SIZE) { 833 double h = -1; 834 boolean vertBias = false; 835 for (int i = 0, size = managed.size(); i < size; i++) { 836 Node child = managed.get(i); 837 if (child.getContentBias() == VERTICAL) { 838 vertBias = true; 839 break; 840 } 841 } 842 if (vertBias) { 843 // widest may depend on height of tile 844 h = computeMaxPrefAreaHeight(managed, marginAccessor, -1, getTileAlignmentInternal().getVpos()); 845 } 846 return snapSizeX(computeMaxPrefAreaWidth(managed, marginAccessor, h, true)); 847 } 848 return snapSizeX(preftilewidth); 849 } 850 851 private double computeTileHeight() { 852 List<Node> managed = getManagedChildren(); 853 double preftileheight = getPrefTileHeight(); 854 if (preftileheight == USE_COMPUTED_SIZE) { 855 double w = -1; 856 boolean horizBias = false; 857 for (int i = 0, size = managed.size(); i < size; i++) { 858 Node child = managed.get(i); 859 if (child.getContentBias() == Orientation.HORIZONTAL) { 860 horizBias = true; 861 break; 862 } 863 } 864 if (horizBias) { 865 // tallest may depend on width of tile 866 w = computeMaxPrefAreaWidth(managed, marginAccessor); 867 } 868 return snapSizeY(computeMaxPrefAreaHeight(managed, marginAccessor, w, getTileAlignmentInternal().getVpos())); 869 } 870 return snapSizeY(preftileheight); 871 } 872 873 private int computeOther(int numNodes, int numCells) { 874 double other = (double)numNodes/(double)Math.max(1, numCells); 875 return (int)Math.ceil(other); 876 } 877 878 private int computeColumns(double width, double tilewidth) { 879 double snappedHgap = snapSpaceX(getHgap()); 880 return Math.max(1,(int)((width + snappedHgap) / (tilewidth + snappedHgap))); 881 } 882 883 private int computeRows(double height, double tileheight) { 884 double snappedVgap = snapSpaceY(getVgap()); 885 return Math.max(1, (int)((height + snappedVgap) / (tileheight + snappedVgap))); 886 } 887 888 private double computeContentWidth(int columns, double tilewidth) { 889 if (columns == 0) return 0; 890 return columns * tilewidth + (columns - 1) * snapSpaceX(getHgap()); 891 } 892 893 private double computeContentHeight(int rows, double tileheight) { 894 if (rows == 0) return 0; 895 return rows * tileheight + (rows - 1) * snapSpaceY(getVgap()); 896 } 897 898 @Override protected void layoutChildren() { 899 List<Node> managed = getManagedChildren(); 900 HPos hpos = getAlignmentInternal().getHpos(); 901 VPos vpos = getAlignmentInternal().getVpos(); 902 double width = getWidth(); 903 double height = getHeight(); 904 double top = snapSpaceY(getInsets().getTop()); 905 double left = snapSpaceX(getInsets().getLeft()); 906 double bottom = snapSpaceY(getInsets().getBottom()); 907 double right = snapSpaceX(getInsets().getRight()); 908 double vgap = snapSpaceY(getVgap()); 909 double hgap = snapSpaceX(getHgap()); 910 double insideWidth = width - left - right; 911 double insideHeight = height - top - bottom; 912 913 double tileWidth = getTileWidth() > insideWidth ? insideWidth : getTileWidth(); 914 double tileHeight = getTileHeight() > insideHeight ? insideHeight : getTileHeight(); 915 916 int lastRowRemainder = 0; 917 int lastColumnRemainder = 0; 918 if (getOrientation() == HORIZONTAL) { 919 actualColumns = computeColumns(insideWidth, tileWidth); 920 actualRows = computeOther(managed.size(), actualColumns); 921 // remainder will be 0 if last row is filled 922 lastRowRemainder = hpos != HPos.LEFT? 923 actualColumns - (actualColumns*actualRows - managed.size()) : 0; 924 } else { 925 // vertical 926 actualRows = computeRows(insideHeight, tileHeight); 927 actualColumns = computeOther(managed.size(), actualRows); 928 // remainder will be 0 if last column is filled 929 lastColumnRemainder = vpos != VPos.TOP? |