-
Bug
-
Resolution: Unresolved
-
P4
-
8, 9
-
generic
-
generic
FULL PRODUCT VERSION :
1.8 u121 x64
ADDITIONAL OS VERSION INFORMATION :
Windows 8.1 x64
A DESCRIPTION OF THE PROBLEM :
GridPane has problems with Nodes with ColSpan and PrefSize
create 2 Columns with PrefSize
every column chaange size to an day Label (day of week)
add a new Label with
- colSpan = 2
- minWidth to USE_PREF_SIZE
- text large as 2 existing columns
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
employeeCount = 1
2 Columns generated
first column set size to [X] Label
second column span to size from label [longlonglong]
http://194.25.240.197:9980/gridpane.layout.work.png
employeeCount = 2
last column dont change size to label [longlonglong]
http://194.25.240.197:9980/gridpane.layout.not.work.png
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
resize columns to ColSpan Label
ACTUAL -
in some cases the Columns dont change its size
the ColSpan Labels is overlab tu next / prev Columns
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package GridPaneLayout;
import java.time.DayOfWeek;
import java.time.format.DateTimeFormatter;
import java.util.LinkedList;
import java.util.List;
import com.sun.javafx.css.StyleManager;
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;
import javafx.stage.Stage;
/** @author sst */
public class GridPaneLayoutMain extends Application {
private static final double MAX_VALUE = Double.MAX_VALUE;
private static final double USE_PREF_SIZE = Double.NEGATIVE_INFINITY;
private static final double USE_COMPUTED_SIZE = -1.0;
private static final String CSS = GridPaneLayoutMain.class.getResource("Planung.css").toExternalForm();
private static final DateTimeFormatter DAY = DateTimeFormatter.ofPattern("EEE");
public static void main(String[] args) {
StyleManager.getInstance().addUserAgentStylesheet(CSS);
launch(GridPaneLayoutMain.class, args);
}
@Override
public void start(final Stage primaryStage) throws Exception {
// Grid
final GridPane grid = new GridPane();
grid.setMinSize(USE_PREF_SIZE, USE_PREF_SIZE);
grid.setPrefSize(USE_COMPUTED_SIZE, USE_COMPUTED_SIZE);
grid.setMaxSize(USE_PREF_SIZE, USE_PREF_SIZE);
grid.setPadding(new Insets(4));
grid.getStylesheets().add(CSS);
// Root
final BorderPane root = new BorderPane();
root.setCenter(new ScrollPane(grid));
// Create
final Button create = new Button("create");
root.setTop(create);
create.setOnAction((event) -> grid(grid));
// show
primaryStage.setScene(new Scene(root, 400, 400));
primaryStage.show();
}
private final void grid(final GridPane grid) {
// clear
grid.getChildren().clear();
grid.getColumnConstraints().clear();
grid.getRowConstraints().clear();
final int sectionCount = 1;
// 1 works, > 1 triggers layouting problem
final int employeeCount = 2;
final int dayOfWeeks = 2;
final List<Node> nodes = new LinkedList<>();
int rowIndex = 0;
int columnIndex = 0;
// for all section
for (int si = 0; si < sectionCount; si++) {
// Start index for section
final int sectionIndex = columnIndex;
// Span of section
// employeeCount * (dayOfWeeks for employee)
// not all employees have the same [dayOfWeek]
// possible fomr 1 to 5
int sectionSpan = 0;
// for all employee in this section
for (int ei = 0; ei < employeeCount; ei++) {
rowIndex = 3;
nodes.add(createEmployeeLabel(columnIndex, dayOfWeeks, si, ei));
for (int d = 0; d < dayOfWeeks; d++) {
nodes.add(createHeaderDayLabel(columnIndex + d, d));
sectionSpan++;
}
// Holiday
{
nodes.add(createHolidayLabel(rowIndex++, columnIndex));
}
// leave
{
}
// work
{
nodes.add(createWorkLabel("long\nlong", rowIndex++, columnIndex, 2));
nodes.add(createWorkLabel("longlonglong", rowIndex++, columnIndex, 2));
// nodes.add(createWorkLabel("_", rows++, columnIndex + 1,
// 1));
}
// Empty
{
nodes.add(createEmptyLabel(rowIndex++, columnIndex, dayOfWeeks));
// nodes.add(createEmptyLabel(rows++, dataIndex,
// dayOfWeeks));
// nodes.add(createEmptyLabel(rows++, dataIndex,
// dayOfWeeks));
}
// next empleyee is current + days per week
columnIndex += dayOfWeeks;
}
// create last
// on this position the current CollSpan for Section is calculated
nodes.add(createSectionLabel(si, sectionIndex, sectionSpan));
}
// constraints
for (int r = 0; r < rowIndex; r++) {
grid.getRowConstraints().add(new RowConstraints(USE_PREF_SIZE, USE_COMPUTED_SIZE, MAX_VALUE, Priority.NEVER, VPos.CENTER, true));
}
for (int c = 0; c < columnIndex; c++) {
grid.getColumnConstraints().add(new ColumnConstraints(USE_PREF_SIZE, USE_COMPUTED_SIZE, MAX_VALUE, Priority.NEVER, HPos.CENTER, true));
}
grid.getChildren().addAll(nodes);
}
// Headers#############################################################################################################################
private final GridLabel createSectionLabel(final int si, final int sectionIndex, final int sectionSpan) {
final GridLabel label = new GridLabel("Section " + si, "planung-header", "planung-header-bereich");
label.setIndex(0, sectionIndex);
label.setSpan(1, sectionSpan);
return label;
}
private final GridLabel createEmployeeLabel(final int column, final int span, final int si, final int mi) {
final GridLabel label = new GridLabel("M." + si + "." + mi, "planung-header", "planung-header-mitarbeiter");
label.setIndex(1, column);
label.setSpan(1, span);
return label;
}
private final GridLabel createHeaderDayLabel(final int column, final int day) {
final GridLabel label = new GridLabel(DAY.format(DayOfWeek.of(day + 1)), "planung-header", "planung-header-tag");
label.setIndex(2, column);
return label;
}
// Data################################################################################################################################
private final GridLabel createHolidayLabel(final int row, final int column) {
final GridLabel label = new GridLabel("X", "planung-item", "planung-feiertag", "planung-abwesenheit");
label.setIndex(row, column);
return label;
}
private final GridLabel createEmptyLabel(final int row, final int column, final int span) {
final GridLabel label = new GridLabel(null, "planung-item");
label.setIndex(row, column);
label.setSpan(1, span);
return label;
}
private final GridLabel createWorkLabel(final String action, final int row, final int column, final int span) {
final GridLabel label = new GridLabel(action, "planung-item", "planung-planung");
label.setIndex(row, column);
label.setSpan(1, span);
return label;
}
// classes#############################################################################################################################
/** @author sst */
private static final class GridLabel extends Label {
private static final Insets BORDER = new Insets(4);
private GridLabel(final String text, final String... css) {
// Label
super();
// Cache
this.setCache(true);
// Size
setMinSize(USE_PREF_SIZE, USE_PREF_SIZE);
setPrefSize(USE_COMPUTED_SIZE, USE_COMPUTED_SIZE);
setMaxSize(MAX_VALUE, MAX_VALUE);
// Border
setPadding(BORDER);
// Text Position
setAlignment(Pos.CENTER);
// Grid Settings
setIndex(0, 0);
setSpan(1, 1);
// CSS
addCssClasses("planung-base");
addCssClasses(css);
setText(text);
}
private final void setIndex(final int row, final int column) {
GridPane.setRowIndex(this, Integer.valueOf(row));
GridPane.setColumnIndex(this, Integer.valueOf(column));
}
private final void setSpan(final int row, final int column) {
GridPane.setRowSpan(this, Integer.valueOf(row));
GridPane.setColumnSpan(this, Integer.valueOf(column));
}
private final void addCssClasses(final String... cssClasses) {
getStyleClass().addAll(cssClasses);
}
}
}
------------------
/* Planung.css */
.planung-base{
-fx-border-color: black !important;
-fx-border-insets: -1px 0px 0px -1px !important;
}
.planung-header{
-fx-font-weight: bold !important;
-fx-background-color: #E6E6E6 !important;
}
.planung-header-bereich{
/* top, right, bottom, and left */
-fx-border-width: 1px 1px 0px, 1px !important;
}
.planung-header-mitarbeiter{
/* top, right, bottom, and left */
-fx-border-width: 0px 1px 0px, 1px !important;
}
.planung-header-tag{
/* top, right, bottom, and left */
-fx-font-weight: normal !important;
-fx-font-size: 10 !important;
-fx-border-width: 0px 1px 1px, 1px !important;
}
.planung-datum{
/* top, right, bottom, and left */
-fx-border-width: 1px 1px 1px, 1px !important;
}
.planung-item{
/* top, right, bottom, and left */
-fx-border-width: 1px 1px 1px, 1px !important;
}
.planung-feiertag{
-fx-text-fill: orangered ;
}
.planung-abwesenheit{
-fx-background-color: silver !important;
}
.planung-planung{
-fx-text-fill: black;
}
---------- END SOURCE ----------
1.8 u121 x64
ADDITIONAL OS VERSION INFORMATION :
Windows 8.1 x64
A DESCRIPTION OF THE PROBLEM :
GridPane has problems with Nodes with ColSpan and PrefSize
create 2 Columns with PrefSize
every column chaange size to an day Label (day of week)
add a new Label with
- colSpan = 2
- minWidth to USE_PREF_SIZE
- text large as 2 existing columns
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
employeeCount = 1
2 Columns generated
first column set size to [X] Label
second column span to size from label [longlonglong]
http://194.25.240.197:9980/gridpane.layout.work.png
employeeCount = 2
last column dont change size to label [longlonglong]
http://194.25.240.197:9980/gridpane.layout.not.work.png
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
resize columns to ColSpan Label
ACTUAL -
in some cases the Columns dont change its size
the ColSpan Labels is overlab tu next / prev Columns
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package GridPaneLayout;
import java.time.DayOfWeek;
import java.time.format.DateTimeFormatter;
import java.util.LinkedList;
import java.util.List;
import com.sun.javafx.css.StyleManager;
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;
import javafx.stage.Stage;
/** @author sst */
public class GridPaneLayoutMain extends Application {
private static final double MAX_VALUE = Double.MAX_VALUE;
private static final double USE_PREF_SIZE = Double.NEGATIVE_INFINITY;
private static final double USE_COMPUTED_SIZE = -1.0;
private static final String CSS = GridPaneLayoutMain.class.getResource("Planung.css").toExternalForm();
private static final DateTimeFormatter DAY = DateTimeFormatter.ofPattern("EEE");
public static void main(String[] args) {
StyleManager.getInstance().addUserAgentStylesheet(CSS);
launch(GridPaneLayoutMain.class, args);
}
@Override
public void start(final Stage primaryStage) throws Exception {
// Grid
final GridPane grid = new GridPane();
grid.setMinSize(USE_PREF_SIZE, USE_PREF_SIZE);
grid.setPrefSize(USE_COMPUTED_SIZE, USE_COMPUTED_SIZE);
grid.setMaxSize(USE_PREF_SIZE, USE_PREF_SIZE);
grid.setPadding(new Insets(4));
grid.getStylesheets().add(CSS);
// Root
final BorderPane root = new BorderPane();
root.setCenter(new ScrollPane(grid));
// Create
final Button create = new Button("create");
root.setTop(create);
create.setOnAction((event) -> grid(grid));
// show
primaryStage.setScene(new Scene(root, 400, 400));
primaryStage.show();
}
private final void grid(final GridPane grid) {
// clear
grid.getChildren().clear();
grid.getColumnConstraints().clear();
grid.getRowConstraints().clear();
final int sectionCount = 1;
// 1 works, > 1 triggers layouting problem
final int employeeCount = 2;
final int dayOfWeeks = 2;
final List<Node> nodes = new LinkedList<>();
int rowIndex = 0;
int columnIndex = 0;
// for all section
for (int si = 0; si < sectionCount; si++) {
// Start index for section
final int sectionIndex = columnIndex;
// Span of section
// employeeCount * (dayOfWeeks for employee)
// not all employees have the same [dayOfWeek]
// possible fomr 1 to 5
int sectionSpan = 0;
// for all employee in this section
for (int ei = 0; ei < employeeCount; ei++) {
rowIndex = 3;
nodes.add(createEmployeeLabel(columnIndex, dayOfWeeks, si, ei));
for (int d = 0; d < dayOfWeeks; d++) {
nodes.add(createHeaderDayLabel(columnIndex + d, d));
sectionSpan++;
}
// Holiday
{
nodes.add(createHolidayLabel(rowIndex++, columnIndex));
}
// leave
{
}
// work
{
nodes.add(createWorkLabel("long\nlong", rowIndex++, columnIndex, 2));
nodes.add(createWorkLabel("longlonglong", rowIndex++, columnIndex, 2));
// nodes.add(createWorkLabel("_", rows++, columnIndex + 1,
// 1));
}
// Empty
{
nodes.add(createEmptyLabel(rowIndex++, columnIndex, dayOfWeeks));
// nodes.add(createEmptyLabel(rows++, dataIndex,
// dayOfWeeks));
// nodes.add(createEmptyLabel(rows++, dataIndex,
// dayOfWeeks));
}
// next empleyee is current + days per week
columnIndex += dayOfWeeks;
}
// create last
// on this position the current CollSpan for Section is calculated
nodes.add(createSectionLabel(si, sectionIndex, sectionSpan));
}
// constraints
for (int r = 0; r < rowIndex; r++) {
grid.getRowConstraints().add(new RowConstraints(USE_PREF_SIZE, USE_COMPUTED_SIZE, MAX_VALUE, Priority.NEVER, VPos.CENTER, true));
}
for (int c = 0; c < columnIndex; c++) {
grid.getColumnConstraints().add(new ColumnConstraints(USE_PREF_SIZE, USE_COMPUTED_SIZE, MAX_VALUE, Priority.NEVER, HPos.CENTER, true));
}
grid.getChildren().addAll(nodes);
}
// Headers#############################################################################################################################
private final GridLabel createSectionLabel(final int si, final int sectionIndex, final int sectionSpan) {
final GridLabel label = new GridLabel("Section " + si, "planung-header", "planung-header-bereich");
label.setIndex(0, sectionIndex);
label.setSpan(1, sectionSpan);
return label;
}
private final GridLabel createEmployeeLabel(final int column, final int span, final int si, final int mi) {
final GridLabel label = new GridLabel("M." + si + "." + mi, "planung-header", "planung-header-mitarbeiter");
label.setIndex(1, column);
label.setSpan(1, span);
return label;
}
private final GridLabel createHeaderDayLabel(final int column, final int day) {
final GridLabel label = new GridLabel(DAY.format(DayOfWeek.of(day + 1)), "planung-header", "planung-header-tag");
label.setIndex(2, column);
return label;
}
// Data################################################################################################################################
private final GridLabel createHolidayLabel(final int row, final int column) {
final GridLabel label = new GridLabel("X", "planung-item", "planung-feiertag", "planung-abwesenheit");
label.setIndex(row, column);
return label;
}
private final GridLabel createEmptyLabel(final int row, final int column, final int span) {
final GridLabel label = new GridLabel(null, "planung-item");
label.setIndex(row, column);
label.setSpan(1, span);
return label;
}
private final GridLabel createWorkLabel(final String action, final int row, final int column, final int span) {
final GridLabel label = new GridLabel(action, "planung-item", "planung-planung");
label.setIndex(row, column);
label.setSpan(1, span);
return label;
}
// classes#############################################################################################################################
/** @author sst */
private static final class GridLabel extends Label {
private static final Insets BORDER = new Insets(4);
private GridLabel(final String text, final String... css) {
// Label
super();
// Cache
this.setCache(true);
// Size
setMinSize(USE_PREF_SIZE, USE_PREF_SIZE);
setPrefSize(USE_COMPUTED_SIZE, USE_COMPUTED_SIZE);
setMaxSize(MAX_VALUE, MAX_VALUE);
// Border
setPadding(BORDER);
// Text Position
setAlignment(Pos.CENTER);
// Grid Settings
setIndex(0, 0);
setSpan(1, 1);
// CSS
addCssClasses("planung-base");
addCssClasses(css);
setText(text);
}
private final void setIndex(final int row, final int column) {
GridPane.setRowIndex(this, Integer.valueOf(row));
GridPane.setColumnIndex(this, Integer.valueOf(column));
}
private final void setSpan(final int row, final int column) {
GridPane.setRowSpan(this, Integer.valueOf(row));
GridPane.setColumnSpan(this, Integer.valueOf(column));
}
private final void addCssClasses(final String... cssClasses) {
getStyleClass().addAll(cssClasses);
}
}
}
------------------
/* Planung.css */
.planung-base{
-fx-border-color: black !important;
-fx-border-insets: -1px 0px 0px -1px !important;
}
.planung-header{
-fx-font-weight: bold !important;
-fx-background-color: #E6E6E6 !important;
}
.planung-header-bereich{
/* top, right, bottom, and left */
-fx-border-width: 1px 1px 0px, 1px !important;
}
.planung-header-mitarbeiter{
/* top, right, bottom, and left */
-fx-border-width: 0px 1px 0px, 1px !important;
}
.planung-header-tag{
/* top, right, bottom, and left */
-fx-font-weight: normal !important;
-fx-font-size: 10 !important;
-fx-border-width: 0px 1px 1px, 1px !important;
}
.planung-datum{
/* top, right, bottom, and left */
-fx-border-width: 1px 1px 1px, 1px !important;
}
.planung-item{
/* top, right, bottom, and left */
-fx-border-width: 1px 1px 1px, 1px !important;
}
.planung-feiertag{
-fx-text-fill: orangered ;
}
.planung-abwesenheit{
-fx-background-color: silver !important;
}
.planung-planung{
-fx-text-fill: black;
}
---------- END SOURCE ----------
- duplicates
-
JDK-8185711 GridPane with HGap > 0 increases row height for label with colSpan=2 and wrapText=true when not necessary
- Closed