G52GUI CSS Tutorial Contents

Page created by Josephine Pearson
 
CONTINUE READING
G52GUI CSS Tutorial Contents
1    CSS Tutorial

    G52GUI CSS Tutorial
    Contents
    Introduction .................................................................................... 1
    Selectors ........................................................................................ 1
    Declarations .................................................................................... 4
    Styling your GUI ............................................................................... 5
    Styling FXML vs. Styling HTML .............................................................. 8
    Useful Links .................................................................................... 8

    Introduction
    Cascading Style Sheets, or CSS, is a styling language for describing and setting the layout
    for markup languages. Most commonly, it is used to set the styling and format of HTML and
    XHTML in websites, but it can be used with any type of XML document, including FXML.

    .button {                                           /*   Set style for all buttons */
        -fx-text-fill: #dddddd;                         /*   Sets font colour (hex) */
        -fx-background-color: #444349;                  /*   Sets background colour */
        -fx-padding: 5px;                               /*   Inner spacing on all sides */
    }

    .button#ok {                                        /* Set style for just OK button */
        -fx-font-weight: bold;                          /* Set font to bold */
    }

    The above code is an example of the CSS layout style for setting the properties of an
    object. This code will set the text colour, background colour and padding (inner spacing)
    for all buttons. Additionally, for only the ‘ok’ button, the font is set to bold. As the name
    implies, CSS properties are cascading, meaning that in the markup hierarchy, objects will
    inherit the properties of their parent, unless it is otherwise stated.

    This tutorial will introduce the basics of CSS, along with its use with JavaFX and
    FXML/Scene Builder 2. Following this, a small example of styling the tutorial GUI is given.
    It is important to remember that CSS cannot change the content or structure of your FXML
    file, it can only affect the appearance – CSS is not a scripting language.

    Selectors
    There are two main types of identifiers when using CSS: classes and ids. The former is
    used when you want to give a series of objects the same properties, such as giving all
    buttons the same colouring style, or setting the font for a particular type of label. The ID
2    CSS Tutorial

    is used to define the properties for a single object where you want to identify that specific
    item in your FXML document.

    The format for accessing classes in CSS is to precede its name with a full-stop “.”, e.g.
    .button will be used to set the properties for all items with the class “button”. Similarly,
    the properties of individual items can be changed using the “#” symbol, appending it to
    the ID, e.g. #ok will allow you to change the properties of an object with id “ok”.

    Note that there may be multiple objects of different classes with the same ID, such as a
    label and a text-field both named “firstname”. You can distinguish between these by using
    the class identifier, which forms a ‘parent’ of each object:

    .label#firstname{
        /* styling for label named firstname */
    }
    .text-field#firstname{
        /* styling for text-field named firstname */
    }

    The above code shows the chaining of classes and ids to be more specific in your styling.
    This is also the case with style cascading, where an element will inherit features of its
    ‘parents’ in the XML layout. The following snippet of code demonstrates an example FXML
    layout. While this has been simplified greatly, it is similar in idea to the tutorial example:
    a Pane containing a SplitPane, which contains a left and a right AnchorPane. These
    contain labels and a text-field: the left contains two labels; the right contains one label
    and one text-field.
3    CSS Tutorial

    The above example can be styled using the following example stylesheet. For now we
    won’t actually show the styling code, but identify which objects will be affected by each
    selector block.

    .root {
        /* Sets the default style for all items */
    }

    .anchor-pane {
        /* Sets the default style for all items contained in an AnchorPane */
        /* Overrides any previous properties of parent tags or root */
    }

    .anchor-pane#right {
        /* Sets the style for the AnchorPane with id “right” (only) */
    }

    .anchor-pane .label {
        /* Sets the style for any Labels that are children of an AnchorPane */
    }

    .label,
    .text-field {
        /* Sets the common properties of all Labels and TextField */
    }

    #left .label {
        /* Sets the style for all child Labels of a tag with id “left” */
    }

    .label#label-italic {
        /* Sets the style for a Label with id “label-italic” */
        /* Note the lack of spacing between the class and id */
    }

    .anchor-pane #label-bold {
        /* Sets the style for tag with the id “label-bold” in an AnchorPane */
        /* The space means the id belongs to a child, not an AnchorPane */
    }

    .anchor-pane.label#label-bold {
        /* An unambiguous equivalent of the above block: specifies the style
           of a Label with id “label-bold” that is a child of an AnchorPane */
    }

    The above code outlines a few different ways of using CSS. There is versatility in the
    cascading of styles, but often it can cause unintended effects if not checked properly. An
4    CSS Tutorial

    example of this is the use of spacing between classes and ids. In the last three cases, you
    can see the distinction between the .class#id and .class #id in that the first will look
    for an object of that class with that id, where as the second will look for an object with
    that id that is a child of the class.

    It is also possible to set common properties of multiple classes without using the
    cascading, but simply using the comma-separation of classes as the block selector: see
    .label, .text-field which will set the style properties for all labels and all text-fields
    regardless of their hierarchy.

    Note that the Pane is the parent tag for all objects, so the properties set for it will
    cascade down to all its children unless they are overridden. This is the same, then, for the
    AnchorPane, and indeed the styling for the right AnchorPane (.anchor-pane#right).

    The .root class is the parent for all objects, so any properties set in the .root selector
    will be the global values unless overridden for specific classes.

    Psuedo-classes are one additional type of selector. These are classes with an appended
    state, which is used to distinguish the style between certain actions. Pseudo-classes are
    appended to a selector with the colon operator ‘:’, e.g. .class:state. These allow you
    to override certain style of a class based on certain actions, although the types of
    interactions are quite limited. The most common state is “hover”, which will trigger when
    the mouse is moved over it. Having a pseudo-class does not override the properties of the
    main class, unless specified explicitly in the CSS file. Other general pseudo-states include
    “pressed” and “focused”.

    Declarations
    Aside from selectors, declarations are needed to actually set the properties of your style.
    These describe the various properties, from fonts and colours to borders and padding. In
    JavaFX, all property declarations begin with “-fx-”. These are added to the selector
    blocks and will set the properties of the elements that match up to this.

    Declarations are made up of two parts: the property name and its value, separated by a
    colon:

        -fx-property-name: value;         /* comment */

    Each separate declaration must end with a semi-colon ‘;’. If the same declaration is
    called multiple times in the same selector block, the last call is the one that is used.

    Property values typically come in 3 types: the numeric value, e.g. for setting the size of
    something; text value, e.g. font types or urls; and colours. Numeric value properties can
    often have the units specified, such as when setting the size of a border you can specify
    centimetres (cm), pixels (px), or points (pt). Note when setting font-size, this is normally
    in pt, e.g. 11pt.

    String values vary more on the property, for example, you can specify a border type as
    ‘solid’ or ‘dashed’, or the font-family, ‘Arial’ or ‘sans-serif’.
5    CSS Tutorial

    Colour types are slightly different in that you can set the using a named colour (e.g. red),
    using hexadecimal values (#F0AAAA), or even by specifying the red-green-blue values
    (rgb(240, 170, 170)). A colour picker tool for getting the rgb or hex values is available
    here, and a list of pre-named colours in JavaFX can be found here.

    Some declarations allow a chain of properties that sets multiple properties in one line. For
    example, the –fx-font property:

    .root { /* base properties for all objects */
        -fx-font: bold 12pt “Arial”
    }

    This is equivalent to the following:

    .root { /* base properties for all objects */
        -fx-font-family: “Arial”;
        -fx-font-weight: bold;
        -fx-font-size: 12pt;
    }

    Note that for font-family, the given value is a string of three fonts. This effectively means
    that the font will be Arial, unless it is not found in the font library of the system it is
    running on, in which case it will be Helvetica. If neither of those is present, it defaults to
    the system’s base sans-serif font.

    To set the font colour, the declaration parameter name is ‘text-fill’, e.g.

         –fx-text-fill: blue;

    Styling your GUI
    Now you have an understanding of CSS, you can apply it to your PersonView from the
    tutorials. It is important to note that the ‘id’s in CSS are NOT the same as ‘fx:id’. The
    former is used by the styling, the latter by
    the Controller. First, we will look at the
    PersonView.fxml file in SceneBuilder. For
    your labels on the right hand side of the right
    AnchorPane, e.g. firstNameLabel, select
    each of them. On the right hand side of
    SceneBuilder, in the ‘Properties’ tab, set the
    ‘Style Class’ to “information”. Make sure you
    click the ‘+’ button. For the “Details” Label,
    add “details” as its ‘Id’ in the CSS properties
    tab. Save in SceneBuilder, and refresh your
    Project in Eclipse.
6    CSS Tutorial

    .root {            /* base properties for all objects */
        -fx-font: 12pt "Arial";    /* set default font */
        -fx-text-fill: #dddddd;           /* set default text colour */
        -fx-background: #444349;          /* set background colour */
        -fx-base: #444349;                /* set base window colour */
        -fx-focus-color: transparent;     /* remove focus colour */
        -fx-accent: #808080;              /* selection colour */
    }
    .menu-bar,                        /* menu bar and menu items */
    .context-menu {
        -fx-background-color: #f2f2f280; /* set to be 50% transparent (rrggbbaa) */
    }
    .context-menu .label {            /* set text colour for menu labels */
        -fx-text-fill: #444349;
    }
    .table-view {                     /* make table view transparent */
        -fx-base: transparent;                        /* base colour */
        -fx-control-inner-background: transparent;    /* background colour */
        -fx-table-cell-border-color: transparent;     /* border colour */
        -fx-table-header-border-color: transparent; /* header border colour */
    }
    .table-view:row-selection,        /* set selection properties */
    .table-view:col-selection {
        -fx-background-color: transparent;            /* make transparent */
        -fx-text-fill: #444349;                       /* change selection colour */
    }
    .table-view .column-header-background {
        -fx-background-color: transparent;            /* make header transparent */
    }
    .table-view .column-header,       /* remove borders for table contents */
    .table-view .filler {
        -fx-border-color: transparent;
        -fx-background-color: transparent;
    }
    .table-view .column-header .label { /* set properties of header label */
        -fx-text-fill: #f2f2f2;
        -fx-font-size: 18pt;             /* increase font size (from 12pt) */
    }
    .label.information {                 /* labels with class ‘information’ */
        -fx-font-style: italic;                      /* make italics */
    }
    .label#details {                     /* label with id ‘details’ */
        -fx-font-size: 14pt;                   /* increase font size (from 12pt) */
        -fx-font-weight: bold;                 /* make font bold */
        -fx-underline: true;                   /* underline text */
    }
    .button {                            /* properties for all buttons */
        -fx-font-size: 10pt;                   /* decrease font size (from 12pt) */
        -fx-text-fill: #444349;                /* change text colour */
        -fx-pref-height: 30px;                 /* set preferred height */
        -fx-padding: 10px;                     /* set inner padding */
        -fx-background-color: #f2f2f2;         /* set background colour */
        -fx-background-radius: 0;              /* make button have sharp corners */
        -fx-border-radius: 0;                  /* make border have sharp corners */
        -fx-border-color: #dddddd;             /* set border colour */
        -fx-border-width: 1px;                 /* set border thickness */
    }
7    CSS Tutorial

    The above code is the CSS to style your GUI. To add this project, create a new File in your
    ‘view’ package (right-click ‘view’ > New > Other… > General > File). Name it
    ‘MyTheme.css’, and copy the above code into it.

    There a multiple ways to assign a stylesheet to a Scene. The first way, we will assign it
    within Scene Builder. Open RootLayout.fxml in Scene Builder, and select the
    BorderPane. On the right hand side, again in ‘Properties’, click the ‘+’ under
    ‘Stylesheets’. Navigate to your ‘src/view’ folder and select ‘MyTheme.css’. Save and
    refresh your project. Running the project now should style both the RootLayout and the
    embedded PersonView.fxml due to the nature of the FXML hierarchy.

    However, if you click either the New… or Edit… buttons, the new window is NOT styled by
    your CSS file. This is because it belongs to a separate Scene. The next step is an example
    of how to assign a stylesheet programmatically to a window.

    For the PersonEdit window, you can assign the stylesheet in Scene Builder, as with the
    RootLayout, or add the following line of code to your showPersonEdit() method after
    the new Scene is created:

    Scene scene = new Scene(personEdit); // !! Existing code !!
    scene.getStylesheets().add(“view/MyTheme.css”); // Add stylesheet
8       CSS Tutorial

    Styling FXML vs. Styling HTML
    This section is for those who are familiar with CSS for styling websites, to highlight the
    differences between using CSS with JavaFX and HTML. There are some notable
    distinctions.

         All declaration begin with –fx- when styling FXML files
         There are no selectors for specific tags, like div for  when styling HTML
              o You should use the class equivalent, like .button for 
         Most objects inherit the Node tag, which has a specific set of pseudo-classes
              o Not all pseudo-classes are supported
              o :active is replaced by :pressed
              o :focus is replaced by :focused
         The FXML CSS parser will return an Exception when a declaration is not valid for that
          object
              o This can be useful to find where styling is not working as it should
         The color declaration for changing the font colour does not work consistently
              o You should use -fx-text-fill instead
         Neither –fx-background or –fx-border can be used to chain commands, so the sub-
          declarations should be called, e.g.
              o –fx-background-color, -fx-background-image
              o –fx-border-color, -fx-border-width
         The width and margin declarations are not valid
              o You can set the preferred width using –fx-pref-width
         The FXML CSS parser does not support comma separated strings of font families

    Useful Links
    Oracle JavaFX 8 CSS Reference:
    http://docs.oracle.com/javase/8/javafx/api/javafx/scene/doc-files/cssref.html

    Oracle Tutorial Styling a JavaFX UI with CSS:
    http://docs.oracle.com/javase/8/javafx/user-interface-tutorial/apply-css.htm

    W3 Schools CSS Tutorial:
    http://www.w3schools.com/css/

    W3 Colour Picker / RGB to Hex Converter
    http://www.w3schools.com/tags/ref_colorpicker.asp
You can also read