Reference and Guidelines for Dynamic Layout using

2019-08-09 13:14发布

问题:

I am using FXML via Scene Builder to establish some JavaFX scenes and formatting templates. Having scanned the web and Oracle tutorials, I still find determining the 'rules' around how layouts size/wrap/fit-contents/etc. and spacing between elements and compoents to be 90% a black art to me. What I'm missing is the "layout overview" (missing chapter) that puts FXML (and JavaFX) layouts all together. If you've come across such a creature, please share link(s).

To date I've only found small bits of information. For example the:

  • JavaFX References
  • JavaFx JavaDocs
  • Java CSS Reference

Give some useful infomation on one attribute, parameter or characteristic. There seems to be nothing outlining the big picture nor making an effort to connect the dots between say "font-family" to (what are) "valid fonts"?

Also I'm looking for some examples that do more business or applications type work. More real-world(tm) examples like a data entry form that takes details with text fields, comboboxes, radio buttons, etc. Doing 'normal' on-screen things not just looking shiny graphics to show what JavaFX might do.

The main thing that I see as missing is a description relating the different JavaFX containers and elements and relating them together for formatted-appearance, formatted-layout, rendered-sizing relating to each other.

Forgive me for giving an example that sounds like a critism, it isn't intended to be I simply haven't found the information to let me satisfy some simple requirements:

  1. Want a dynamic layout that will work on different sized displays/windows.
  2. Some screne areas will need to size according to the content. More or less what I'd describe as, fit-to-content.
  3. Other areas may need to be fixed width or height (as constraints).
  4. The remaining parts of the formetted-layout would shrink or grow depending on the size and capacity of the window.
  5. I want this in FXML: so that we can have a menu of layout styles with the same information (as views). That way we are expecting to match display with the best layout.

I can list the main, specific roadblocks I've come across (next). The thing I accept is that there are gaps in my knowldge and in what I'm reading about how containter work, how do min-prefered-max widths and heights work? How to they interact, etc.? That may be too large a question for now. I can give an example and some specifics to follow and leave it to the wisdom of the crowd ...

Example

  | col-01   |  col-02 | col-03 | col-04   |  col-04 |
  |          |         |        |          |         |
  |  expand  |  fixed  | scale  |  expand  |   fit   |
  |          | percent |conetnet|          | content |
  |          |         |        |          |         |

Specifics:

  1. If I used a GridPane, there is NO properties or style field in SceneBuilder for the columns or rows.
    • Question: can I code style for GridPane rows and columns in the FXML file?
  2. Percentages are not valid in most places (Java CSS Reference). Where can we use a percent and not use percent.
  3. I want the columns with "expand" to grow/shrink according to the display size.
  4. Fit content shouldn't expand (or only expand moderately).
  5. Scale content should expand/shrink to suit the 'remaining space' and at the same time I want the content to 'fit-space' (which will normally be a graphic or other media)
  6. What are the VALID CSS styles for elements.
    • What are the VALID values for the different JavaFX CCS styles?
    • Which style (path) selectors and combination work for JavaFX?

I still believe these constraints are do-able with JavaFX. I want the "outline rules" for my layout to be set-up in FXML. I feel that FXML should capable of doing what's needed provided I get the inforation about how to combine and set-up my layouts to satisfy the deploymed display constraints.

I'm expecting all these answers are not all in one place. As this is my second time (project) where I needed to know these things. I would prefer to get things working with a little less brute force this time because we want the flexibility offered with FXML definitions. I also think lots of us want to know how to do this but JavaFX styling is not the same as HTML. My thanks in advance.

see also:

  • FXML Guice, could be very useful.

回答1:

Almost all of your specific questions can be answered by using the ColumnConstraints on a GridPane. Have a look at the "Work with layouts" chapter in the official tutorial.

Note that, unlike HTML (where CSS is used for both style and layout), in JavaFX CSS is not really intended to be used for layout, but just for the "look" of the application. (Clearly, there are some gray areas here, such as borders etc, but in my opinion there's a genuine difference in approach.) I think the question on percentages in CSS values becomes a moot point once you realize this difference.

For your specific example, and just off the top of my head, so this may not be exactly correct, you can do something like:

<GridPane>
  <columnConstraints>
    <ColumnConstraints hgrow="ALWAYS">
      <maxWidth><Double fx:constant="POSITIVE_INFINITY" /></maxWidth>
    </ColumnConstraints>
    <ColumnConstraints percentWidth="20"/>
    <ColumnConstraints hgrow="SOMETIMES" fillWidth="true"/>
    <ColumnConstraints hgrow="ALWAYS">
      <maxWidth><Double fx:constant="POSITIVE_INFINITY" /></maxWidth>
    </ColumnConstraints>
    <ColumnConstraints hgrow="NEVER" />
  </columnConstraints>

  <!-- Nodes... -->

</GridPane>

In SceneBuilder (screenshot is from 2.0, but this worked in 1.1 too), click on the "header tabs" for a column and under layout on the right you will be able to set the column constraints for that column. In this screen shot, column 1 is selected (its "header tabs" are yellow):

For your specific question 6, about css styles, I've found the CSS reference is pretty explicit about that, once you figure out how it's laid out. It lists the types and the values they take, then lists nodes, the attributes that can be used with them, and their type. The selectors are the standard css selectors, with a few pseudoclasses not being supported (documented in the introduction of the reference).

One thing that's not stated explicitly in the reference is that the "substructure" section for each Node is listing css classes. So, for example, ScrollBar (which has css class scroll-bar) has "track" listed under its substructure as a StackPane. StackPane is listed as defining a property -fx-alignment as well as inheriting all the properties of Pane, which in turn inherits all the properties of Region, such as -fx-background-color. So if I want really ugly scroll bars, I can do

.scroll-bar .track {
  -fx-background-color: purple ;
}

And if I want one particular scroll bar to be ugly, I can give it a style class (say "ugly") and do

.scroll-bar.ugly .track {
  -fx-background-color: purple ;
}

(So the usual selection rules for css apply.)

While the reference is pretty good, I do quite often dip into the default stylesheet source code to see how things are done there. This is a useful resource, and Oracle seem to actively encourage you to look at this. As well as the link from before, you can just extract it from the jfxrt.jar file with

jar xf JAVA_HOME/jre/lib/ext/jfxrt.jar com/sun/javafx/scene/control/skin/modena/modena.css