Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8186023

[JavaFX 9] Various ComboBox issues on TabPane with custom skin

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P3 P3
    • tbd
    • 9, 10
    • javafx

      I've noticed some issues when a ComboBox with a custom skin is used in a TabPane with a custom skin. Note: The issue occurs only if the ComboBox skin is specified in an external CSS file.

      - the arrow button is not placed correct, it appears in the top left corner (looks like it has no parent)
      - the selected entry does not appear
      - the width of the ComboBox is too small
      - the NPE issue on focus has been already posted - see JDK-8185854

      Please find the related test below - tested with Java 9u175

      package test.combobox;

      import java.lang.reflect.Field;

      import javafx.application.Application;
      import javafx.collections.FXCollections;
      import javafx.geometry.Insets;
      import javafx.scene.Node;
      import javafx.scene.Parent;
      import javafx.scene.Scene;
      import javafx.scene.control.ComboBox;
      import javafx.scene.control.Tab;
      import javafx.scene.control.TabPane;
      import javafx.scene.control.skin.ComboBoxBaseSkin;
      import javafx.scene.layout.BorderPane;
      import javafx.scene.layout.FlowPane;
      import javafx.scene.layout.StackPane;
      import javafx.stage.Stage;

      public class ComboTabPaneTest extends Application
      {

        public static void main(String[] args)
        {
          Application.launch(args);
        }

        @Override
        public void start(Stage stage)
        {
          Application.setUserAgentStylesheet(getClass().getResource("/test/combobox/style.css").toExternalForm());
          stage.setScene(new Scene(createContent()));
          stage.setTitle(getClass().getSimpleName());
          stage.show();
        }

        private Parent createContent()
        {
          TabPane tabPane = new TabPane();
          tabPane.getTabs().add(new Tab("Tab", createTabContent()));
          // Note: update package if not in test.combobox
          tabPane.setStyle("-fx-skin: 'test.combobox.ComboTabPaneTest$TabPaneSkin'");
          
          BorderPane content = new BorderPane();
          content.setCenter(tabPane);
          return content;
        }
        
        private Node createTabContent()
        {
          FlowPane p = new FlowPane();
          p.setPadding(new Insets(40));
          ComboBox<String> combo = new ComboBox<>();
          //combo.setStyle("-fx-skin: 'test.combobox.ComboTabPaneTest$ComboBoxListViewSkin'");
          combo.setItems(FXCollections.<String>observableArrayList("Regular", "ReadOnly", "Disabled", "Disabled/ReadOnly"));
          combo.setDisable(false);
          combo.setEditable(false);
          combo.setValue("ReadOnly");
          p.getChildren().add(combo);
          return p;
        }
        
        
        // TabPaneSkin class
        public static class TabPaneSkin extends javafx.scene.control.skin.TabPaneSkin
        {
          public TabPaneSkin(TabPane tabPane)
          {
            super(tabPane);
          }
        }
        
        // ComboBoxSkin class
        public static class ComboBoxListViewSkin<T> extends javafx.scene.control.skin.ComboBoxListViewSkin<T>
        {
          public ComboBoxListViewSkin(ComboBox<T> combo)
          {
            super(combo);
            StackPane arrowButton = null;
            try
            {
              Field field = ComboBoxBaseSkin.class.getDeclaredField("arrowButton");
              field.setAccessible(true);
              arrowButton = (StackPane)field.get(this);
              System.err.println("Parent of arrow-button: " + arrowButton.getParent());
            }
            catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e)
            {
              e.printStackTrace();
            }
          }
        }
      }

      style.css:
      .root {
      -fx-font: 11 Tahoma;
          -fx-text-fill: black;
      }

       .text {
          -fx-text-fill: #F00;
          -fx-font-smoothing-type: lcd;
      }

      .combo-box{
          -fx-skin: "test.combobox.ComboTabPaneTest$ComboBoxListViewSkin";
      }

      .combo-box-base{
          -fx-background-color: #0FF;
          -fx-padding: 2 2;
      }

      .combo-box-base:editable{
          -fx-background-color: #FF0;
      }

      .combo-box-base:editable > .text-field {
          -fx-border-image-source: null;
          -fx-background-color: transparent;
          -fx-padding: 1 0;
      }

      .combo-box-base > .arrow-button {
         -fx-background-color: red;
         -fx-padding: 0 4;
        }

      .combo-box-base > .arrow-button > .arrow {
          -fx-background-color: black;
          -fx-background-insets: 0 0 0 0;
          -fx-padding: 2 4;
          -fx-shape: "M 0 0 H 7 L 3.5 4 z";
      }

      /* -------------- STYLES FOR THE DEFAULT LISTVIEW-BASED COMBOBOX ------------- */

      .combo-box-popup > .list-view {
          -fx-border-style: solid;
          -fx-border-width: 1;
          -fx-border-color: black;
          -fx-background-color: white;
          -fx-background-insets: 0, 1;
      }

      .combo-box-popup > .list-view > .virtual-flow > .clipped-container > .sheet > .list-cell {
          -fx-padding: 1 10;
          /*-fx-background-color: red;*/
          /*-fx-cell-size: 10;*/
      }
      .combo-box-popup > .list-view > .virtual-flow > .clipped-container > .sheet > .list-cell:filled:selected {
          -fx-background: green;
          -fx-background-color: orange !important;
      }
      .combo-box-popup > .list-view > .virtual-flow > .clipped-container > .sheet > .list-cell:filled:hover,
      .combo-box-popup > .list-view > .virtual-flow > .clipped-container > .sheet > .list-cell:filled:selected:hover {
          -fx-background-color: silver !important;
      }
      .combo-box-popup > .list-view > .placeholder > .label {
          -fx-text-fill: blue;
      }

            Unassigned Unassigned
            wzberger Wolfgang Zitzelsberger
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: