java - honeycomb layout in javafx (with flowpane?) -


i'm trying make honeycomb flow buttons in javafx far flowpane

so far got half working using negative vgap on flowpane, resize , make 3-4 row go 3-3-1 goes wrong

i'm trying find solution keep honeycomb layout variable amounts of buttons, far havent had success. wondering if knows solution this.

edit: here basic code have @ moment

flowpane root = new flowpane(); root.sethgap(3.0); root.setvgap(-23.0); root.setalignment(pos.center);  button[] array = new button[7];  for(int = 0; <= 6; i++){     button button = new button();     button.setshape(polygon); (made polygon in same of hexagon)     array[i] = button; } root.getchildren().addall(array); 

predetermined columns/ rows

this bit more convenient using flowpane place fields.

you can observe using column spans can place buttons in gridpane: every field fills 2 columns of sqrt(3/4) times field height; odd/even rows start @ column 0/1 respectively. every field fills 3 rows , size of column constraints alternate between 1 quarter , 1 half of field height.

example

public static gridpane createhoneycomb(int rows, int columns, double size) {     double[] points = new double[12];     (int = 0; < 12; += 2) {         double angle = math.pi * (0.5 + / 6d);         points[i] = math.cos(angle);         points[i + 1] = math.sin(angle);     }     polygon polygon = new polygon(points);      gridpane result = new gridpane();     rowconstraints rc1 = new rowconstraints(size / 4);     rc1.setfillheight(true);     rowconstraints rc2 = new rowconstraints(size / 2);     rc2.setfillheight(true);      double width = math.sqrt(0.75) * size;     columnconstraints cc = new columnconstraints(width/2);     cc.setfillwidth(true);      (int = 0; < columns; i++) {         result.getcolumnconstraints().addall(cc, cc);     }      (int r = 0; r < rows; r++) {         result.getrowconstraints().addall(rc1, rc2);         int offset = r % 2;         int count = columns - offset;         (int c = 0; c < count; c++) {             button b = new button();             b.setprefsize(width, size);             b.setshape(polygon);             result.add(b, 2 * c + offset, 2 * r, 2, 3);         }     }     result.getrowconstraints().add(rc1);     return result; } 

 

flowpane-like behavior

making x position depend on row child added not idea in flowpane. instead recommend extending pane , overriding layoutchildren method place children @ custom positions.

in case following class used:

public class offsetpane extends pane {      public interface positionfunction {          public point2d getnextposition(int index, double x, double y, double width, double height);      }      private static final positionfunction default_function = new positionfunction() {          @override         public point2d getnextposition(int index, double x, double y, double width, double height) {             return new point2d(x, y);         }      };      private final objectproperty<positionfunction> hpositionfunction;     private final objectproperty<positionfunction> vpositionfunction;      private objectproperty<positionfunction> createposproperty(string name) {         return new simpleobjectproperty<positionfunction>(this, name, default_function) {              @override             public void set(positionfunction newvalue) {                 if (newvalue == null) {                     throw new illegalargumentexception();                 } else if (get() != newvalue) {                     super.set(newvalue);                     requestlayout();                 }             }          };     }      public offsetpane() {         this.hpositionfunction = createposproperty("hpositionfunction");         this.vpositionfunction = createposproperty("vpositionfunction");     }      @override     protected void layoutchildren() {         super.layoutchildren();         double width = getwidth();          list<node> children = getmanagedchildren();         final int childsize = children.size();         if (childsize > 0) {             int row = 0;             node lastrowstart = children.get(0);             node lastnode = lastrowstart;             lastrowstart.relocate(0, 0);             positionfunction hfunc = gethpositionfunction();             positionfunction vfunc = getvpositionfunction();             int index = 1;             int columnindex = 0;              while (index < childsize) {                 node child = children.get(index);                 bounds lastbounds = lastnode.getlayoutbounds();                 bounds bounds = child.getlayoutbounds();                 point2d pt = hfunc.getnextposition(columnindex, lastnode.getlayoutx(), lastnode.getlayouty(), lastbounds.getwidth(), lastbounds.getheight());                  if (pt.getx() + bounds.getwidth() > width) {                     // break row                     lastbounds = lastrowstart.getlayoutbounds();                     pt = vfunc.getnextposition(row, lastrowstart.getlayoutx(), lastrowstart.getlayouty(), lastbounds.getwidth(), lastbounds.getheight());                     child.relocate(pt.getx(), pt.gety());                      lastrowstart = child;                     row++;                     columnindex = 0;                 } else {                     child.relocate(pt.getx(), pt.gety());                     columnindex++;                 }                  lastnode = child;                  index++;             }         }     }      public final positionfunction gethpositionfunction() {         return this.hpositionfunction.get();     }      public final void sethpositionfunction(positionfunction value) {         this.hpositionfunction.set(value);     }      public final objectproperty<positionfunction> hpositionfunctionproperty() {         return this.hpositionfunction;     }      public final positionfunction getvpositionfunction() {         return this.vpositionfunction.get();     }      public final void setvpositionfunction(positionfunction value) {         this.vpositionfunction.set(value);     }      public final objectproperty<positionfunction> vpositionfunctionproperty() {         return this.vpositionfunction;     }  } 
double[] points = new double[12]; (int = 0; < 12; += 2) {     double angle = math.pi * (0.5 + / 6d);     points[i] = math.cos(angle);     points[i + 1] = math.sin(angle); } polygon polygon = new polygon(points);  offsetpane op = new offsetpane();  double fieldheight = 100; double fieldwidth = math.sqrt(0.75) * fieldheight;  (int = 0; < 23; i++) {     button button = new button();     button.setshape(polygon);     button.setprefsize(fieldwidth, fieldheight);     op.getchildren().add(button); } // horizontal placement right of last element op.sethpositionfunction((int index, double x, double y, double width, double height) -> new point2d(x + width, y));  // vertical position half size left/right depending on index , // 1/4 node height above bottom of last node op.setvpositionfunction((int index, double x, double y, double width, double height) -> new point2d(x + (index % 2 == 0 ? width : -width) / 2, y + height * 0.75)); 

Comments

Popular posts from this blog

asynchronous - C# WinSCP .NET assembly: How to upload multiple files asynchronously -

aws api gateway - SerializationException in posting new Records via Dynamodb Proxy Service in API -

asp.net - Problems sending emails from forum -