Improve samples visual design

This commit is contained in:
mkpaz 2022-09-20 21:44:48 +04:00
parent 978577dc6a
commit 79a9a9cfc2
47 changed files with 1606 additions and 1672 deletions

@ -2,16 +2,13 @@
package atlantafx.sampler.page; package atlantafx.sampler.page;
import atlantafx.sampler.layout.Overlay; import atlantafx.sampler.layout.Overlay;
import javafx.event.ActionEvent; import javafx.scene.Node;
import javafx.event.EventHandler;
import javafx.scene.control.ScrollPane; import javafx.scene.control.ScrollPane;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.*;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import net.datafaker.Faker; import net.datafaker.Faker;
import org.kordamp.ikonli.feather.Feather; import org.kordamp.ikonli.feather.Feather;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -25,34 +22,32 @@ public abstract class AbstractPage extends BorderPane implements Page {
protected static final Faker FAKER = new Faker(); protected static final Faker FAKER = new Faker();
protected static final Random RANDOM = new Random(); protected static final Random RANDOM = new Random();
protected static final EventHandler<ActionEvent> PRINT_SOURCE = System.out::println;
protected VBox userContent; protected final StackPane userContent = new StackPane();
protected Overlay overlay; protected Overlay overlay;
protected boolean isRendered = false; protected boolean isRendered = false;
protected AbstractPage() { protected AbstractPage() {
super(); super();
userContent.getStyleClass().add("user-content");
getStyleClass().add("page"); getStyleClass().add("page");
createPageLayout(); createPageLayout();
} }
protected void createPageLayout() { protected void createPageLayout() {
userContent = new VBox(); var scrollPane = new ScrollPane(userContent);
userContent.getStyleClass().add("user-content");
var userContentWrapper = new StackPane();
userContentWrapper.getStyleClass().add("wrapper");
userContentWrapper.getChildren().setAll(userContent);
var scrollPane = new ScrollPane(userContentWrapper);
setScrollConstraints(scrollPane, AS_NEEDED, true, AS_NEEDED, true); setScrollConstraints(scrollPane, AS_NEEDED, true, AS_NEEDED, true);
scrollPane.setMaxHeight(10_000); scrollPane.setMaxHeight(10_000);
setCenter(scrollPane); setCenter(scrollPane);
} }
protected void setUserContent(Node content) {
userContent.getChildren().setAll(content);
}
@Override @Override
public Pane getView() { public Pane getView() {
return this; return this;
@ -91,6 +86,12 @@ public abstract class AbstractPage extends BorderPane implements Page {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
protected HBox expandingHBox(Node... nodes) {
var box = new HBox(PAGE_HGAP, nodes);
Arrays.stream(nodes).forEach(n -> HBox.setHgrow(n, Priority.ALWAYS));
return box;
}
protected <T> List<T> generate(Supplier<T> supplier, int count) { protected <T> List<T> generate(Supplier<T> supplier, int count) {
return Stream.generate(supplier).limit(count).collect(Collectors.toList()); return Stream.generate(supplier).limit(count).collect(Collectors.toList());
} }

@ -5,6 +5,9 @@ import javafx.scene.Parent;
public interface Page { public interface Page {
int PAGE_HGAP = 30;
int PAGE_VGAP = 30;
String getName(); String getName();
Parent getView(); Parent getView();

@ -3,40 +3,59 @@ package atlantafx.sampler.page;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority; import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
public class SampleBlock { import java.util.Objects;
public class SampleBlock extends VBox {
public static final int BLOCK_HGAP = 20;
public static final int BLOCK_VGAP = 10;
protected final VBox root;
protected final Label titleLabel; protected final Label titleLabel;
protected final Node content; protected final Node content; // can be either Pane or Control
protected TextFlow descriptionText;
public SampleBlock(String title, Node content) { public SampleBlock(String title, Node content) {
this.titleLabel = new Label(title); this(title, content, null);
this.titleLabel.getStyleClass().add("title");
this.content = content;
VBox.setVgrow(content, Priority.ALWAYS);
this.root = new VBox(titleLabel, content);
this.root.getStyleClass().add("sample-block");
} }
public Pane getRoot() { public SampleBlock(String title, Node content, String description) {
return root; titleLabel = new Label(Objects.requireNonNull(title));
titleLabel.getStyleClass().add("title");
this.content = Objects.requireNonNull(content);
content.getStyleClass().add("content");
getChildren().setAll(titleLabel, content);
if (description != null && !description.isBlank()) {
descriptionText = new TextFlow(new Text(description));
getChildren().add(descriptionText);
} }
public String getText() { getStyleClass().add("sample-block");
}
public String getTitle() {
return titleLabel.getText(); return titleLabel.getText();
} }
public void setText(String text) { public void setTitle(String text) {
titleLabel.setText(text); titleLabel.setText(text);
} }
public Node getContent() { public Node getContent() {
return content; return content;
} }
public void setFillHeight(boolean fillHeight) {
if (fillHeight) {
VBox.setVgrow(content, Priority.ALWAYS);
} else {
VBox.setVgrow(content, Priority.NEVER);
}
}
} }

@ -4,10 +4,12 @@ package atlantafx.sampler.page.components;
import atlantafx.base.controls.ToggleSwitch; import atlantafx.base.controls.ToggleSwitch;
import atlantafx.sampler.Resources; import atlantafx.sampler.Resources;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.SampleBlock;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Accordion; import javafx.scene.control.Accordion;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane; import javafx.scene.control.ScrollPane;
@ -31,17 +33,32 @@ public class AccordionPage extends AbstractPage {
public AccordionPage() { public AccordionPage() {
super(); super();
createView();
var sample = new SampleBlock(
"Playground",
new VBox(SampleBlock.BLOCK_VGAP, createControls(), createPlayground())
);
sample.setFillHeight(true);
setUserContent(sample);
} }
private void createView() { private HBox createControls() {
userContent.getChildren().addAll(new VBox(10, var animatedToggle = new ToggleSwitch("Animated");
controls(), animatedProperty.bind(animatedToggle.selectedProperty());
playground() animatedToggle.setSelected(true);
));
var expandedToggle = new ToggleSwitch("Always expanded");
expandedProperty.bind(expandedToggle.selectedProperty());
expandedToggle.setSelected(true);
var controls = new HBox(SampleBlock.BLOCK_HGAP, animatedToggle, expandedToggle);
controls.setAlignment(Pos.CENTER);
controls.setPadding(new Insets(0, 0, 0, 2));
return controls;
} }
private Accordion playground() { private Accordion createPlayground() {
var textBlockContent = new Label(FAKER.chuckNorris().fact()); var textBlockContent = new Label(FAKER.chuckNorris().fact());
var textBlock = new TitledPane("_Quote", textBlockContent); var textBlock = new TitledPane("_Quote", textBlockContent);
textBlock.setMnemonicParsing(true); textBlock.setMnemonicParsing(true);
@ -74,30 +91,16 @@ public class AccordionPage extends AbstractPage {
disabledBlock, disabledBlock,
imageBlock imageBlock
); );
// prevents accordion from being completely collapsed
accordion.expandedPaneProperty().addListener((obs, old, val) -> { accordion.expandedPaneProperty().addListener((obs, old, val) -> {
// make sure the accordion can never be completely collapsed
boolean hasExpanded = accordion.getPanes().stream().anyMatch(TitledPane::isExpanded); boolean hasExpanded = accordion.getPanes().stream().anyMatch(TitledPane::isExpanded);
if (expandedProperty.get() && !hasExpanded && old != null) { if (expandedProperty.get() && !hasExpanded && old != null) {
Platform.runLater(() -> accordion.setExpandedPane(old)); Platform.runLater(() -> accordion.setExpandedPane(old));
} }
}); });
accordion.setExpandedPane(accordion.getPanes().get(0)); accordion.setExpandedPane(accordion.getPanes().get(1));
return accordion; return accordion;
} }
private HBox controls() {
var animatedToggle = new ToggleSwitch("Animated");
animatedProperty.bind(animatedToggle.selectedProperty());
animatedToggle.setSelected(true);
var expandedToggle = new ToggleSwitch("Always expanded");
expandedProperty.bind(expandedToggle.selectedProperty());
expandedToggle.setSelected(true);
var controls = new HBox(20, animatedToggle, expandedToggle);
controls.setPadding(new Insets(0, 0, 0, 2));
return controls;
}
} }

@ -4,11 +4,13 @@ package atlantafx.sampler.page.components;
import atlantafx.base.controls.Breadcrumbs; import atlantafx.base.controls.Breadcrumbs;
import atlantafx.base.theme.Styles; import atlantafx.base.theme.Styles;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.TreeItem; import javafx.scene.control.TreeItem;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.util.Callback; import javafx.util.Callback;
import org.kordamp.ikonli.feather.Feather; import org.kordamp.ikonli.feather.Feather;
import org.kordamp.ikonli.javafx.FontIcon; import org.kordamp.ikonli.javafx.FontIcon;
@ -22,18 +24,14 @@ public class BreadcrumbsPage extends AbstractPage {
public BreadcrumbsPage() { public BreadcrumbsPage() {
super(); super();
createView(); setUserContent(new VBox(Page.PAGE_VGAP,
} defaultSample(),
customCrumbSample()
private void createView() { ));
userContent.getChildren().addAll(
defaultSample().getRoot(),
customCrumbSample().getRoot()
);
} }
private SampleBlock defaultSample() { private SampleBlock defaultSample() {
return new SampleBlock("Basic", breadcrumbs(null)); return new SampleBlock("Basic", createBreadcrumbs(null));
} }
private SampleBlock customCrumbSample() { private SampleBlock customCrumbSample() {
@ -47,10 +45,10 @@ public class BreadcrumbsPage extends AbstractPage {
return btn; return btn;
}; };
return new SampleBlock("Custom crumb factory", breadcrumbs(crumbFactory)); return new SampleBlock("Flat", createBreadcrumbs(crumbFactory));
} }
private HBox breadcrumbs(Callback<TreeItem<String>, Button> crumbFactory) { private HBox createBreadcrumbs(Callback<TreeItem<String>, Button> crumbFactory) {
int count = 5; int count = 5;
TreeItem<String> model = Breadcrumbs.buildTreeModel( TreeItem<String> model = Breadcrumbs.buildTreeModel(
generate(() -> FAKER.science().element(), count).toArray(String[]::new) generate(() -> FAKER.science().element(), count).toArray(String[]::new)
@ -76,7 +74,7 @@ public class BreadcrumbsPage extends AbstractPage {
} }
}); });
var box = new HBox(60, nextBtn, breadcrumbs); var box = new HBox(40, nextBtn, breadcrumbs);
box.setAlignment(Pos.CENTER_LEFT); box.setAlignment(Pos.CENTER_LEFT);
return box; return box;

@ -2,6 +2,7 @@
package atlantafx.sampler.page.components; package atlantafx.sampler.page.components;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay; import javafx.scene.control.ContentDisplay;
@ -12,6 +13,7 @@ import org.kordamp.ikonli.feather.Feather;
import org.kordamp.ikonli.javafx.FontIcon; import org.kordamp.ikonli.javafx.FontIcon;
import static atlantafx.base.theme.Styles.*; import static atlantafx.base.theme.Styles.*;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
public class ButtonPage extends AbstractPage { public class ButtonPage extends AbstractPage {
@ -29,36 +31,31 @@ public class ButtonPage extends AbstractPage {
private void createView() { private void createView() {
var grid = new GridPane(); var grid = new GridPane();
grid.setHgap(40); grid.setHgap(Page.PAGE_HGAP);
grid.setVgap(40); grid.setVgap(Page.PAGE_VGAP);
grid.add(basicSamples().getRoot(), 0, 0); grid.add(basicSamples(), 0, 0);
grid.add(iconOnlySamples().getRoot(), 1, 0); grid.add(iconButtonSamples(), 1, 0);
grid.add(coloredSamples().getRoot(), 0, 1); grid.add(coloredSamples(), 0, 1);
grid.add(circularButtons().getRoot(), 1, 1); grid.add(circularButtons(), 1, 1);
grid.add(outlinedSamples().getRoot(), 0, 2); grid.add(outlinedSamples(), 0, 2);
grid.add(roundedSamples().getRoot(), 1, 2); grid.add(roundedSamples(), 1, 2);
grid.add(disabledSample().getRoot(), 0, 3); grid.add(disabledSample(), 0, 3);
userContent.getChildren().addAll(grid); setUserContent(grid);
} }
private SampleBlock basicSamples() { private SampleBlock basicSamples() {
var basicBtn = new Button("_Basic"); var basicBtn = new Button("_Basic");
basicBtn.setMnemonicParsing(true); basicBtn.setMnemonicParsing(true);
basicBtn.setOnAction(PRINT_SOURCE);
var defaultBtn = new Button("_Default"); var defaultBtn = new Button("_Default");
defaultBtn.setDefaultButton(true); defaultBtn.setDefaultButton(true);
defaultBtn.setMnemonicParsing(true); defaultBtn.setMnemonicParsing(true);
defaultBtn.setOnAction(PRINT_SOURCE);
var flatBtn = new Button("_Flat"); var flatBtn = new Button("_Flat");
flatBtn.getStyleClass().add(FLAT); flatBtn.getStyleClass().add(FLAT);
flatBtn.setOnAction(PRINT_SOURCE);
var content = new HBox(10);
content.getChildren().addAll(basicBtn, defaultBtn, flatBtn);
var content = new HBox(BLOCK_HGAP, basicBtn, defaultBtn, flatBtn);
return new SampleBlock("Basic", content); return new SampleBlock("Basic", content);
} }
@ -66,26 +63,21 @@ public class ButtonPage extends AbstractPage {
var accentBtn = new Button("_Accent"); var accentBtn = new Button("_Accent");
accentBtn.getStyleClass().add(ACCENT); accentBtn.getStyleClass().add(ACCENT);
accentBtn.setMnemonicParsing(true); accentBtn.setMnemonicParsing(true);
accentBtn.setOnAction(PRINT_SOURCE);
var successBtn = new Button("_Success", new FontIcon(Feather.CHECK)); var successBtn = new Button("_Success", new FontIcon(Feather.CHECK));
successBtn.getStyleClass().add(SUCCESS); successBtn.getStyleClass().add(SUCCESS);
successBtn.setMnemonicParsing(true); successBtn.setMnemonicParsing(true);
successBtn.setOnAction(PRINT_SOURCE);
var dangerBtn = new Button("Da_nger", new FontIcon(Feather.TRASH)); var dangerBtn = new Button("Da_nger", new FontIcon(Feather.TRASH));
dangerBtn.getStyleClass().add(DANGER); dangerBtn.getStyleClass().add(DANGER);
dangerBtn.setContentDisplay(ContentDisplay.RIGHT); dangerBtn.setContentDisplay(ContentDisplay.RIGHT);
dangerBtn.setMnemonicParsing(true); dangerBtn.setMnemonicParsing(true);
dangerBtn.setOnAction(PRINT_SOURCE);
var content = new HBox(10);
content.getChildren().addAll(accentBtn, successBtn, dangerBtn);
var content = new HBox(BLOCK_HGAP, accentBtn, successBtn, dangerBtn);
return new SampleBlock("Colored", content); return new SampleBlock("Colored", content);
} }
private SampleBlock iconOnlySamples() { private SampleBlock iconButtonSamples() {
var basicBtn = new Button("", new FontIcon(Feather.MORE_HORIZONTAL)); var basicBtn = new Button("", new FontIcon(Feather.MORE_HORIZONTAL));
basicBtn.getStyleClass().addAll(BUTTON_ICON); basicBtn.getStyleClass().addAll(BUTTON_ICON);
@ -107,12 +99,11 @@ public class ButtonPage extends AbstractPage {
var flatDangerBtn = new Button("", new FontIcon(Feather.CROSSHAIR)); var flatDangerBtn = new Button("", new FontIcon(Feather.CROSSHAIR));
flatDangerBtn.getStyleClass().addAll(BUTTON_ICON, FLAT, DANGER); flatDangerBtn.getStyleClass().addAll(BUTTON_ICON, FLAT, DANGER);
var content = new HBox(10); var content = new HBox(BLOCK_HGAP,
content.getChildren().addAll(basicBtn, accentBtn, successBtn, dangerBtn, basicBtn, accentBtn, successBtn, dangerBtn,
flatAccentBtn, flatSuccessBtn, flatDangerBtn flatAccentBtn, flatSuccessBtn, flatDangerBtn
); );
return new SampleBlock("Icon", content);
return new SampleBlock("Icon only", content);
} }
private SampleBlock circularButtons() { private SampleBlock circularButtons() {
@ -144,11 +135,10 @@ public class ButtonPage extends AbstractPage {
flatDangerBtn.getStyleClass().addAll(BUTTON_CIRCLE, FLAT, DANGER); flatDangerBtn.getStyleClass().addAll(BUTTON_CIRCLE, FLAT, DANGER);
flatDangerBtn.setShape(new Circle(50)); flatDangerBtn.setShape(new Circle(50));
var content = new HBox(10); var content = new HBox(BLOCK_HGAP,
content.getChildren().addAll(basicBtn, accentBtn, successBtn, dangerBtn, basicBtn, accentBtn, successBtn, dangerBtn,
flatAccentBtn, flatSuccessBtn, flatDangerBtn flatAccentBtn, flatSuccessBtn, flatDangerBtn
); );
return new SampleBlock("Circular", content); return new SampleBlock("Circular", content);
} }
@ -156,21 +146,17 @@ public class ButtonPage extends AbstractPage {
var accentBtn = new Button("Accen_t"); var accentBtn = new Button("Accen_t");
accentBtn.getStyleClass().addAll(BUTTON_OUTLINED, ACCENT); accentBtn.getStyleClass().addAll(BUTTON_OUTLINED, ACCENT);
accentBtn.setMnemonicParsing(true); accentBtn.setMnemonicParsing(true);
accentBtn.setOnAction(PRINT_SOURCE);
var successBtn = new Button("S_uccess", new FontIcon(Feather.CHECK)); var successBtn = new Button("S_uccess", new FontIcon(Feather.CHECK));
successBtn.getStyleClass().addAll(BUTTON_OUTLINED, SUCCESS); successBtn.getStyleClass().addAll(BUTTON_OUTLINED, SUCCESS);
successBtn.setMnemonicParsing(true); successBtn.setMnemonicParsing(true);
successBtn.setOnAction(PRINT_SOURCE);
var dangerBtn = new Button("Dan_ger", new FontIcon(Feather.TRASH)); var dangerBtn = new Button("Dan_ger", new FontIcon(Feather.TRASH));
dangerBtn.getStyleClass().addAll(BUTTON_OUTLINED, DANGER); dangerBtn.getStyleClass().addAll(BUTTON_OUTLINED, DANGER);
dangerBtn.setContentDisplay(ContentDisplay.RIGHT); dangerBtn.setContentDisplay(ContentDisplay.RIGHT);
dangerBtn.setMnemonicParsing(true); dangerBtn.setMnemonicParsing(true);
dangerBtn.setOnAction(PRINT_SOURCE);
var content = new HBox(10); var content = new HBox(BLOCK_HGAP, accentBtn, successBtn, dangerBtn);
content.getChildren().addAll(accentBtn, successBtn, dangerBtn);
return new SampleBlock("Outlined", content); return new SampleBlock("Outlined", content);
} }
@ -178,19 +164,14 @@ public class ButtonPage extends AbstractPage {
private SampleBlock roundedSamples() { private SampleBlock roundedSamples() {
var basicBtn = new Button("Basic"); var basicBtn = new Button("Basic");
basicBtn.getStyleClass().add(ROUNDED); basicBtn.getStyleClass().add(ROUNDED);
basicBtn.setOnAction(PRINT_SOURCE);
var accentBtn = new Button("Accent"); var accentBtn = new Button("Accent");
accentBtn.getStyleClass().addAll(ROUNDED, ACCENT); accentBtn.getStyleClass().addAll(ROUNDED, ACCENT);
accentBtn.setOnAction(PRINT_SOURCE);
var successBtn = new Button("Success", new FontIcon(Feather.CHECK)); var successBtn = new Button("Success", new FontIcon(Feather.CHECK));
successBtn.getStyleClass().addAll(ROUNDED, BUTTON_OUTLINED, SUCCESS); successBtn.getStyleClass().addAll(ROUNDED, BUTTON_OUTLINED, SUCCESS);
successBtn.setOnAction(PRINT_SOURCE);
var content = new HBox(10);
content.getChildren().addAll(basicBtn, accentBtn, successBtn);
var content = new HBox(BLOCK_HGAP, basicBtn, accentBtn, successBtn);
return new SampleBlock("Rounded", content); return new SampleBlock("Rounded", content);
} }
@ -210,9 +191,7 @@ public class ButtonPage extends AbstractPage {
iconBtn.getStyleClass().addAll(BUTTON_ICON); iconBtn.getStyleClass().addAll(BUTTON_ICON);
iconBtn.setDisable(true); iconBtn.setDisable(true);
var content = new HBox(10); var content = new HBox(BLOCK_HGAP, basicBtn, defaultBtn, flatBtn, iconBtn);
content.getChildren().addAll(basicBtn, defaultBtn, flatBtn, iconBtn);
return new SampleBlock("Disabled", content); return new SampleBlock("Disabled", content);
} }
} }

@ -1,17 +1,17 @@
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
package atlantafx.sampler.page.components; package atlantafx.sampler.page.components;
import atlantafx.base.controls.ToggleSwitch;
import atlantafx.base.controls.Spacer; import atlantafx.base.controls.Spacer;
import atlantafx.base.controls.ToggleSwitch;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.SampleBlock;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.geometry.Orientation;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.chart.*; import javafx.scene.chart.*;
import javafx.scene.control.ComboBox; import javafx.scene.control.ComboBox;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.Separator; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.util.StringConverter; import javafx.util.StringConverter;
@ -31,38 +31,30 @@ public class ChartPage extends AbstractPage {
@Override @Override
public String getName() { return NAME; } public String getName() { return NAME; }
private VBox playground; private final BorderPane chartWrapper = new BorderPane();
private ComboBox<Example> exampleSelect; private final ComboBox<Example> exampleSelect = new ComboBox<>();
public ChartPage() { public ChartPage() {
super(); super();
createView(); setUserContent(new VBox(
new SampleBlock("Playground", createPlayground())
));
} }
private void createView() { private VBox createPlayground() {
playground = new VBox(10);
playground.setMinHeight(100);
// === SELECT ===
exampleSelect = new ComboBox<>();
exampleSelect.setMaxWidth(Double.MAX_VALUE); exampleSelect.setMaxWidth(Double.MAX_VALUE);
exampleSelect.getItems().setAll(Example.values()); exampleSelect.getItems().setAll(Example.values());
exampleSelect.getSelectionModel().selectedItemProperty().addListener((obs, old, val) -> { exampleSelect.getSelectionModel().selectedItemProperty().addListener((obs, old, val) -> {
if (val == null) { return; } if (val == null) { return; }
if (playground.getChildren().size() != 5) {
throw new RuntimeException("Unexpected container size.");
}
Chart newChart = createChart(val); Chart newChart = createChart(val);
// copy existing properties to the new chart // copy existing properties to the new chart
findDisplayedChart().ifPresent(ch -> newChart.setDisable(ch.isDisable())); findDisplayedChart().ifPresent(chart -> newChart.setDisable(chart.isDisable()));
playground.getChildren().set(2, newChart); chartWrapper.setCenter(newChart);
}); });
exampleSelect.setConverter(new StringConverter<>() { exampleSelect.setConverter(new StringConverter<>() {
@Override @Override
public String toString(Example example) { public String toString(Example example) {
return example == null ? "" : example.getName(); return example == null ? "" : example.getName();
@ -74,31 +66,22 @@ public class ChartPage extends AbstractPage {
} }
}); });
// === CONTROLS ===
var disableToggle = new ToggleSwitch("Disable"); var disableToggle = new ToggleSwitch("Disable");
disableToggle.selectedProperty().addListener((obs, old, val) -> findDisplayedChart().ifPresent(ch -> { disableToggle.selectedProperty().addListener((obs, old, val) -> findDisplayedChart().ifPresent(ch -> {
if (val != null) { ch.setDisable(val); } if (val != null) { ch.setDisable(val); }
})); }));
var controls = new HBox(20, var controls = new HBox(disableToggle);
new Spacer(),
disableToggle,
new Spacer()
);
controls.setAlignment(Pos.CENTER); controls.setAlignment(Pos.CENTER);
// ~ VBox playground = new VBox(SampleBlock.BLOCK_VGAP);
playground.getChildren().setAll( playground.getChildren().setAll(
new Label("Select an example:"), new HBox(new Label("Select an example:"), new Spacer(), disableToggle),
exampleSelect, exampleSelect,
new Spacer(Orientation.VERTICAL), chartWrapper
new Separator(),
controls
); );
userContent.getChildren().setAll(playground); return playground;
} }
@Override @Override
@ -108,10 +91,9 @@ public class ChartPage extends AbstractPage {
} }
private Optional<Chart> findDisplayedChart() { private Optional<Chart> findDisplayedChart() {
return playground.getChildren().stream() return chartWrapper.getChildren().size() > 0 ?
.filter(c -> c instanceof Chart) Optional.of((Chart) chartWrapper.getChildren().get(0)) :
.findFirst() Optional.empty();
.map(c -> (Chart) c);
} }
private Chart createChart(Example example) { private Chart createChart(Example example) {

@ -4,6 +4,7 @@ package atlantafx.sampler.page.components;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import javafx.scene.control.CheckBox; import javafx.scene.control.CheckBox;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
@ -23,35 +24,29 @@ public class CheckBoxPage extends AbstractPage {
} }
private void createView() { private void createView() {
userContent.getChildren().addAll( setUserContent(new FlowPane(
basicSamples(), PAGE_HGAP, PAGE_VGAP,
disabledSamples() basicSample(),
); indeterminateSample(),
disabledSample()
));
} }
private HBox basicSamples() { private SampleBlock basicSample() {
basicCheck = new CheckBox("_Check Me"); basicCheck = new CheckBox("_Check Me");
basicCheck.setMnemonicParsing(true); basicCheck.setMnemonicParsing(true);
basicCheck.setOnAction(PRINT_SOURCE); return new SampleBlock("Basic", basicCheck);
var basicBlock = new SampleBlock("Basic", basicCheck); }
private SampleBlock indeterminateSample() {
indeterminateCheck = new CheckBox("C_heck Me"); indeterminateCheck = new CheckBox("C_heck Me");
indeterminateCheck.setAllowIndeterminate(true); indeterminateCheck.setAllowIndeterminate(true);
indeterminateCheck.setIndeterminate(true); indeterminateCheck.setIndeterminate(true);
indeterminateCheck.setMnemonicParsing(true); indeterminateCheck.setMnemonicParsing(true);
indeterminateCheck.setOnAction(PRINT_SOURCE); return new SampleBlock("Indeterminate", indeterminateCheck);
var indeterminateBlock = new SampleBlock("Indeterminate", indeterminateCheck);
var root = new HBox(20);
root.getChildren().addAll(
basicBlock.getRoot(),
indeterminateBlock.getRoot()
);
return root;
} }
private HBox disabledSamples() { private SampleBlock disabledSample() {
var basicCheck = new CheckBox("Check Me"); var basicCheck = new CheckBox("Check Me");
basicCheck.setSelected(true); basicCheck.setSelected(true);
basicCheck.setDisable(true); basicCheck.setDisable(true);
@ -61,12 +56,10 @@ public class CheckBoxPage extends AbstractPage {
indeterminateCheck.setIndeterminate(true); indeterminateCheck.setIndeterminate(true);
indeterminateCheck.setDisable(true); indeterminateCheck.setDisable(true);
var disabledBlock = new SampleBlock("Disabled", new HBox(10, basicCheck, indeterminateCheck)); return new SampleBlock(
"Disabled",
var root = new HBox(20); new HBox(SampleBlock.BLOCK_HGAP, basicCheck, indeterminateCheck)
root.getChildren().addAll(disabledBlock.getRoot()); );
return root;
} }
// visually compare normal and indeterminate checkboxes size // visually compare normal and indeterminate checkboxes size
@ -80,13 +73,14 @@ public class CheckBoxPage extends AbstractPage {
((StackPane) normalBox).layout(); ((StackPane) normalBox).layout();
((StackPane) indeterminateBox).layout(); ((StackPane) indeterminateBox).layout();
basicCheck.setText(String.format("_Check Me (size = H%.2f x W%.2f)", System.out.printf("Basic: height = %.2f , width = %.2f\n",
normalBox.getBoundsInParent().getHeight(), normalBox.getBoundsInParent().getHeight(),
normalBox.getBoundsInParent().getWidth() normalBox.getBoundsInParent().getWidth()
)); );
indeterminateCheck.setText(String.format("C_heck Me (box size = H%.2f x W%.2f)",
normalBox.getBoundsInParent().getHeight(), System.out.printf("Indeterminate: height = %.2f , width = %.2f\n",
normalBox.getBoundsInParent().getWidth() indeterminateBox.getBoundsInParent().getHeight(),
)); indeterminateBox.getBoundsInParent().getWidth()
);
} }
} }

@ -2,17 +2,20 @@
package atlantafx.sampler.page.components; package atlantafx.sampler.page.components;
import atlantafx.base.controls.ToggleSwitch; import atlantafx.base.controls.ToggleSwitch;
import atlantafx.base.controls.Spacer;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import javafx.geometry.Pos; import atlantafx.sampler.page.SampleBlock;
import javafx.geometry.HPos;
import javafx.scene.control.ChoiceBox; import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ColorPicker; import javafx.scene.control.ColorPicker;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.Separator; import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.HBox; import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
public class ColorPickerPage extends AbstractPage { public class ColorPickerPage extends AbstractPage {
public static final String NAME = "ColorPicker"; public static final String NAME = "ColorPicker";
@ -22,73 +25,72 @@ public class ColorPickerPage extends AbstractPage {
public ColorPickerPage() { public ColorPickerPage() {
super(); super();
createView(); setUserContent(new VBox(
new SampleBlock("Playground", createPlayground())
));
} }
private void createView() { private GridPane createPlayground() {
userContent.getChildren().setAll(
playground()
);
}
private VBox playground() {
var colorPicker = new ColorPicker(); var colorPicker = new ColorPicker();
colorPicker.setValue(Color.AQUA); colorPicker.setValue(Color.DEEPSKYBLUE);
var pickerBox = new HBox( var labelToggle = new ToggleSwitch();
new Spacer(),
colorPicker,
new Spacer()
);
var labelToggle = new ToggleSwitch("Show label");
labelToggle.setSelected(true); labelToggle.setSelected(true);
labelToggle.selectedProperty().addListener((obs, old, val) -> { labelToggle.selectedProperty().addListener((obs, old, val) -> {
colorPicker.setStyle("-fx-color-label-visible: false;"); colorPicker.setStyle("-fx-color-label-visible: false;");
if (val) { colorPicker.setStyle("-fx-color-label-visible: true;"); } if (val) { colorPicker.setStyle("-fx-color-label-visible: true;"); }
}); });
var disableToggle = new ToggleSwitch("Disable"); var disableToggle = new ToggleSwitch();
colorPicker.disableProperty().bind(disableToggle.selectedProperty()); colorPicker.disableProperty().bind(disableToggle.selectedProperty());
var pickerStyleBox = new HBox(5, new Label("Picker Style"), pickerStyleChoice(colorPicker)); var grid = new GridPane();
pickerStyleBox.setAlignment(Pos.CENTER); grid.setHgap(BLOCK_HGAP);
grid.setVgap(BLOCK_VGAP);
grid.add(colorPicker, 0, 0, 1, GridPane.REMAINING);
grid.add(createLabel("Show label"), 1, 0);
grid.add(labelToggle, 2, 0);
grid.add(createLabel("Picker style"), 1, 1);
grid.add(createPickerStyleChoice(colorPicker), 2, 1);
grid.add(createLabel("Disable"), 1, 2);
grid.add(disableToggle, 2, 2);
var controls = new HBox(20, grid.getColumnConstraints().setAll(
new Spacer(), new ColumnConstraints(200),
pickerStyleBox, new ColumnConstraints(),
labelToggle, new ColumnConstraints()
disableToggle,
new Spacer()
);
controls.setAlignment(Pos.CENTER);
// ~
var root = new VBox(20);
root.setAlignment(Pos.CENTER);
root.getChildren().setAll(
pickerBox,
new Separator(),
controls
); );
return root; return grid;
} }
private ChoiceBox<String> pickerStyleChoice(ColorPicker colorPicker) { private Label createLabel(String text) {
var label = new Label(text);
GridPane.setHalignment(label, HPos.RIGHT);
return label;
}
private ChoiceBox<String> createPickerStyleChoice(ColorPicker colorPicker) {
var optDefault = "Default"; var optDefault = "Default";
var optButton = "Button"; var optButton = "Button";
var optSplitButton = "Split Button"; var optSplitButton = "Split Button";
var choice = new ChoiceBox<String>(); var choice = new ChoiceBox<String>();
choice.getItems().setAll(optDefault, optButton, optSplitButton); choice.getItems().setAll(optDefault, optButton, optSplitButton);
choice.setPrefWidth(120);
choice.getSelectionModel().selectedItemProperty().addListener((obs, old, val) -> { choice.getSelectionModel().selectedItemProperty().addListener((obs, old, val) -> {
if (val == null) { return; } if (val == null) { return; }
colorPicker.getStyleClass().removeAll(ColorPicker.STYLE_CLASS_BUTTON, ColorPicker.STYLE_CLASS_SPLIT_BUTTON);
if (optButton.equals(val)) { colorPicker.getStyleClass().add(ColorPicker.STYLE_CLASS_BUTTON); } colorPicker.getStyleClass().removeAll(
if (optSplitButton.equals(val)) { colorPicker.getStyleClass().add(ColorPicker.STYLE_CLASS_SPLIT_BUTTON); } ColorPicker.STYLE_CLASS_BUTTON,
ColorPicker.STYLE_CLASS_SPLIT_BUTTON
);
if (optButton.equals(val)) {
colorPicker.getStyleClass().add(ColorPicker.STYLE_CLASS_BUTTON);
}
if (optSplitButton.equals(val)) {
colorPicker.getStyleClass().add(ColorPicker.STYLE_CLASS_SPLIT_BUTTON);
}
}); });
choice.getSelectionModel().select(optDefault); choice.getSelectionModel().select(optDefault);

@ -3,6 +3,7 @@ package atlantafx.sampler.page.components;
import atlantafx.base.theme.Tweaks; import atlantafx.base.theme.Tweaks;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.SampleBlock;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.geometry.HPos; import javafx.geometry.HPos;
@ -11,7 +12,7 @@ import javafx.scene.control.ComboBox;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.ListCell; import javafx.scene.control.ListCell;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane; import javafx.scene.layout.VBox;
import org.kordamp.ikonli.Ikon; import org.kordamp.ikonli.Ikon;
import org.kordamp.ikonli.javafx.FontIcon; import org.kordamp.ikonli.javafx.FontIcon;
@ -21,6 +22,8 @@ import java.util.stream.IntStream;
import static atlantafx.base.theme.Styles.STATE_DANGER; import static atlantafx.base.theme.Styles.STATE_DANGER;
import static atlantafx.base.theme.Styles.STATE_SUCCESS; import static atlantafx.base.theme.Styles.STATE_SUCCESS;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
import static atlantafx.sampler.util.Containers.H_GROW_NEVER; import static atlantafx.sampler.util.Containers.H_GROW_NEVER;
import static javafx.collections.FXCollections.observableArrayList; import static javafx.collections.FXCollections.observableArrayList;
@ -34,49 +37,40 @@ public class ComboBoxPage extends AbstractPage {
public ComboBoxPage() { public ComboBoxPage() {
super(); super();
createView(); setUserContent(new VBox(
new SampleBlock("Examples", createPlayground())
));
} }
private void createView() { private GridPane createPlayground() {
userContent.getChildren().setAll(
createGrid()
);
}
private Pane createGrid() {
var grid = new GridPane(); var grid = new GridPane();
grid.setHgap(20); grid.setHgap(BLOCK_HGAP);
grid.setVgap(10); grid.setVgap(BLOCK_VGAP);
grid.getColumnConstraints().setAll(H_GROW_NEVER, H_GROW_NEVER, H_GROW_NEVER); grid.getColumnConstraints().setAll(H_GROW_NEVER, H_GROW_NEVER, H_GROW_NEVER);
grid.setMaxWidth((PREF_WIDTH * 3) + 100);
var comboLabel = new Label("C_omboBox"); var comboLabel = new Label("C_omboBox");
comboLabel.setMnemonicParsing(true); comboLabel.setMnemonicParsing(true);
comboLabel.setStyle("-fx-font-weight: bold;");
grid.add(comboLabel, 0, 0); grid.add(comboLabel, 0, 0);
var choiceLabel = new Label("C_hoiceBox"); var choiceLabel = new Label("C_hoiceBox");
choiceLabel.setMnemonicParsing(true); choiceLabel.setMnemonicParsing(true);
choiceLabel.setStyle("-fx-font-weight: bold;");
grid.add(choiceLabel, 2, 0); grid.add(choiceLabel, 2, 0);
// default // default
grid.add(comboBox(), 0, 1); grid.add(createComboBox(), 0, 1);
grid.add(label("empty"), 1, 1); grid.add(createLabel("empty"), 1, 1);
grid.add(choiceBox(), 2, 1); grid.add(createChoiceBox(), 2, 1);
// editable // editable
grid.add(comboBox(c -> { grid.add(createComboBoxWith(c -> {
c.setItems(createItems(5)); c.setItems(createItems(5));
c.setEditable(true); c.setEditable(true);
}), 0, 2); }), 0, 2);
grid.add(label("editable"), 1, 2); grid.add(createLabel("editable"), 1, 2);
// placeholder // placeholder
grid.add(comboBox(c -> c.setPlaceholder(new Label("Loading..."))), 0, 3); grid.add(createComboBoxWith(c -> c.setPlaceholder(new Label("Loading..."))), 0, 3);
grid.add(label("placeholder"), 1, 3); grid.add(createLabel("placeholder"), 1, 3);
// with icons // with icons
var badges = IntStream.range(0, 5).boxed() var badges = IntStream.range(0, 5).boxed()
@ -88,70 +82,70 @@ public class ComboBoxPage extends AbstractPage {
badgeCombo.setCellFactory(lv -> new BadgeCell()); badgeCombo.setCellFactory(lv -> new BadgeCell());
badgeCombo.getSelectionModel().selectFirst(); badgeCombo.getSelectionModel().selectFirst();
grid.add(badgeCombo, 0, 4); grid.add(badgeCombo, 0, 4);
grid.add(label("graphic"), 1, 4); grid.add(createLabel("graphic"), 1, 4);
// success // success
grid.add(comboBox(c -> { grid.add(createComboBoxWith(c -> {
c.setItems(createItems(5)); c.setItems(createItems(5));
c.pseudoClassStateChanged(STATE_SUCCESS, true); c.pseudoClassStateChanged(STATE_SUCCESS, true);
c.getSelectionModel().selectFirst(); c.getSelectionModel().selectFirst();
}), 0, 5); }), 0, 5);
grid.add(label("success"), 1, 5); grid.add(createLabel("success"), 1, 5);
grid.add(choiceBox(c -> { grid.add(createChoiceBoxWith(c -> {
c.setItems(createItems(5)); c.setItems(createItems(5));
c.pseudoClassStateChanged(STATE_SUCCESS, true); c.pseudoClassStateChanged(STATE_SUCCESS, true);
c.getSelectionModel().selectFirst(); c.getSelectionModel().selectFirst();
}), 2, 5); }), 2, 5);
// negative // negative
grid.add(comboBox(c -> { grid.add(createComboBoxWith(c -> {
c.setItems(createItems(5)); c.setItems(createItems(5));
c.pseudoClassStateChanged(STATE_DANGER, true); c.pseudoClassStateChanged(STATE_DANGER, true);
c.getSelectionModel().selectFirst(); c.getSelectionModel().selectFirst();
}), 0, 6); }), 0, 6);
grid.add(label("success"), 1, 6); grid.add(createLabel("success"), 1, 6);
grid.add(choiceBox(c -> { grid.add(createChoiceBoxWith(c -> {
c.setItems(createItems(5)); c.setItems(createItems(5));
c.pseudoClassStateChanged(STATE_DANGER, true); c.pseudoClassStateChanged(STATE_DANGER, true);
c.getSelectionModel().selectFirst(); c.getSelectionModel().selectFirst();
}), 2, 6); }), 2, 6);
// alt icon // alt icon
grid.add(comboBox(c -> { grid.add(createComboBoxWith(c -> {
c.setItems(createItems(5)); c.setItems(createItems(5));
c.getStyleClass().add(Tweaks.ALT_ICON); c.getStyleClass().add(Tweaks.ALT_ICON);
c.getSelectionModel().selectFirst(); c.getSelectionModel().selectFirst();
}), 0, 7); }), 0, 7);
grid.add(label("alt icon"), 1, 7); grid.add(createLabel("alt icon"), 1, 7);
grid.add(choiceBox(c -> { grid.add(createChoiceBoxWith(c -> {
c.setItems(createItems(5)); c.setItems(createItems(5));
c.getStyleClass().add(Tweaks.ALT_ICON); c.getStyleClass().add(Tweaks.ALT_ICON);
c.getSelectionModel().selectFirst(); c.getSelectionModel().selectFirst();
}), 2, 7); }), 2, 7);
// disabled // disabled
grid.add(comboBox(c -> c.setDisable(true)), 0, 8); grid.add(createComboBoxWith(c -> c.setDisable(true)), 0, 8);
grid.add(label("disabled"), 1, 8); grid.add(createLabel("disabled"), 1, 8);
grid.add(choiceBox(c -> c.setDisable(true)), 2, 8); grid.add(createChoiceBoxWith(c -> c.setDisable(true)), 2, 8);
// overflow // vertical overflow
grid.add(comboBox(c -> { grid.add(createComboBoxWith(c -> {
c.setItems(createItems(50)); c.setItems(createItems(50));
c.getSelectionModel().selectFirst(); c.getSelectionModel().selectFirst();
}), 0, 9); }), 0, 9);
grid.add(label("large list"), 1, 9); grid.add(createLabel("large list"), 1, 9);
grid.add(choiceBox(c -> { grid.add(createChoiceBoxWith(c -> {
c.setItems(createItems(50)); c.setItems(createItems(50));
c.getSelectionModel().selectFirst(); c.getSelectionModel().selectFirst();
}), 2, 9); }), 2, 9);
// overflow // horizontal overflow
grid.add(comboBox(c -> { grid.add(createComboBoxWith(c -> {
c.setItems(observableArrayList(generate(() -> FAKER.chuckNorris().fact(), 5))); c.setItems(observableArrayList(generate(() -> FAKER.chuckNorris().fact(), 5)));
c.getSelectionModel().selectFirst(); c.getSelectionModel().selectFirst();
}), 0, 10); }), 0, 10);
grid.add(label("wide text"), 1, 10); grid.add(createLabel("wide text"), 1, 10);
grid.add(choiceBox(c -> { grid.add(createChoiceBoxWith(c -> {
c.setItems(observableArrayList(generate(() -> FAKER.chuckNorris().fact(), 5))); c.setItems(observableArrayList(generate(() -> FAKER.chuckNorris().fact(), 5)));
c.getSelectionModel().selectFirst(); c.getSelectionModel().selectFirst();
}), 2, 10); }), 2, 10);
@ -159,38 +153,38 @@ public class ComboBoxPage extends AbstractPage {
return grid; return grid;
} }
private ObservableList<String> createItems(int count) { private Label createLabel(String text) {
return observableArrayList(generate(() -> FAKER.hipster().word(), count)); var label = new Label(text);
GridPane.setHalignment(label, HPos.CENTER);
return label;
} }
private Label label(String text) { private ComboBox<String> createComboBox() {
return new Label(text) {{ return createComboBoxWith(null);
GridPane.setHalignment(this, HPos.CENTER);
}};
} }
private ComboBox<String> comboBox() { private ComboBox<String> createComboBoxWith(Consumer<ComboBox<String>> mutator) {
return comboBox(null);
}
private ComboBox<String> comboBox(Consumer<ComboBox<String>> mutator) {
var c = new ComboBox<String>(); var c = new ComboBox<String>();
c.setPrefWidth(PREF_WIDTH); c.setPrefWidth(PREF_WIDTH);
if (mutator != null) { mutator.accept(c); } if (mutator != null) { mutator.accept(c); }
return c; return c;
} }
private ChoiceBox<String> choiceBox() { private ChoiceBox<String> createChoiceBox() {
return choiceBox(null); return createChoiceBoxWith(null);
} }
private ChoiceBox<String> choiceBox(Consumer<ChoiceBox<String>> mutator) { private ChoiceBox<String> createChoiceBoxWith(Consumer<ChoiceBox<String>> mutator) {
var c = new ChoiceBox<String>(); var c = new ChoiceBox<String>();
c.setPrefWidth(PREF_WIDTH); c.setPrefWidth(PREF_WIDTH);
if (mutator != null) { mutator.accept(c); } if (mutator != null) { mutator.accept(c); }
return c; return c;
} }
private ObservableList<String> createItems(int count) {
return observableArrayList(generate(() -> FAKER.hipster().word(), count));
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
private record Badge(String text, Ikon icon) { } private record Badge(String text, Ikon icon) { }

@ -14,58 +14,60 @@ import static atlantafx.base.theme.Styles.STATE_SUCCESS;
public class CustomTextFieldPage extends AbstractPage { public class CustomTextFieldPage extends AbstractPage {
public static final String NAME = "CustomTextField"; public static final String NAME = "CustomTextField";
private static final int PREF_WIDTH = 120;
@Override @Override
public String getName() { return NAME; } public String getName() { return NAME; }
public CustomTextFieldPage() { public CustomTextFieldPage() {
super(); super();
createView(); setUserContent(new FlowPane(
PAGE_HGAP, PAGE_VGAP,
leftIconSample(),
rightIconSample(),
bothIconsSample(),
successSample(),
dangerSample()
));
} }
private void createView() { private SampleBlock leftIconSample() {
userContent.getChildren().setAll(samples());
}
private FlowPane samples() {
var leftIconField = new CustomTextField(); var leftIconField = new CustomTextField();
leftIconField.setPromptText("Prompt text"); leftIconField.setPromptText("Prompt text");
leftIconField.setRight(new FontIcon(Feather.X)); leftIconField.setRight(new FontIcon(Feather.X));
var leftIconBlock = new SampleBlock("Node on the left", leftIconField); leftIconField.setPrefWidth(PREF_WIDTH);
return new SampleBlock("Left", leftIconField);
}
private SampleBlock rightIconSample() {
var rightIconField = new CustomTextField(); var rightIconField = new CustomTextField();
rightIconField.setPromptText("Prompt text"); rightIconField.setPromptText("Prompt text");
rightIconField.setLeft(new FontIcon(Feather.MAP_PIN)); rightIconField.setLeft(new FontIcon(Feather.MAP_PIN));
var rightIconBlock = new SampleBlock("Node on the right", rightIconField); rightIconField.setPrefWidth(PREF_WIDTH);
return new SampleBlock("Right", rightIconField);
}
private SampleBlock bothIconsSample() {
var bothIconField = new CustomTextField("Text"); var bothIconField = new CustomTextField("Text");
bothIconField.setLeft(new FontIcon(Feather.MAP_PIN)); bothIconField.setLeft(new FontIcon(Feather.MAP_PIN));
bothIconField.setRight(new FontIcon(Feather.X)); bothIconField.setRight(new FontIcon(Feather.X));
var bothIconBlock = new SampleBlock("Nodes on both sides", bothIconField); bothIconField.setPrefWidth(PREF_WIDTH);
return new SampleBlock("Both Sides", bothIconField);
var noSideIconsField = new CustomTextField("Text"); }
var noSideIconsBlock = new SampleBlock("No side nodes", noSideIconsField);
private SampleBlock successSample() {
var successField = new CustomTextField("Text"); var successField = new CustomTextField("Text");
successField.pseudoClassStateChanged(STATE_SUCCESS, true); successField.pseudoClassStateChanged(STATE_SUCCESS, true);
successField.setRight(new FontIcon(Feather.X)); successField.setRight(new FontIcon(Feather.X));
var successBlock = new SampleBlock("Success", successField); successField.setPrefWidth(PREF_WIDTH);
return new SampleBlock("Success", successField);
}
private SampleBlock dangerSample() {
var dangerField = new CustomTextField("Text"); var dangerField = new CustomTextField("Text");
dangerField.pseudoClassStateChanged(STATE_DANGER, true); dangerField.pseudoClassStateChanged(STATE_DANGER, true);
dangerField.setLeft(new FontIcon(Feather.MAP_PIN)); dangerField.setLeft(new FontIcon(Feather.MAP_PIN));
var dangerBlock = new SampleBlock("Danger", dangerField); dangerField.setPrefWidth(PREF_WIDTH);
return new SampleBlock("Danger", dangerField);
var flowPane = new FlowPane(20, 20);
flowPane.getChildren().setAll(
leftIconBlock.getRoot(),
rightIconBlock.getRoot(),
bothIconBlock.getRoot(),
noSideIconsBlock.getRoot(),
successBlock.getRoot(),
dangerBlock.getRoot()
);
return flowPane;
} }
} }

@ -6,6 +6,7 @@ import atlantafx.base.controls.Spacer;
import atlantafx.base.controls.ToggleSwitch; import atlantafx.base.controls.ToggleSwitch;
import atlantafx.base.theme.Styles; import atlantafx.base.theme.Styles;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.SampleBlock;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@ -47,20 +48,18 @@ public class DatePickerPage extends AbstractPage {
public DatePickerPage() { public DatePickerPage() {
super(); super();
createView(); setUserContent(new VBox(
new SampleBlock("Playground", createPlayground())
));
} }
private void createView() { private GridPane createPlayground() {
userContent.getChildren().addAll(playground()); var grid = new GridPane();
} grid.setHgap(40);
grid.setVgap(SampleBlock.BLOCK_VGAP);
private GridPane playground() { final var popupDatePicker = createPopupDatePicker();
var playground = new GridPane(); final var inlineDatePicker = createInlineDatePicker(null);
playground.setHgap(40);
playground.setVgap(10);
final var popupDatePicker = popupDatePicker();
final var inlineDatePicker = inlineDatePicker(null);
var inlineValue = new Label(); var inlineValue = new Label();
inlineValue.setAlignment(Pos.CENTER); inlineValue.setAlignment(Pos.CENTER);
@ -74,25 +73,27 @@ public class DatePickerPage extends AbstractPage {
weekNumToggle.setSelected(true); weekNumToggle.setSelected(true);
var chronologyToggle = new ToggleSwitch("Second chronology"); var chronologyToggle = new ToggleSwitch("Second chronology");
chronologyToggle.selectedProperty().addListener((obs, old, val) -> chronologyToggle.selectedProperty().addListener(
popupDatePicker.setChronology(val ? HijrahChronology.INSTANCE : null) (obs, old, val) -> popupDatePicker.setChronology(val ? HijrahChronology.INSTANCE : null)
); );
var editableToggle = new ToggleSwitch("Editable"); var editableToggle = new ToggleSwitch("Editable");
editableProperty.bind(editableToggle.selectedProperty()); editableProperty.bind(editableToggle.selectedProperty());
// clear selected value to demonstrate prompt text // clear selected value to demonstrate prompt text
editableProperty.addListener((obs, old, val) -> popupDatePicker.setValue(val ? null : TODAY)); editableProperty.addListener(
(obs, old, val) -> popupDatePicker.setValue(val ? null : TODAY)
);
var offPastDatesToggle = new ToggleSwitch("No past dates"); var offPastDatesToggle = new ToggleSwitch("No past dates");
offPastDatesProperty.bind(offPastDatesToggle.selectedProperty()); offPastDatesProperty.bind(offPastDatesToggle.selectedProperty());
offPastDatesProperty.addListener((obs, old, val) -> { offPastDatesProperty.addListener((obs, old, val) -> {
popupDatePicker.setDayCellFactory(val ? dp -> new CustomDateCell() : null); popupDatePicker.setDayCellFactory(val ? dp -> new FutureDateCell() : null);
popupDatePicker.setValue(TODAY); popupDatePicker.setValue(TODAY);
// we have to create new date picker, because changing cell factory won't update existing cells // we have to create new date picker, because changing cell factory won't update existing cells
var datePicker = inlineDatePicker(val ? dp -> new CustomDateCell() : null); var datePicker = createInlineDatePicker(val ? dp -> new FutureDateCell() : null);
playground.getChildren().removeIf(n -> n instanceof InlineDatePicker); grid.getChildren().removeIf(n -> n instanceof InlineDatePicker);
playground.add(datePicker, INLINE_DATE_PICKER_COL, INLINE_DATE_PICKER_ROW); grid.add(datePicker, INLINE_DATE_PICKER_COL, INLINE_DATE_PICKER_ROW);
inlineValue.textProperty().unbind(); inlineValue.textProperty().unbind();
inlineValue.textProperty().bind(datePicker.valueProperty().asString()); inlineValue.textProperty().bind(datePicker.valueProperty().asString());
}); });
@ -100,7 +101,8 @@ public class DatePickerPage extends AbstractPage {
var disablePickerToggle = new ToggleSwitch("Disable"); var disablePickerToggle = new ToggleSwitch("Disable");
disableProperty.bind(disablePickerToggle.selectedProperty()); disableProperty.bind(disablePickerToggle.selectedProperty());
var controls = new VBox(10, var controls = new VBox(
SampleBlock.BLOCK_VGAP,
weekNumToggle, weekNumToggle,
chronologyToggle, chronologyToggle,
editableToggle, editableToggle,
@ -109,7 +111,7 @@ public class DatePickerPage extends AbstractPage {
); );
controls.setAlignment(Pos.CENTER_RIGHT); controls.setAlignment(Pos.CENTER_RIGHT);
var colorSelector = new DatePickerColorSelector(playground); var colorSelector = new DatePickerColorSelector(grid);
// == GRID == // == GRID ==
@ -119,19 +121,19 @@ public class DatePickerPage extends AbstractPage {
var inlineLabel = new Label("Inline"); var inlineLabel = new Label("Inline");
inlineLabel.getStyleClass().add(Styles.TEXT_BOLD); inlineLabel.getStyleClass().add(Styles.TEXT_BOLD);
playground.add(defaultLabel, 0, 0); grid.add(defaultLabel, 0, 0);
playground.add(popupDatePicker, 0, 1); grid.add(popupDatePicker, 0, 1);
playground.add(new Spacer(20), 0, 2); grid.add(new Spacer(20), 0, 2);
playground.add(inlineLabel, 0, 3); grid.add(inlineLabel, 0, 3);
playground.add(inlineDatePicker, INLINE_DATE_PICKER_COL, INLINE_DATE_PICKER_ROW); grid.add(inlineDatePicker, INLINE_DATE_PICKER_COL, INLINE_DATE_PICKER_ROW);
playground.add(inlineValue, 0, 5); grid.add(inlineValue, 0, 5);
playground.add(colorSelector, 0, 6); grid.add(colorSelector, 0, 6);
playground.add(controls, 1, 0, 1, REMAINING); grid.add(controls, 1, 0, 1, REMAINING);
return playground; return grid;
} }
private DatePicker popupDatePicker() { private DatePicker createPopupDatePicker() {
var datePicker = new DatePicker(); var datePicker = new DatePicker();
datePicker.setConverter(DATE_CONVERTER); datePicker.setConverter(DATE_CONVERTER);
datePicker.setPromptText(DATE_FORMATTER_PROMPT); datePicker.setPromptText(DATE_FORMATTER_PROMPT);
@ -140,18 +142,16 @@ public class DatePickerPage extends AbstractPage {
datePicker.showWeekNumbersProperty().bind(weekNumProperty); datePicker.showWeekNumbersProperty().bind(weekNumProperty);
datePicker.editableProperty().bind(editableProperty); datePicker.editableProperty().bind(editableProperty);
datePicker.disableProperty().bind(disableProperty); datePicker.disableProperty().bind(disableProperty);
return datePicker; return datePicker;
} }
private InlineDatePicker inlineDatePicker(Callback<InlineDatePicker, DateCell> dayCellFactory) { private InlineDatePicker createInlineDatePicker(Callback<InlineDatePicker, DateCell> dayCellFactory) {
var datePicker = new InlineDatePicker(); var datePicker = new InlineDatePicker();
datePicker.setMaxSize(USE_PREF_SIZE, USE_PREF_SIZE); datePicker.setMaxSize(USE_PREF_SIZE, USE_PREF_SIZE);
datePicker.setDayCellFactory(dayCellFactory); datePicker.setDayCellFactory(dayCellFactory);
datePicker.setValue(TODAY); datePicker.setValue(TODAY);
datePicker.showWeekNumbersProperty().bind(weekNumProperty); datePicker.showWeekNumbersProperty().bind(weekNumProperty);
datePicker.disableProperty().bind(disableProperty); datePicker.disableProperty().bind(disableProperty);
return datePicker; return datePicker;
} }
@ -170,11 +170,13 @@ public class DatePickerPage extends AbstractPage {
if (dateString == null || dateString.trim().isEmpty()) { return null; } if (dateString == null || dateString.trim().isEmpty()) { return null; }
try { try {
return LocalDate.parse(dateString, DATE_FORMATTER); return LocalDate.parse(dateString, DATE_FORMATTER);
} catch (Exception e) { return null; } } catch (Exception e) {
return null;
}
} }
}; };
private static class CustomDateCell extends DateCell { private static class FutureDateCell extends DateCell {
public void updateItem(LocalDate date, boolean empty) { public void updateItem(LocalDate date, boolean empty) {
super.updateItem(date, empty); super.updateItem(date, empty);
@ -185,11 +187,11 @@ public class DatePickerPage extends AbstractPage {
// This class shares stylesheet with the AccentColorSelector // This class shares stylesheet with the AccentColorSelector
private static class DatePickerColorSelector extends HBox { private static class DatePickerColorSelector extends HBox {
private final Pane root; private final Pane parent;
public DatePickerColorSelector(Pane root) { public DatePickerColorSelector(Pane parent) {
super(); super();
this.root = root; this.parent = parent;
createView(); createView();
} }
@ -221,7 +223,7 @@ public class DatePickerPage extends AbstractPage {
} }
private void setColorVariables(String bgColorName, String fgColorName) { private void setColorVariables(String bgColorName, String fgColorName) {
for (Node node : root.getChildren()) { for (Node node : parent.getChildren()) {
var style = String.format("-color-date-border:%s;-color-date-month-year-bg:%s;-color-date-month-year-fg:%s;", var style = String.format("-color-date-border:%s;-color-date-month-year-bg:%s;-color-date-month-year-fg:%s;",
bgColorName, bgColorName,
bgColorName, bgColorName,
@ -236,7 +238,7 @@ public class DatePickerPage extends AbstractPage {
} }
private void resetColorVariables() { private void resetColorVariables() {
for (Node node : root.getChildren()) { for (Node node : parent.getChildren()) {
if (node instanceof InlineDatePicker dp) { if (node instanceof InlineDatePicker dp) {
var popup = dp.lookup(".date-picker-popup"); var popup = dp.lookup(".date-picker-popup");
if (popup != null) { popup.setStyle(null); } if (popup != null) { popup.setStyle(null); }

@ -2,7 +2,6 @@
package atlantafx.sampler.page.components; package atlantafx.sampler.page.components;
import atlantafx.base.controls.ToggleSwitch; import atlantafx.base.controls.ToggleSwitch;
import atlantafx.base.controls.Spacer;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
@ -10,10 +9,7 @@ import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Orientation; import javafx.geometry.Orientation;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.GridPane; import javafx.scene.layout.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.StageStyle; import javafx.stage.StageStyle;
import org.kordamp.ikonli.feather.Feather; import org.kordamp.ikonli.feather.Feather;
import org.kordamp.ikonli.javafx.FontIcon; import org.kordamp.ikonli.javafx.FontIcon;
@ -22,6 +18,7 @@ import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.ArrayList; import java.util.ArrayList;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
import static javafx.scene.control.Alert.AlertType; import static javafx.scene.control.Alert.AlertType;
import static javafx.scene.control.ButtonBar.ButtonData; import static javafx.scene.control.ButtonBar.ButtonData;
@ -41,10 +38,6 @@ public class DialogPage extends AbstractPage {
} }
private void createView() { private void createView() {
userContent.getChildren().setAll(playground());
}
private VBox playground() {
var showHeaderToggle = new ToggleSwitch("Show header"); var showHeaderToggle = new ToggleSwitch("Show header");
showHeaderProperty.bind(showHeaderToggle.selectedProperty()); showHeaderProperty.bind(showHeaderToggle.selectedProperty());
showHeaderToggle.setSelected(true); showHeaderToggle.setSelected(true);
@ -53,25 +46,30 @@ public class DialogPage extends AbstractPage {
minDecorationsProperty.bind(minDecorationsToggle.selectedProperty()); minDecorationsProperty.bind(minDecorationsToggle.selectedProperty());
minDecorationsToggle.setSelected(true); minDecorationsToggle.setSelected(true);
var controls = new HBox(20, new Spacer(), showHeaderToggle, minDecorationsToggle, new Spacer()); var controls = new HBox(BLOCK_HGAP, showHeaderToggle, minDecorationsToggle);
controls.setAlignment(Pos.CENTER); controls.setAlignment(Pos.CENTER);
// ~ var samples = new FlowPane(
PAGE_HGAP, PAGE_VGAP,
infoDialogSample(),
warningDialogSample(),
errorDialogSample(),
exceptionDialogSample(),
confirmationDialogSample(),
textInputDialogSample(),
choiceDialogSample()
);
var row1 = new HBox(40, infoDialogButton().getRoot(), warnDialogButton().getRoot(), errorDialogButton().getRoot()); setUserContent(new VBox(
10,
var row2 = new HBox(40, exceptionDialogButton().getRoot(), confirmationDialogButton().getRoot(), textInputDialogButton().getRoot(), choiceDialogButton().getRoot()); controls,
new Separator(Orientation.HORIZONTAL),
var playground = new VBox(20); samples
playground.setMinHeight(100); ));
playground.getChildren().setAll(controls, new Separator(Orientation.HORIZONTAL), row1, row2);
return playground;
} }
private SampleBlock infoDialogButton() { private SampleBlock infoDialogSample() {
var button = new Button("Click"); var button = new Button("Click", new FontIcon(Feather.INFO));
button.setGraphic(new FontIcon(Feather.INFO));
button.setOnAction(e -> { button.setOnAction(e -> {
var alert = new Alert(AlertType.INFORMATION); var alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Information Dialog"); alert.setTitle("Information Dialog");
@ -85,9 +83,8 @@ public class DialogPage extends AbstractPage {
return new SampleBlock("Information", button); return new SampleBlock("Information", button);
} }
private SampleBlock warnDialogButton() { private SampleBlock warningDialogSample() {
var button = new Button("Click"); var button = new Button("Click", new FontIcon(Feather.ALERT_TRIANGLE));
button.setGraphic(new FontIcon(Feather.ALERT_TRIANGLE));
button.setOnAction(e -> { button.setOnAction(e -> {
var alert = new Alert(AlertType.WARNING); var alert = new Alert(AlertType.WARNING);
alert.setTitle("Warning Dialog"); alert.setTitle("Warning Dialog");
@ -101,9 +98,8 @@ public class DialogPage extends AbstractPage {
return new SampleBlock("Warning", button); return new SampleBlock("Warning", button);
} }
private SampleBlock errorDialogButton() { private SampleBlock errorDialogSample() {
var button = new Button("Click"); var button = new Button("Click", new FontIcon(Feather.X_CIRCLE));
button.setGraphic(new FontIcon(Feather.X_CIRCLE));
button.setOnAction(e -> { button.setOnAction(e -> {
var alert = new Alert(AlertType.ERROR); var alert = new Alert(AlertType.ERROR);
alert.setTitle("Error Dialog"); alert.setTitle("Error Dialog");
@ -117,10 +113,8 @@ public class DialogPage extends AbstractPage {
return new SampleBlock("Error", button); return new SampleBlock("Error", button);
} }
private SampleBlock exceptionDialogButton() { private SampleBlock exceptionDialogSample() {
var button = new Button("Click"); var button = new Button("Click", new FontIcon(Feather.MEH));
button.setGraphic(new FontIcon(Feather.MEH));
button.setOnAction(e -> { button.setOnAction(e -> {
var alert = new Alert(AlertType.ERROR); var alert = new Alert(AlertType.ERROR);
alert.setTitle("Error Dialog"); alert.setTitle("Error Dialog");
@ -157,10 +151,8 @@ public class DialogPage extends AbstractPage {
return new SampleBlock("Exception", button); return new SampleBlock("Exception", button);
} }
private SampleBlock confirmationDialogButton() { private SampleBlock confirmationDialogSample() {
var button = new Button("Click"); var button = new Button("Click", new FontIcon(Feather.CHECK_SQUARE));
button.setGraphic(new FontIcon(Feather.CHECK_SQUARE));
button.setOnAction(e -> { button.setOnAction(e -> {
var alert = new Alert(AlertType.CONFIRMATION); var alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Confirmation Dialog"); alert.setTitle("Confirmation Dialog");
@ -181,10 +173,8 @@ public class DialogPage extends AbstractPage {
return new SampleBlock("Confirmation", button); return new SampleBlock("Confirmation", button);
} }
private SampleBlock textInputDialogButton() { private SampleBlock textInputDialogSample() {
var button = new Button("Click"); var button = new Button("Click", new FontIcon(Feather.EDIT_2));
button.setGraphic(new FontIcon(Feather.EDIT_2));
button.setOnAction(e -> { button.setOnAction(e -> {
var dialog = new TextInputDialog(); var dialog = new TextInputDialog();
dialog.setTitle("Text Input Dialog"); dialog.setTitle("Text Input Dialog");
@ -198,10 +188,8 @@ public class DialogPage extends AbstractPage {
return new SampleBlock("Text Input", button); return new SampleBlock("Text Input", button);
} }
private SampleBlock choiceDialogButton() { private SampleBlock choiceDialogSample() {
var button = new Button("Click"); var button = new Button("Click", new FontIcon(Feather.LIST));
button.setGraphic(new FontIcon(Feather.LIST));
button.setOnAction(e -> { button.setOnAction(e -> {
var choices = new ArrayList<>(); var choices = new ArrayList<>();
choices.add("A"); choices.add("A");

@ -2,27 +2,28 @@
package atlantafx.sampler.page.components; package atlantafx.sampler.page.components;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.SampleBlock;
import javafx.scene.layout.VBox;
import javafx.scene.web.HTMLEditor; import javafx.scene.web.HTMLEditor;
public class HTMLEditorPage extends AbstractPage { public class HTMLEditorPage extends AbstractPage {
public static final String NAME = "HTMLEditor"; public static final String NAME = "HTMLEditor";
@Override
public String getName() { return NAME; }
public HTMLEditorPage() { public HTMLEditorPage() {
super(); super();
createView(); setUserContent(new VBox(
editorSample()
));
} }
private void createView() { private SampleBlock editorSample() {
var editor = new HTMLEditor(); var editor = new HTMLEditor();
editor.setPrefHeight(400); editor.setPrefHeight(400);
editor.setHtmlText(String.join("<br/><br/>", FAKER.lorem().paragraphs(5))); editor.setHtmlText(String.join("<br/><br/>", FAKER.lorem().paragraphs(10)));
return new SampleBlock("Playground", editor);
userContent.getChildren().setAll(editor);
}
@Override
public String getName() {
return NAME;
} }
} }

@ -3,11 +3,12 @@ package atlantafx.sampler.page.components;
import atlantafx.base.theme.Styles; import atlantafx.base.theme.Styles;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import org.kordamp.ikonli.feather.Feather; import org.kordamp.ikonli.feather.Feather;
import org.kordamp.ikonli.javafx.FontIcon; import org.kordamp.ikonli.javafx.FontIcon;
@ -22,16 +23,10 @@ public class InputGroupPage extends AbstractPage {
public InputGroupPage() { public InputGroupPage() {
super(); super();
createView(); setUserContent(new VBox(
} Page.PAGE_VGAP,
expandingHBox(httpMethodSample(), passwordSample()),
private void createView() { expandingHBox(networkSample(), dropdownSample())
userContent.getChildren().addAll(new FlowPane(
20, 20,
httpMethodSample().getRoot(),
passwordSample().getRoot(),
networkSample().getRoot(),
dropdownSample().getRoot()
)); ));
} }
@ -47,11 +42,11 @@ public class InputGroupPage extends AbstractPage {
var box = new HBox(leftCombo, rightText); var box = new HBox(leftCombo, rightText);
box.setAlignment(Pos.CENTER_LEFT); box.setAlignment(Pos.CENTER_LEFT);
return new SampleBlock("ComboBox + TextField", box); return new SampleBlock("ComboBox & TextField", box);
} }
private SampleBlock passwordSample() { private SampleBlock passwordSample() {
var leftPassword = new PasswordField(); var leftPassword = new TextField();
leftPassword.setText(FAKER.internet().password()); leftPassword.setText(FAKER.internet().password());
leftPassword.getStyleClass().add(Styles.LEFT_PILL); leftPassword.getStyleClass().add(Styles.LEFT_PILL);
@ -63,19 +58,21 @@ public class InputGroupPage extends AbstractPage {
var box = new HBox(leftPassword, rightBtn); var box = new HBox(leftPassword, rightBtn);
box.setAlignment(Pos.CENTER_LEFT); box.setAlignment(Pos.CENTER_LEFT);
return new SampleBlock("Password Field + Button", box); return new SampleBlock("Text Field & Button", box);
} }
private SampleBlock networkSample() { private SampleBlock networkSample() {
var leftText = new TextField("192.168.1.10"); var leftText = new TextField("192.168.1.10");
leftText.getStyleClass().add(Styles.LEFT_PILL); leftText.getStyleClass().add(Styles.LEFT_PILL);
leftText.setPrefWidth(140);
var centerText = new TextField("24"); var centerText = new TextField("24");
centerText.getStyleClass().add(Styles.CENTER_PILL); centerText.getStyleClass().add(Styles.CENTER_PILL);
centerText.setPrefWidth(50); centerText.setPrefWidth(70);
var rightText = new TextField("192.168.1.10"); var rightText = new TextField("192.168.1.1");
rightText.getStyleClass().add(Styles.RIGHT_PILL); rightText.getStyleClass().add(Styles.RIGHT_PILL);
rightText.setPrefWidth(140);
var box = new HBox(leftText, centerText, rightText); var box = new HBox(leftText, centerText, rightText);
box.setAlignment(Pos.CENTER_LEFT); box.setAlignment(Pos.CENTER_LEFT);
@ -84,21 +81,26 @@ public class InputGroupPage extends AbstractPage {
} }
private SampleBlock dropdownSample() { private SampleBlock dropdownSample() {
var leftMenu = new MenuButton(FAKER.harryPotter().character()); var rightText = new TextField(FAKER.harryPotter().spell());
leftMenu.getItems().addAll(
new MenuItem(FAKER.harryPotter().spell()),
new MenuItem(FAKER.harryPotter().spell()),
new MenuItem(FAKER.harryPotter().spell())
);
leftMenu.getStyleClass().add(Styles.LEFT_PILL);
var rightText = new TextField();
rightText.getStyleClass().add(Styles.RIGHT_PILL); rightText.getStyleClass().add(Styles.RIGHT_PILL);
var spellItem = new MenuItem("Spell");
spellItem.setOnAction(e -> rightText.setText(FAKER.harryPotter().spell()));
var characterItem = new MenuItem("Character");
characterItem.setOnAction(e -> rightText.setText(FAKER.harryPotter().character()));
var locationItem = new MenuItem("Location");
locationItem.setOnAction(e -> rightText.setText(FAKER.harryPotter().location()));
var leftMenu = new MenuButton("Generate");
leftMenu.getItems().addAll(spellItem, characterItem, locationItem);
leftMenu.getStyleClass().add(Styles.LEFT_PILL);
var box = new HBox(leftMenu, rightText); var box = new HBox(leftMenu, rightText);
box.setAlignment(Pos.CENTER_LEFT); box.setAlignment(Pos.CENTER_LEFT);
return new SampleBlock("MenuButton + TextField", box); return new SampleBlock("MenuButton & TextField", box);
} }
} }

@ -6,14 +6,16 @@ import atlantafx.base.controls.ToggleSwitch;
import atlantafx.base.theme.Tweaks; import atlantafx.base.theme.Tweaks;
import atlantafx.sampler.fake.domain.Book; import atlantafx.sampler.fake.domain.Book;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import javafx.geometry.Orientation; import atlantafx.sampler.page.SampleBlock;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.control.cell.CheckBoxListCell; import javafx.scene.control.cell.CheckBoxListCell;
import javafx.scene.control.cell.ChoiceBoxListCell; import javafx.scene.control.cell.ChoiceBoxListCell;
import javafx.scene.control.cell.ComboBoxListCell; import javafx.scene.control.cell.ComboBoxListCell;
import javafx.scene.control.cell.TextFieldListCell; import javafx.scene.control.cell.TextFieldListCell;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.util.StringConverter; import javafx.util.StringConverter;
import org.kordamp.ikonli.feather.Feather; import org.kordamp.ikonli.feather.Feather;
@ -27,6 +29,8 @@ import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static atlantafx.base.theme.Styles.*; import static atlantafx.base.theme.Styles.*;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
public class ListPage extends AbstractPage { public class ListPage extends AbstractPage {
@ -35,54 +39,20 @@ public class ListPage extends AbstractPage {
@Override @Override
public String getName() { return NAME; } public String getName() { return NAME; }
private VBox playground;
private ComboBox<Example> exampleSelect;
private final List<Book> dataList = generate(() -> Book.random(FAKER), 50); private final List<Book> dataList = generate(() -> Book.random(FAKER), 50);
private final StringConverter<Book> bookStringConverter = new StringConverter<>() { private final StringConverter<Book> bookStringConverter = new BookStringConverter(dataList);
private final BorderPane listWrapper = new BorderPane();
@Override private final ComboBox<Example> exampleSelect = createExampleSelect();
public String toString(Book book) {
if (book == null) { return null; }
return String.format("\"%s\" by %s", book.getTitle(), book.getAuthor());
}
@Override
public Book fromString(String s) {
if (s == null) { return null; }
int sep = s.indexOf("\" by");
String title = s.substring(1, sep);
String author = s.substring(sep + "\" by".length());
return dataList.stream()
.filter(b -> Objects.equals(b.getTitle(), title) && Objects.equals(b.getAuthor(), author))
.findFirst()
.orElse(null);
}
};
public ListPage() { public ListPage() {
super(); super();
createView();
var sample = new SampleBlock("Playground", createPlayground());
sample.setFillHeight(true);
setUserContent(sample);
} }
private void createView() { private VBox createPlayground() {
exampleSelect = exampleSelect();
playground = playground(exampleSelect);
userContent.getChildren().setAll(playground);
}
@Override
protected void onRendered() {
super.onRendered();
exampleSelect.getSelectionModel().selectFirst();
}
private VBox playground(ComboBox<Example> exampleSelect) {
var playground = new VBox(10);
playground.setMinHeight(100);
var borderedToggle = new ToggleSwitch("Bordered"); var borderedToggle = new ToggleSwitch("Bordered");
borderedToggle.selectedProperty().addListener((obs, old, value) -> toggleListProperty(lv -> toggleStyleClass(lv, BORDERED))); borderedToggle.selectedProperty().addListener((obs, old, value) -> toggleListProperty(lv -> toggleStyleClass(lv, BORDERED)));
@ -100,37 +70,30 @@ public class ListPage extends AbstractPage {
if (val != null) { lv.setDisable(val); } if (val != null) { lv.setDisable(val); }
})); }));
var controls = new HBox(20, var controls = new HBox(BLOCK_HGAP, borderedToggle, denseToggle, stripedToggle, edge2edgeToggle);
new Spacer(), controls.setAlignment(Pos.CENTER);
borderedToggle,
denseToggle,
stripedToggle,
edge2edgeToggle,
disableToggle,
new Spacer()
);
playground.getChildren().setAll( VBox.setVgrow(listWrapper, Priority.ALWAYS);
new Label("Select an example:"),
var playground = new VBox(
BLOCK_VGAP,
new HBox(new Label("Select an example:"), new Spacer(), disableToggle),
exampleSelect, exampleSelect,
new Spacer(Orientation.VERTICAL), // placeholder for ListView<?> listWrapper,
controls controls
); );
playground.setMinHeight(100);
return playground; return playground;
} }
private ComboBox<Example> exampleSelect() { private ComboBox<Example> createExampleSelect() {
var select = new ComboBox<Example>(); var select = new ComboBox<Example>();
select.setMaxWidth(Double.MAX_VALUE); select.setMaxWidth(Double.MAX_VALUE);
select.getItems().setAll(Example.values()); select.getItems().setAll(Example.values());
select.getSelectionModel().selectedItemProperty().addListener((obs, old, val) -> { select.getSelectionModel().selectedItemProperty().addListener((obs, old, val) -> {
if (val == null) { return; } if (val == null) { return; }
if (playground.getChildren().size() != 4) {
throw new RuntimeException("Unexpected container size.");
}
ListView<?> newList = createList(val); ListView<?> newList = createList(val);
@ -139,15 +102,13 @@ public class ListPage extends AbstractPage {
List<String> currentStyles = lv.getStyleClass(); List<String> currentStyles = lv.getStyleClass();
currentStyles.remove("list-view"); currentStyles.remove("list-view");
newList.getStyleClass().addAll(currentStyles); newList.getStyleClass().addAll(currentStyles);
newList.setDisable(lv.isDisable()); newList.setDisable(lv.isDisable());
}); });
playground.getChildren().set(2, newList); listWrapper.setCenter(newList);
}); });
select.setConverter(new StringConverter<>() { select.setConverter(new StringConverter<>() {
@Override @Override
public String toString(Example example) { public String toString(Example example) {
return example == null ? "" : example.getName(); return example == null ? "" : example.getName();
@ -162,12 +123,16 @@ public class ListPage extends AbstractPage {
return select; return select;
} }
@Override
protected void onRendered() {
super.onRendered();
exampleSelect.getSelectionModel().selectFirst();
}
private Optional<ListView<?>> findDisplayedList() { private Optional<ListView<?>> findDisplayedList() {
if (playground == null) { return Optional.empty(); } return listWrapper.getChildren().size() > 0 ?
return playground.getChildren().stream() Optional.of((ListView<?>) listWrapper.getChildren().get(0)) :
.filter(c -> c instanceof ListView<?>) Optional.empty();
.findFirst()
.map(c -> (ListView<?>) c);
} }
private void toggleListProperty(Consumer<ListView<?>> consumer) { private void toggleListProperty(Consumer<ListView<?>> consumer) {
@ -263,6 +228,35 @@ public class ListPage extends AbstractPage {
} }
} }
private static class BookStringConverter extends StringConverter<Book> {
private final List<Book> dataList;
public BookStringConverter(List<Book> dataList) {
this.dataList = dataList;
}
@Override
public String toString(Book book) {
if (book == null) { return null; }
return String.format("\"%s\" by %s", book.getTitle(), book.getAuthor());
}
@Override
public Book fromString(String s) {
if (s == null) { return null; }
int sep = s.indexOf("\" by");
String title = s.substring(1, sep);
String author = s.substring(sep + "\" by".length());
return dataList.stream()
.filter(b -> Objects.equals(b.getTitle(), title) && Objects.equals(b.getAuthor(), author))
.findFirst()
.orElse(null);
}
}
private static class NestedControlsListCell extends ListCell<Book> { private static class NestedControlsListCell extends ListCell<Book> {
private final HBox root; private final HBox root;

@ -3,64 +3,63 @@ package atlantafx.sampler.page.components;
import atlantafx.base.theme.Tweaks; import atlantafx.base.theme.Tweaks;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import javafx.geometry.Side; import javafx.geometry.Side;
import javafx.scene.control.MenuButton; import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem; import javafx.scene.control.MenuItem;
import javafx.scene.control.SplitMenuButton; import javafx.scene.control.SplitMenuButton;
import javafx.scene.layout.FlowPane; import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import org.kordamp.ikonli.feather.Feather; import org.kordamp.ikonli.feather.Feather;
import org.kordamp.ikonli.javafx.FontIcon; import org.kordamp.ikonli.javafx.FontIcon;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import static atlantafx.base.theme.Styles.*; import static atlantafx.base.theme.Styles.*;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
public class MenuButtonPage extends AbstractPage { public class MenuButtonPage extends AbstractPage {
public static final String NAME = "MenuButton"; public static final String NAME = "MenuButton";
private static final int PREF_WIDTH = 150;
@Override @Override
public String getName() { return NAME; } public String getName() { return NAME; }
public MenuButtonPage() { public MenuButtonPage() {
super(); super();
createView(); setUserContent(new VBox(
} Page.PAGE_VGAP,
expandingHBox(basicSample(), iconOnlySample()),
expandingHBox(coloredSample(), outlinedSample()),
expandingHBox(popupSideSample(), noArrowSample()),
disabledSample()
private void createView() { ));
userContent.getChildren().addAll(
basicSample().getRoot(),
coloredSample().getRoot(),
popupSideSample().getRoot(),
iconOnlySample().getRoot(),
outlinedSample().getRoot(),
disabledSample().getRoot(),
noArrowSample().getRoot()
);
} }
private SampleBlock basicSample() { private SampleBlock basicSample() {
var basicMenuBtn = new MenuButton("_Menu Button"); var basicMenuBtn = new MenuButton("_Menu Button");
basicMenuBtn.getItems().setAll(menuItems(5)); basicMenuBtn.getItems().setAll(createItems(5));
basicMenuBtn.setMnemonicParsing(true); basicMenuBtn.setMnemonicParsing(true);
basicMenuBtn.setOnAction(PRINT_SOURCE);
var basicSplitBtn = new SplitMenuButton(menuItems(5)); var basicSplitBtn = new SplitMenuButton(createItems(5));
basicSplitBtn.setText("_Split Menu Button"); basicSplitBtn.setText("_Split Menu Button");
basicSplitBtn.setMnemonicParsing(true); basicSplitBtn.setMnemonicParsing(true);
basicSplitBtn.setOnAction(PRINT_SOURCE);
var flatMenuBtn = new MenuButton("Flat"); var flatMenuBtn = new MenuButton("Flat");
flatMenuBtn.getItems().setAll(menuItems(5)); flatMenuBtn.getItems().setAll(createItems(5));
flatMenuBtn.getStyleClass().add(FLAT); flatMenuBtn.getStyleClass().add(FLAT);
var flatSplitBtn = new SplitMenuButton(menuItems(5)); var flatSplitBtn = new SplitMenuButton(createItems(5));
flatSplitBtn.setText("Flat"); flatSplitBtn.setText("Flat");
flatSplitBtn.getStyleClass().add(FLAT); flatSplitBtn.getStyleClass().add(FLAT);
var content = new HBox(10); var content = new FlowPane(BLOCK_HGAP, BLOCK_VGAP);
content.getChildren().addAll(basicMenuBtn, basicSplitBtn, flatMenuBtn, flatSplitBtn); content.getChildren().addAll(basicMenuBtn, basicSplitBtn, flatMenuBtn, flatSplitBtn);
return new SampleBlock("Basic", content); return new SampleBlock("Basic", content);
@ -68,72 +67,76 @@ public class MenuButtonPage extends AbstractPage {
private SampleBlock coloredSample() { private SampleBlock coloredSample() {
var accentMenuBtn = new MenuButton("_Accent"); var accentMenuBtn = new MenuButton("_Accent");
accentMenuBtn.getItems().setAll(menuItems(5)); accentMenuBtn.getItems().setAll(createItems(5));
accentMenuBtn.getStyleClass().add(ACCENT); accentMenuBtn.getStyleClass().add(ACCENT);
accentMenuBtn.setMnemonicParsing(true); accentMenuBtn.setMnemonicParsing(true);
accentMenuBtn.setOnAction(PRINT_SOURCE); accentMenuBtn.setPrefWidth(PREF_WIDTH);
var accentSplitBtn = new SplitMenuButton(menuItems(5)); var accentSplitBtn = new SplitMenuButton(createItems(5));
accentSplitBtn.setText("Accent"); accentSplitBtn.setText("Accent");
accentSplitBtn.getStyleClass().add(ACCENT); accentSplitBtn.getStyleClass().add(ACCENT);
accentSplitBtn.setPrefWidth(PREF_WIDTH);
var successMenuBtn = new MenuButton("Success"); var successMenuBtn = new MenuButton("Success");
successMenuBtn.getItems().setAll(menuItems(5)); successMenuBtn.getItems().setAll(createItems(5));
successMenuBtn.setGraphic(new FontIcon(Feather.CHECK)); successMenuBtn.setGraphic(new FontIcon(Feather.CHECK));
successMenuBtn.getStyleClass().add(SUCCESS); successMenuBtn.getStyleClass().add(SUCCESS);
successMenuBtn.setPrefWidth(PREF_WIDTH);
var successSplitBtn = new SplitMenuButton(menuItems(5)); var successSplitBtn = new SplitMenuButton(createItems(5));
successMenuBtn.setGraphic(new FontIcon(Feather.CHECK)); successSplitBtn.setGraphic(new FontIcon(Feather.CHECK));
successSplitBtn.setText("_Success"); successSplitBtn.setText("_Success");
successSplitBtn.getStyleClass().add(SUCCESS); successSplitBtn.getStyleClass().add(SUCCESS);
successSplitBtn.setMnemonicParsing(true); successSplitBtn.setMnemonicParsing(true);
successSplitBtn.setOnAction(PRINT_SOURCE); successSplitBtn.setPrefWidth(PREF_WIDTH);
var dangerMenuBtn = new MenuButton("Danger"); var dangerMenuBtn = new MenuButton("Danger");
dangerMenuBtn.setGraphic(new FontIcon(Feather.TRASH)); dangerMenuBtn.setGraphic(new FontIcon(Feather.TRASH));
dangerMenuBtn.getItems().setAll(menuItems(5)); dangerMenuBtn.getItems().setAll(createItems(5));
dangerMenuBtn.getStyleClass().add(DANGER); dangerMenuBtn.getStyleClass().add(DANGER);
dangerMenuBtn.setPrefWidth(PREF_WIDTH);
var dangerSplitBtn = new SplitMenuButton(menuItems(5)); var dangerSplitBtn = new SplitMenuButton(createItems(5));
dangerSplitBtn.setGraphic(new FontIcon(Feather.TRASH)); dangerSplitBtn.setGraphic(new FontIcon(Feather.TRASH));
dangerSplitBtn.setText("_Danger"); dangerSplitBtn.setText("_Danger");
dangerSplitBtn.getStyleClass().add(DANGER); dangerSplitBtn.getStyleClass().add(DANGER);
dangerSplitBtn.setMnemonicParsing(true); dangerSplitBtn.setMnemonicParsing(true);
dangerSplitBtn.setOnAction(PRINT_SOURCE); dangerSplitBtn.setPrefWidth(PREF_WIDTH);
var content = new HBox(10); var content = new GridPane();
content.getChildren().addAll( content.setHgap(BLOCK_HGAP);
accentMenuBtn, accentSplitBtn, content.setVgap(BLOCK_VGAP);
successMenuBtn, successSplitBtn, content.add(accentMenuBtn, 0, 0);
dangerMenuBtn, dangerSplitBtn content.add(accentSplitBtn, 1, 0);
); content.add(successMenuBtn, 0, 1);
content.add(successSplitBtn, 1, 1);
content.add(dangerMenuBtn, 0, 2);
content.add(dangerSplitBtn, 1, 2);
return new SampleBlock("Colored", content); return new SampleBlock("Colored", content);
} }
private SampleBlock popupSideSample() { private SampleBlock popupSideSample() {
var topMenuBtn = new MenuButton("Top"); var topMenuBtn = new MenuButton("Top");
topMenuBtn.getItems().setAll(menuItems(5)); topMenuBtn.getItems().setAll(createItems(5));
topMenuBtn.setPopupSide(Side.TOP); topMenuBtn.setPopupSide(Side.TOP);
var rightMenuBtn = new MenuButton("Right"); var rightMenuBtn = new MenuButton("Right");
rightMenuBtn.getItems().setAll(menuItems(5)); rightMenuBtn.getItems().setAll(createItems(5));
rightMenuBtn.setPopupSide(Side.RIGHT); rightMenuBtn.setPopupSide(Side.RIGHT);
rightMenuBtn.getStyleClass().add(ACCENT); rightMenuBtn.getStyleClass().add(ACCENT);
var bottomMenuBtn = new MenuButton("Bottom"); var bottomMenuBtn = new MenuButton("Bottom");
bottomMenuBtn.setGraphic(new FontIcon(Feather.CHECK)); bottomMenuBtn.getItems().setAll(createItems(5));
bottomMenuBtn.getItems().setAll(menuItems(5));
bottomMenuBtn.setPopupSide(Side.BOTTOM); bottomMenuBtn.setPopupSide(Side.BOTTOM);
bottomMenuBtn.getStyleClass().add(SUCCESS); bottomMenuBtn.getStyleClass().add(SUCCESS);
var leftMenuBtn = new MenuButton("Left"); var leftMenuBtn = new MenuButton("Left");
leftMenuBtn.setGraphic(new FontIcon(Feather.TRASH)); leftMenuBtn.getItems().setAll(createItems(5));
leftMenuBtn.getItems().setAll(menuItems(5));
leftMenuBtn.setPopupSide(Side.LEFT); leftMenuBtn.setPopupSide(Side.LEFT);
leftMenuBtn.getStyleClass().add(DANGER); leftMenuBtn.getStyleClass().add(DANGER);
var content = new FlowPane(10, 10); var content = new FlowPane(BLOCK_HGAP, BLOCK_VGAP);
content.getChildren().addAll(topMenuBtn, rightMenuBtn, bottomMenuBtn, leftMenuBtn); content.getChildren().addAll(topMenuBtn, rightMenuBtn, bottomMenuBtn, leftMenuBtn);
return new SampleBlock("Popup Side", content); return new SampleBlock("Popup Side", content);
@ -142,23 +145,23 @@ public class MenuButtonPage extends AbstractPage {
private SampleBlock iconOnlySample() { private SampleBlock iconOnlySample() {
var basicMenuBtn = new MenuButton(); var basicMenuBtn = new MenuButton();
basicMenuBtn.setGraphic(new FontIcon(Feather.MORE_HORIZONTAL)); basicMenuBtn.setGraphic(new FontIcon(Feather.MORE_HORIZONTAL));
basicMenuBtn.getItems().setAll(menuItems(5)); basicMenuBtn.getItems().setAll(createItems(5));
basicMenuBtn.getStyleClass().addAll(BUTTON_ICON); basicMenuBtn.getStyleClass().addAll(BUTTON_ICON);
var basicSplitBtn = new SplitMenuButton(menuItems(5)); var basicSplitBtn = new SplitMenuButton(createItems(5));
basicSplitBtn.setGraphic(new FontIcon(Feather.MORE_HORIZONTAL)); basicSplitBtn.setGraphic(new FontIcon(Feather.MORE_HORIZONTAL));
basicSplitBtn.getStyleClass().addAll(BUTTON_ICON); basicSplitBtn.getStyleClass().addAll(BUTTON_ICON);
var accentMenuBtn = new MenuButton(); var accentMenuBtn = new MenuButton();
accentMenuBtn.setGraphic(new FontIcon(Feather.MENU)); accentMenuBtn.setGraphic(new FontIcon(Feather.MENU));
accentMenuBtn.getItems().setAll(menuItems(5)); accentMenuBtn.getItems().setAll(createItems(5));
accentMenuBtn.getStyleClass().addAll(BUTTON_ICON, ACCENT); accentMenuBtn.getStyleClass().addAll(BUTTON_ICON, ACCENT);
var accentSplitBtn = new SplitMenuButton(menuItems(5)); var accentSplitBtn = new SplitMenuButton(createItems(5));
accentSplitBtn.setGraphic(new FontIcon(Feather.MENU)); accentSplitBtn.setGraphic(new FontIcon(Feather.MENU));
accentSplitBtn.getStyleClass().addAll(BUTTON_ICON, ACCENT); accentSplitBtn.getStyleClass().addAll(BUTTON_ICON, ACCENT);
var content = new FlowPane(10, 10); var content = new FlowPane(BLOCK_HGAP, BLOCK_VGAP);
content.getChildren().addAll(basicMenuBtn, basicSplitBtn, accentMenuBtn, accentSplitBtn); content.getChildren().addAll(basicMenuBtn, basicSplitBtn, accentMenuBtn, accentSplitBtn);
return new SampleBlock("Icons", content); return new SampleBlock("Icons", content);
@ -166,71 +169,77 @@ public class MenuButtonPage extends AbstractPage {
private SampleBlock outlinedSample() { private SampleBlock outlinedSample() {
var accentMenuBtn = new MenuButton("Accen_t"); var accentMenuBtn = new MenuButton("Accen_t");
accentMenuBtn.getItems().setAll(menuItems(5)); accentMenuBtn.getItems().setAll(createItems(5));
accentMenuBtn.getStyleClass().addAll(BUTTON_OUTLINED, ACCENT); accentMenuBtn.getStyleClass().addAll(BUTTON_OUTLINED, ACCENT);
accentMenuBtn.setMnemonicParsing(true); accentMenuBtn.setMnemonicParsing(true);
accentMenuBtn.setOnAction(PRINT_SOURCE); accentMenuBtn.setPrefWidth(PREF_WIDTH);
var accentSplitBtn = new SplitMenuButton(menuItems(5)); var accentSplitBtn = new SplitMenuButton(createItems(5));
accentSplitBtn.setText("Accent"); accentSplitBtn.setText("Accent");
accentSplitBtn.getStyleClass().addAll(BUTTON_OUTLINED, ACCENT); accentSplitBtn.getStyleClass().addAll(BUTTON_OUTLINED, ACCENT);
accentSplitBtn.setPrefWidth(PREF_WIDTH);
var successMenuBtn = new MenuButton("S_uccess"); var successMenuBtn = new MenuButton("S_uccess");
successMenuBtn.getItems().setAll(menuItems(5)); successMenuBtn.getItems().setAll(createItems(5));
successMenuBtn.setGraphic(new FontIcon(Feather.CHECK)); successMenuBtn.setGraphic(new FontIcon(Feather.CHECK));
successMenuBtn.getStyleClass().addAll(BUTTON_OUTLINED, SUCCESS); successMenuBtn.getStyleClass().addAll(BUTTON_OUTLINED, SUCCESS);
successMenuBtn.setMnemonicParsing(true); successMenuBtn.setMnemonicParsing(true);
successMenuBtn.setOnAction(PRINT_SOURCE); successMenuBtn.setPrefWidth(PREF_WIDTH);
var successSplitBtn = new SplitMenuButton(menuItems(5)); var successSplitBtn = new SplitMenuButton(createItems(5));
successMenuBtn.setGraphic(new FontIcon(Feather.CHECK)); successSplitBtn.setGraphic(new FontIcon(Feather.CHECK));
successSplitBtn.setText("Success"); successSplitBtn.setText("Success");
successSplitBtn.getStyleClass().addAll(BUTTON_OUTLINED, SUCCESS); successSplitBtn.getStyleClass().addAll(BUTTON_OUTLINED, SUCCESS);
successSplitBtn.setPrefWidth(PREF_WIDTH);
var dangerMenuBtn = new MenuButton("Danger"); var dangerMenuBtn = new MenuButton("Danger");
dangerMenuBtn.setGraphic(new FontIcon(Feather.TRASH)); dangerMenuBtn.setGraphic(new FontIcon(Feather.TRASH));
dangerMenuBtn.getItems().setAll(menuItems(5)); dangerMenuBtn.getItems().setAll(createItems(5));
dangerMenuBtn.getStyleClass().addAll(BUTTON_OUTLINED, DANGER); dangerMenuBtn.getStyleClass().addAll(BUTTON_OUTLINED, DANGER);
dangerMenuBtn.setPrefWidth(PREF_WIDTH);
var dangerSplitBtn = new SplitMenuButton(menuItems(5)); var dangerSplitBtn = new SplitMenuButton(createItems(5));
dangerSplitBtn.setGraphic(new FontIcon(Feather.TRASH)); dangerSplitBtn.setGraphic(new FontIcon(Feather.TRASH));
dangerSplitBtn.setText("Dan_ger"); dangerSplitBtn.setText("Dan_ger");
dangerSplitBtn.getStyleClass().addAll(BUTTON_OUTLINED, DANGER); dangerSplitBtn.getStyleClass().addAll(BUTTON_OUTLINED, DANGER);
dangerSplitBtn.setMnemonicParsing(true); dangerSplitBtn.setMnemonicParsing(true);
dangerSplitBtn.setOnAction(PRINT_SOURCE); dangerSplitBtn.setPrefWidth(PREF_WIDTH);
var content = new HBox(10); var content = new GridPane();
content.getChildren().addAll( content.setHgap(BLOCK_HGAP);
accentMenuBtn, accentSplitBtn, content.setVgap(BLOCK_VGAP);
successMenuBtn, successSplitBtn, content.add(accentMenuBtn, 0, 0);
dangerMenuBtn, dangerSplitBtn content.add(accentSplitBtn, 1, 0);
); content.add(successMenuBtn, 0, 1);
content.add(successSplitBtn, 1, 1);
content.add(dangerMenuBtn, 0, 2);
content.add(dangerSplitBtn, 1, 2);
return new SampleBlock("Outlined", content); return new SampleBlock("Outlined", content);
} }
private SampleBlock disabledSample() { private SampleBlock disabledSample() {
var basicMenuBtn = new MenuButton("Menu Button"); var basicMenuBtn = new MenuButton("Menu Button");
basicMenuBtn.getItems().setAll(menuItems(5)); basicMenuBtn.getItems().setAll(createItems(5));
basicMenuBtn.setDisable(true); basicMenuBtn.setDisable(true);
var accentSplitBtn = new SplitMenuButton(); var accentSplitBtn = new SplitMenuButton();
accentSplitBtn.setText("Accent"); accentSplitBtn.setText("Accent");
accentSplitBtn.getItems().setAll(menuItems(5)); accentSplitBtn.getItems().setAll(createItems(5));
accentSplitBtn.getStyleClass().addAll(ACCENT); accentSplitBtn.getStyleClass().addAll(ACCENT);
accentSplitBtn.setDisable(true); accentSplitBtn.setDisable(true);
var flatMenuBtn = new MenuButton("Flat"); var flatMenuBtn = new MenuButton("Flat");
flatMenuBtn.getItems().setAll(menuItems(5)); flatMenuBtn.getItems().setAll(createItems(5));
flatMenuBtn.getStyleClass().addAll(FLAT); flatMenuBtn.getStyleClass().addAll(FLAT);
flatMenuBtn.setDisable(true); flatMenuBtn.setDisable(true);
var iconMenuBtn = new MenuButton(); var iconMenuBtn = new MenuButton();
iconMenuBtn.getItems().setAll(menuItems(5)); iconMenuBtn.getItems().setAll(createItems(5));
iconMenuBtn.getStyleClass().addAll(BUTTON_ICON); iconMenuBtn.getStyleClass().addAll(BUTTON_ICON);
iconMenuBtn.setDisable(true); iconMenuBtn.setDisable(true);
var sample = new HBox(10); var sample = new HBox(BLOCK_HGAP);
sample.getChildren().addAll(basicMenuBtn, accentSplitBtn, flatMenuBtn, iconMenuBtn); sample.getChildren().addAll(basicMenuBtn, accentSplitBtn, flatMenuBtn, iconMenuBtn);
return new SampleBlock("Disabled", sample); return new SampleBlock("Disabled", sample);
@ -238,26 +247,26 @@ public class MenuButtonPage extends AbstractPage {
private SampleBlock noArrowSample() { private SampleBlock noArrowSample() {
var basicMenuBtn = new MenuButton("_Menu Button"); var basicMenuBtn = new MenuButton("_Menu Button");
basicMenuBtn.getItems().setAll(menuItems(5)); basicMenuBtn.getItems().setAll(createItems(5));
basicMenuBtn.getStyleClass().addAll(Tweaks.NO_ARROW); basicMenuBtn.getStyleClass().addAll(Tweaks.NO_ARROW);
var flatMenuBtn = new MenuButton("Flat"); var flatMenuBtn = new MenuButton("Flat");
flatMenuBtn.getItems().setAll(menuItems(5)); flatMenuBtn.getItems().setAll(createItems(5));
flatMenuBtn.getStyleClass().addAll(FLAT, Tweaks.NO_ARROW); flatMenuBtn.getStyleClass().addAll(FLAT, Tweaks.NO_ARROW);
var iconMenuBtn = new MenuButton(); var iconMenuBtn = new MenuButton();
iconMenuBtn.setGraphic(new FontIcon(Feather.MORE_HORIZONTAL)); iconMenuBtn.setGraphic(new FontIcon(Feather.MORE_HORIZONTAL));
iconMenuBtn.getItems().setAll(menuItems(5)); iconMenuBtn.getItems().setAll(createItems(5));
iconMenuBtn.getStyleClass().addAll(BUTTON_ICON, Tweaks.NO_ARROW); iconMenuBtn.getStyleClass().addAll(BUTTON_ICON, Tweaks.NO_ARROW);
var content = new HBox(10); var content = new HBox(BLOCK_HGAP);
content.getChildren().addAll(basicMenuBtn, flatMenuBtn, iconMenuBtn); content.getChildren().addAll(basicMenuBtn, flatMenuBtn, iconMenuBtn);
return new SampleBlock("No Arrow", content); return new SampleBlock("No Arrow", content);
} }
@SuppressWarnings("SameParameterValue") @SuppressWarnings("SameParameterValue")
private MenuItem[] menuItems(int count) { private MenuItem[] createItems(int count) {
return IntStream.range(0, count) return IntStream.range(0, count)
.mapToObj(i -> new MenuItem(FAKER.babylon5().character())) .mapToObj(i -> new MenuItem(FAKER.babylon5().character()))
.toArray(MenuItem[]::new); .toArray(MenuItem[]::new);

@ -4,6 +4,7 @@ package atlantafx.sampler.page.components;
import atlantafx.base.theme.Styles; import atlantafx.base.theme.Styles;
import atlantafx.sampler.fake.SampleMenuBar; import atlantafx.sampler.fake.SampleMenuBar;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import atlantafx.sampler.util.Controls; import atlantafx.sampler.util.Controls;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@ -12,9 +13,9 @@ import javafx.scene.control.Label;
import javafx.scene.control.SeparatorMenuItem; import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination; import javafx.scene.input.KeyCodeCombination;
import javafx.scene.layout.VBox;
import org.kordamp.ikonli.feather.Feather; import org.kordamp.ikonli.feather.Feather;
import static atlantafx.sampler.util.Controls.menuItem;
import static javafx.scene.input.KeyCombination.CONTROL_DOWN; import static javafx.scene.input.KeyCombination.CONTROL_DOWN;
public class MenuPage extends AbstractPage { public class MenuPage extends AbstractPage {
@ -26,14 +27,10 @@ public class MenuPage extends AbstractPage {
public MenuPage() { public MenuPage() {
super(); super();
createView(); setUserContent(new VBox(Page.PAGE_VGAP,
} menuBarSample(),
contextMenuExample()
private void createView() { ));
userContent.getChildren().addAll(
menuBarSample().getRoot(),
contextMenuExample().getRoot()
);
} }
private SampleBlock menuBarSample() { private SampleBlock menuBarSample() {
@ -45,11 +42,9 @@ public class MenuPage extends AbstractPage {
var undoItem = Controls.menuItem("_Undo", Feather.CORNER_DOWN_LEFT, new KeyCodeCombination(KeyCode.Z, CONTROL_DOWN)); var undoItem = Controls.menuItem("_Undo", Feather.CORNER_DOWN_LEFT, new KeyCodeCombination(KeyCode.Z, CONTROL_DOWN));
undoItem.setMnemonicParsing(true); undoItem.setMnemonicParsing(true);
undoItem.setOnAction(PRINT_SOURCE);
var redoItem = Controls.menuItem("_Redo", Feather.CORNER_DOWN_RIGHT, new KeyCodeCombination(KeyCode.Y, CONTROL_DOWN)); var redoItem = Controls.menuItem("_Redo", Feather.CORNER_DOWN_RIGHT, new KeyCodeCombination(KeyCode.Y, CONTROL_DOWN));
redoItem.setMnemonicParsing(true); redoItem.setMnemonicParsing(true);
redoItem.setOnAction(PRINT_SOURCE);
contextMenu.getItems().addAll( contextMenu.getItems().addAll(
undoItem, undoItem,
@ -60,13 +55,13 @@ public class MenuPage extends AbstractPage {
Controls.menuItem("Paste", null, new KeyCodeCombination(KeyCode.V, CONTROL_DOWN)) Controls.menuItem("Paste", null, new KeyCodeCombination(KeyCode.V, CONTROL_DOWN))
); );
var sample = new Label("Right-Click Here"); var content = new Label("Right-Click Here");
sample.setAlignment(Pos.CENTER); content.setAlignment(Pos.CENTER);
sample.setMinSize(400, 80); content.setMinSize(400, 80);
sample.setMaxSize(200, 80); content.setMaxSize(400, 80);
sample.setContextMenu(contextMenu); content.setContextMenu(contextMenu);
sample.getStyleClass().add(Styles.BORDERED); content.getStyleClass().add(Styles.BORDERED);
return new SampleBlock("Context menu", sample); return new SampleBlock("Context Menu", content);
} }
} }

@ -19,6 +19,8 @@ import java.time.LocalDate;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import static atlantafx.base.theme.Styles.*; import static atlantafx.base.theme.Styles.*;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
public class OverviewPage extends AbstractPage { public class OverviewPage extends AbstractPage {
@ -26,44 +28,25 @@ public class OverviewPage extends AbstractPage {
private static final int BUTTON_WIDTH = 120; private static final int BUTTON_WIDTH = 120;
private static final int COMBO_BOX_WIDTH = 150; private static final int COMBO_BOX_WIDTH = 150;
private static final int H_GAP = 20;
private static final int V_GAP = 10;
@Override @Override
public String getName() { return NAME; } public String getName() { return NAME; }
public OverviewPage() { public OverviewPage() {
super(); super();
createView(); setUserContent(new VBox(
} PAGE_VGAP,
buttonSample(),
private void createView() { expandingHBox(iconButtonSample(), dropdownMenuSample()),
userContent.getChildren().setAll( expandingHBox(checkBoxSample(), radioButtonSample(), toggleSwitchSample()),
buttonSample().getRoot(), comboBoxSample(),
new HBox(H_GAP * 2, sliderSample(),
iconButtonSample().getRoot(), expandingHBox(textFieldSample(), spinnerSample()),
dropdownMenuSample().getRoot() textAreaSample()
), ));
new HBox(H_GAP * 2,
checkBoxSample().getRoot(),
radioButtonSample().getRoot(),
toggleSwitchSample().getRoot()
),
comboBoxSample().getRoot(),
sliderSample().getRoot(),
new HBox(H_GAP * 2,
textFieldSample().getRoot(),
spinnerSample().getRoot()
),
textAreaSample().getRoot()
);
} }
private SampleBlock buttonSample() { private SampleBlock buttonSample() {
var grid = new GridPane();
grid.setVgap(V_GAP);
grid.setHgap(H_GAP);
var basicBtn = new Button("Basic"); var basicBtn = new Button("Basic");
basicBtn.setPrefWidth(BUTTON_WIDTH); basicBtn.setPrefWidth(BUTTON_WIDTH);
@ -88,13 +71,15 @@ public class OverviewPage extends AbstractPage {
outlinedBtn.setPrefWidth(BUTTON_WIDTH); outlinedBtn.setPrefWidth(BUTTON_WIDTH);
var twoButtonGroup = new ToggleGroup(); var twoButtonGroup = new ToggleGroup();
var leftPill = toggleButton("Toggle 1", twoButtonGroup, true, LEFT_PILL); var leftPill = createToggleButton("Toggle 1", twoButtonGroup, true, LEFT_PILL);
leftPill.setPrefWidth(BUTTON_WIDTH + grid.getHgap() / 2); leftPill.setPrefWidth(BUTTON_WIDTH + BLOCK_HGAP / 2.0);
var rightPill = toggleButton("Toggle 2", twoButtonGroup, false, RIGHT_PILL); var rightPill = createToggleButton("Toggle 2", twoButtonGroup, false, RIGHT_PILL);
rightPill.setPrefWidth(BUTTON_WIDTH + grid.getHgap() / 2); rightPill.setPrefWidth(BUTTON_WIDTH + BLOCK_HGAP / 2.0);
var twoButtonBox = new HBox(leftPill, rightPill); var twoButtonBox = new HBox(leftPill, rightPill);
// ~ var grid = new GridPane();
grid.setVgap(BLOCK_VGAP);
grid.setHgap(BLOCK_HGAP);
grid.add(basicBtn, 0, 0); grid.add(basicBtn, 0, 0);
grid.add(flatBtn, 1, 0); grid.add(flatBtn, 1, 0);
grid.add(successBtn, 2, 0); grid.add(successBtn, 2, 0);
@ -108,10 +93,6 @@ public class OverviewPage extends AbstractPage {
} }
private SampleBlock iconButtonSample() { private SampleBlock iconButtonSample() {
var grid = new GridPane();
grid.setVgap(V_GAP);
grid.setHgap(H_GAP);
var basicBtn = new Button("", new FontIcon(Feather.MORE_HORIZONTAL)); var basicBtn = new Button("", new FontIcon(Feather.MORE_HORIZONTAL));
basicBtn.getStyleClass().addAll(BUTTON_ICON); basicBtn.getStyleClass().addAll(BUTTON_ICON);
@ -129,7 +110,9 @@ public class OverviewPage extends AbstractPage {
flatBtn.getStyleClass().addAll(BUTTON_CIRCLE, FLAT); flatBtn.getStyleClass().addAll(BUTTON_CIRCLE, FLAT);
flatBtn.setShape(new Circle(50)); flatBtn.setShape(new Circle(50));
// ~ var grid = new GridPane();
grid.setVgap(BLOCK_VGAP);
grid.setHgap(BLOCK_HGAP);
grid.add(basicBtn, 0, 0); grid.add(basicBtn, 0, 0);
grid.add(successBtn, 1, 0); grid.add(successBtn, 1, 0);
grid.add(dangerBtn, 2, 0); grid.add(dangerBtn, 2, 0);
@ -140,46 +123,42 @@ public class OverviewPage extends AbstractPage {
} }
private SampleBlock dropdownMenuSample() { private SampleBlock dropdownMenuSample() {
var grid = new GridPane(); var basicMenuBtn = new MenuButton("Menu Button");
grid.setVgap(V_GAP); basicMenuBtn.getItems().setAll(createMenuItems());
grid.setHgap(H_GAP); basicMenuBtn.setPrefWidth(COMBO_BOX_WIDTH);
var basicIconBtn = new MenuButton(); var basicIconBtn = new MenuButton();
basicIconBtn.setGraphic(new FontIcon(Feather.MORE_HORIZONTAL)); basicIconBtn.setGraphic(new FontIcon(Feather.MORE_HORIZONTAL));
basicIconBtn.getItems().setAll(menuItems(5)); basicIconBtn.getItems().setAll(createMenuItems());
basicIconBtn.getStyleClass().addAll(BUTTON_ICON); basicIconBtn.getStyleClass().addAll(BUTTON_ICON);
var accentIconBtn = new MenuButton(); var accentIconBtn = new MenuButton();
accentIconBtn.setGraphic(new FontIcon(Feather.MENU)); accentIconBtn.setGraphic(new FontIcon(Feather.MENU));
accentIconBtn.getItems().setAll(menuItems(5)); accentIconBtn.getItems().setAll(createMenuItems());
accentIconBtn.getStyleClass().addAll(BUTTON_ICON, ACCENT); accentIconBtn.getStyleClass().addAll(BUTTON_ICON, ACCENT);
var basicMenuBtn = new MenuButton("Menu Button"); var basicSplitBtn = new SplitMenuButton(createMenuItems());
basicMenuBtn.getItems().setAll(menuItems(5));
basicMenuBtn.setPrefWidth(COMBO_BOX_WIDTH);
var basicSplitBtn = new SplitMenuButton(menuItems(5));
basicSplitBtn.setText("Split Menu Button"); basicSplitBtn.setText("Split Menu Button");
var outlinedSplitBtn = new SplitMenuButton(menuItems(5)); var outlinedSplitBtn = new SplitMenuButton(createMenuItems());
outlinedSplitBtn.setGraphic(new FontIcon(Feather.TRASH)); outlinedSplitBtn.setGraphic(new FontIcon(Feather.TRASH));
outlinedSplitBtn.setText("Danger"); outlinedSplitBtn.setText("Danger");
outlinedSplitBtn.getStyleClass().addAll(BUTTON_OUTLINED, DANGER); outlinedSplitBtn.getStyleClass().addAll(BUTTON_OUTLINED, DANGER);
outlinedSplitBtn.setPrefWidth(COMBO_BOX_WIDTH); outlinedSplitBtn.setPrefWidth(COMBO_BOX_WIDTH);
// ~ var grid = new GridPane();
grid.add(basicIconBtn, 0, 0); grid.setVgap(BLOCK_VGAP);
grid.add(accentIconBtn, 1, 0); grid.setHgap(BLOCK_HGAP);
grid.add(basicMenuBtn, 2, 0); grid.add(basicMenuBtn, 0, 0);
grid.add(basicSplitBtn, 0, 1, 2, 1); grid.add(basicIconBtn, 1, 0);
grid.add(outlinedSplitBtn, 2, 1); grid.add(accentIconBtn, 2, 0);
grid.add(basicSplitBtn, 1, 1, 2, 1);
grid.add(outlinedSplitBtn, 0, 1);
return new SampleBlock("Dropdown Menus", grid); return new SampleBlock("Dropdown Menus", grid);
} }
private SampleBlock checkBoxSample() { private SampleBlock checkBoxSample() {
var box = new VBox(V_GAP);
var opt1 = new CheckBox("Option 1"); var opt1 = new CheckBox("Option 1");
var opt2 = new CheckBox("Option 2"); var opt2 = new CheckBox("Option 2");
@ -189,13 +168,11 @@ public class OverviewPage extends AbstractPage {
opt3.setAllowIndeterminate(true); opt3.setAllowIndeterminate(true);
opt3.setIndeterminate(true); opt3.setIndeterminate(true);
box.getChildren().setAll(opt1, opt2, opt3); var container = new VBox(BLOCK_VGAP, opt1, opt2, opt3);
return new SampleBlock("Check Boxes", box); return new SampleBlock("Check Boxes", container);
} }
private SampleBlock radioButtonSample() { private SampleBlock radioButtonSample() {
var box = new VBox(V_GAP);
var group = new ToggleGroup(); var group = new ToggleGroup();
var opt1 = new RadioButton("Option 1"); var opt1 = new RadioButton("Option 1");
@ -208,25 +185,21 @@ public class OverviewPage extends AbstractPage {
var opt3 = new RadioButton("Option 3"); var opt3 = new RadioButton("Option 3");
opt3.setToggleGroup(group); opt3.setToggleGroup(group);
box.getChildren().setAll(opt1, opt2, opt3); var container = new VBox(BLOCK_VGAP, opt1, opt2, opt3);
return new SampleBlock("Radio Buttons", box); return new SampleBlock("Radio Buttons", container);
} }
private SampleBlock toggleSwitchSample() { private SampleBlock toggleSwitchSample() {
var box = new VBox(V_GAP);
var switch1 = new ToggleSwitch(); var switch1 = new ToggleSwitch();
var switch2 = new ToggleSwitch(); var switch2 = new ToggleSwitch();
switch2.setSelected(true); switch2.setSelected(true);
box.getChildren().setAll(switch1, switch2); var container = new VBox(BLOCK_VGAP, switch1, switch2);
return new SampleBlock("Switches", box); return new SampleBlock("Switches", container);
} }
private SampleBlock comboBoxSample() { private SampleBlock comboBoxSample() {
var box = new HBox(H_GAP);
var comboBox = new ComboBox<String>(); var comboBox = new ComboBox<String>();
comboBox.getItems().setAll("Option 1", "Option 2", "Option 3"); comboBox.getItems().setAll("Option 1", "Option 2", "Option 3");
comboBox.getStyleClass().add(Tweaks.ALT_ICON); comboBox.getStyleClass().add(Tweaks.ALT_ICON);
@ -246,13 +219,11 @@ public class OverviewPage extends AbstractPage {
colorPicker.setPrefWidth(COMBO_BOX_WIDTH); colorPicker.setPrefWidth(COMBO_BOX_WIDTH);
colorPicker.setValue(Color.ORANGE); colorPicker.setValue(Color.ORANGE);
box.getChildren().setAll(comboBox, choiceBox, datePicker, colorPicker); var container = new HBox(BLOCK_HGAP, comboBox, choiceBox, datePicker, colorPicker);
return new SampleBlock("Combo Boxes", box); return new SampleBlock("Combo Boxes", container);
} }
private SampleBlock sliderSample() { private SampleBlock sliderSample() {
var box = new HBox(H_GAP);
var slider = new Slider(1, 5, 3); var slider = new Slider(1, 5, 3);
slider.setPrefWidth(BUTTON_WIDTH * 2); slider.setPrefWidth(BUTTON_WIDTH * 2);
@ -265,38 +236,34 @@ public class OverviewPage extends AbstractPage {
tickSlider.setSnapToTicks(true); tickSlider.setSnapToTicks(true);
tickSlider.setPrefWidth(BUTTON_WIDTH * 2); tickSlider.setPrefWidth(BUTTON_WIDTH * 2);
box.getChildren().setAll(slider, tickSlider); var container = new HBox(BLOCK_HGAP, slider, tickSlider);
return new SampleBlock("Sliders", box); return new SampleBlock("Sliders", container);
} }
private SampleBlock textFieldSample() { private SampleBlock textFieldSample() {
var box = new HBox(H_GAP);
var textField = new TextField("Text"); var textField = new TextField("Text");
textField.setPrefWidth(BUTTON_WIDTH); textField.setPrefWidth(COMBO_BOX_WIDTH);
var passwordField = new PasswordField(); var passwordField = new PasswordField();
passwordField.setText(FAKER.internet().password()); passwordField.setText(FAKER.internet().password());
passwordField.setPrefWidth(BUTTON_WIDTH); passwordField.setPrefWidth(COMBO_BOX_WIDTH);
box.getChildren().setAll(textField, passwordField); var container = new HBox(BLOCK_HGAP, textField, passwordField);
return new SampleBlock("Text Fields", box); return new SampleBlock("Text Fields", container);
} }
private SampleBlock spinnerSample() { private SampleBlock spinnerSample() {
var box = new HBox(H_GAP);
var spinner1 = new Spinner<Integer>(1, 10, 1); var spinner1 = new Spinner<Integer>(1, 10, 1);
IntegerStringConverter.createFor(spinner1); IntegerStringConverter.createFor(spinner1);
spinner1.setPrefWidth(BUTTON_WIDTH); spinner1.setPrefWidth(COMBO_BOX_WIDTH);
var spinner2 = new Spinner<Integer>(1, 10, 1); var spinner2 = new Spinner<Integer>(1, 10, 1);
IntegerStringConverter.createFor(spinner2); IntegerStringConverter.createFor(spinner2);
spinner2.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL); spinner2.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
spinner2.setPrefWidth(BUTTON_WIDTH); spinner2.setPrefWidth(COMBO_BOX_WIDTH);
box.getChildren().setAll(spinner1, spinner2); var container = new HBox(BLOCK_HGAP, spinner1, spinner2);
return new SampleBlock("Spinners", box); return new SampleBlock("Spinners", container);
} }
private SampleBlock textAreaSample() { private SampleBlock textAreaSample() {
@ -308,7 +275,7 @@ public class OverviewPage extends AbstractPage {
return new SampleBlock("Text Area", textArea); return new SampleBlock("Text Area", textArea);
} }
private ToggleButton toggleButton(String text, private ToggleButton createToggleButton(String text,
ToggleGroup group, ToggleGroup group,
boolean selected, boolean selected,
String... styleClasses) { String... styleClasses) {
@ -320,9 +287,8 @@ public class OverviewPage extends AbstractPage {
return toggleButton; return toggleButton;
} }
@SuppressWarnings("SameParameterValue") private MenuItem[] createMenuItems() {
private MenuItem[] menuItems(int count) { return IntStream.range(0, 5)
return IntStream.range(0, count)
.mapToObj(i -> new MenuItem(FAKER.babylon5().character())) .mapToObj(i -> new MenuItem(FAKER.babylon5().character()))
.toArray(MenuItem[]::new); .toArray(MenuItem[]::new);
} }

@ -1,10 +1,10 @@
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
package atlantafx.sampler.page.components; package atlantafx.sampler.page.components;
import atlantafx.base.theme.Styles;
import atlantafx.base.controls.ToggleSwitch; import atlantafx.base.controls.ToggleSwitch;
import atlantafx.base.controls.Spacer; import atlantafx.base.theme.Styles;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.SampleBlock;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.Pagination; import javafx.scene.control.Pagination;
@ -12,9 +12,11 @@ import javafx.scene.control.Separator;
import javafx.scene.control.Spinner; import javafx.scene.control.Spinner;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
public class PaginationPage extends AbstractPage { public class PaginationPage extends AbstractPage {
public static final String NAME = "Pagination"; public static final String NAME = "Pagination";
@ -25,14 +27,12 @@ public class PaginationPage extends AbstractPage {
public PaginationPage() { public PaginationPage() {
super(); super();
createView(); setUserContent(new VBox(
new SampleBlock("Playground", createPlayground())
));
} }
private void createView() { private VBox createPlayground() {
var playground = new VBox(10);
playground.setMinHeight(100);
playground.setAlignment(Pos.CENTER);
var pagination = new Pagination(); var pagination = new Pagination();
pagination.setCurrentPageIndex(1); pagination.setCurrentPageIndex(1);
pagination.setPageFactory(index -> { pagination.setPageFactory(index -> {
@ -76,13 +76,14 @@ public class PaginationPage extends AbstractPage {
pagination.disableProperty().bind(disableToggle.selectedProperty()); pagination.disableProperty().bind(disableToggle.selectedProperty());
var controls = new GridPane(); var controls = new GridPane();
controls.setHgap(20); controls.setHgap(BLOCK_HGAP);
controls.setVgap(10); controls.setVgap(BLOCK_VGAP);
controls.setAlignment(Pos.CENTER);
controls.add(new Label("Page count:"), 0, 0); controls.add(new Label("Page count"), 0, 0);
controls.add(pageCountSpinner, 1, 0); controls.add(pageCountSpinner, 1, 0);
controls.add(new Label("Visible count:"), 0, 1); controls.add(new Label("Visible count"), 0, 1);
controls.add(visibleCountSpinner, 1, 1); controls.add(visibleCountSpinner, 1, 1);
controls.add(new Label("Bullet style"), 3, 0); controls.add(new Label("Bullet style"), 3, 0);
@ -99,15 +100,9 @@ public class PaginationPage extends AbstractPage {
// ~ // ~
var separator = new Separator(); var playground = new VBox(BLOCK_VGAP, pagination, new Separator(), controls);
separator.getStyleClass().addAll(Styles.LARGE); playground.setMinHeight(100);
playground.getChildren().setAll( return playground;
pagination,
separator,
new HBox(new Spacer(), controls, new Spacer())
);
userContent.getChildren().setAll(playground);
} }
} }

@ -5,16 +5,22 @@ import atlantafx.base.controls.InlineDatePicker;
import atlantafx.base.controls.Popover; import atlantafx.base.controls.Popover;
import atlantafx.base.controls.Popover.ArrowLocation; import atlantafx.base.controls.Popover.ArrowLocation;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import atlantafx.sampler.theme.CSSFragment;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Hyperlink; import javafx.scene.control.Hyperlink;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text; import javafx.scene.text.Text;
import javafx.scene.text.TextFlow; import javafx.scene.text.TextFlow;
import java.time.LocalDate; import java.time.LocalDate;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
public class PopoverPage extends AbstractPage { public class PopoverPage extends AbstractPage {
public static final String NAME = "Popover"; public static final String NAME = "Popover";
@ -24,66 +30,73 @@ public class PopoverPage extends AbstractPage {
public PopoverPage() { public PopoverPage() {
super(); super();
createView(); setUserContent(new VBox(Page.PAGE_VGAP,
new HBox(PAGE_HGAP, textSample(), datePickerSample()),
positionSample()
));
} }
private void createView() { private SampleBlock textSample() {
userContent.getChildren().setAll(basicSamples(), positionSamples().getRoot()); var popover = new Popover(createTextFlow(30));
popover.setTitle("Lorem Ipsum");
popover.setHeaderAlwaysVisible(true);
popover.setDetachable(true);
var link = createHyperlink("Click me");
link.setOnAction(e -> popover.show(link));
return new SampleBlock("Text", link);
} }
private HBox basicSamples() { private SampleBlock datePickerSample() {
var textPopover = new Popover(textFlow(30));
textPopover.setTitle("Lorem Ipsum");
textPopover.setHeaderAlwaysVisible(true);
textPopover.setDetachable(true);
var textLink = hyperlink("Click me");
textLink.setOnAction(e -> textPopover.show(textLink));
var textBlock = new SampleBlock("Basic", textLink);
var datePicker = new InlineDatePicker(); var datePicker = new InlineDatePicker();
datePicker.setValue(LocalDate.now()); datePicker.setValue(LocalDate.now());
var datePopover = new Popover(datePicker); var popover = new Popover(datePicker);
textPopover.setHeaderAlwaysVisible(false); popover.setHeaderAlwaysVisible(false);
datePopover.setDetachable(true); popover.setDetachable(true);
var dateLink = hyperlink("Click me");
dateLink.setOnAction(e -> datePopover.show(dateLink));
var dateBlock = new SampleBlock("Date picker", dateLink);
var box = new HBox(20, var link = createHyperlink("Click me");
textBlock.getRoot(), link.setOnAction(e -> popover.show(link));
dateBlock.getRoot() new CSSFragment("""
); .popover .date-picker-popup {
box.setAlignment(Pos.CENTER_LEFT); -color-date-border: transparent;
-color-date-bg: transparent;
-color-date-day-bg: transparent;
-color-date-month-year-bg: transparent;
-color-date-day-bg-hover: -color-bg-subtle;
}
"""
).addTo(link);
return box; return new SampleBlock("Date Picker", link);
} }
private SampleBlock positionSamples() { private SampleBlock positionSample() {
var grid = new GridPane(); var grid = new GridPane();
grid.setHgap(20); grid.setHgap(BLOCK_HGAP);
grid.setVgap(20); grid.setVgap(BLOCK_VGAP);
grid.add(arrowPositionBlock(ArrowLocation.TOP_LEFT), 0, 0); grid.add(createArrowPositionBlock(ArrowLocation.TOP_LEFT), 0, 0);
grid.add(arrowPositionBlock(ArrowLocation.TOP_CENTER), 0, 1); grid.add(createArrowPositionBlock(ArrowLocation.TOP_CENTER), 0, 1);
grid.add(arrowPositionBlock(ArrowLocation.TOP_RIGHT), 0, 2); grid.add(createArrowPositionBlock(ArrowLocation.TOP_RIGHT), 0, 2);
grid.add(arrowPositionBlock(ArrowLocation.RIGHT_TOP), 1, 0); grid.add(createArrowPositionBlock(ArrowLocation.RIGHT_TOP), 1, 0);
grid.add(arrowPositionBlock(ArrowLocation.RIGHT_CENTER), 1, 1); grid.add(createArrowPositionBlock(ArrowLocation.RIGHT_CENTER), 1, 1);
grid.add(arrowPositionBlock(ArrowLocation.RIGHT_BOTTOM), 1, 2); grid.add(createArrowPositionBlock(ArrowLocation.RIGHT_BOTTOM), 1, 2);
grid.add(arrowPositionBlock(ArrowLocation.BOTTOM_LEFT), 2, 0); grid.add(createArrowPositionBlock(ArrowLocation.BOTTOM_LEFT), 2, 0);
grid.add(arrowPositionBlock(ArrowLocation.BOTTOM_CENTER), 2, 1); grid.add(createArrowPositionBlock(ArrowLocation.BOTTOM_CENTER), 2, 1);
grid.add(arrowPositionBlock(ArrowLocation.BOTTOM_RIGHT), 2, 2); grid.add(createArrowPositionBlock(ArrowLocation.BOTTOM_RIGHT), 2, 2);
grid.add(arrowPositionBlock(ArrowLocation.LEFT_TOP), 3, 0); grid.add(createArrowPositionBlock(ArrowLocation.LEFT_TOP), 3, 0);
grid.add(arrowPositionBlock(ArrowLocation.LEFT_CENTER), 3, 1); grid.add(createArrowPositionBlock(ArrowLocation.LEFT_CENTER), 3, 1);
grid.add(arrowPositionBlock(ArrowLocation.LEFT_BOTTOM), 3, 2); grid.add(createArrowPositionBlock(ArrowLocation.LEFT_BOTTOM), 3, 2);
return new SampleBlock("Position", grid); return new SampleBlock("Position", grid);
} }
private Hyperlink hyperlink(String text) { private Hyperlink createHyperlink(String text) {
Hyperlink hyperlink = new Hyperlink(text); Hyperlink hyperlink = new Hyperlink(text);
hyperlink.setMinWidth(50); hyperlink.setMinWidth(50);
hyperlink.setMinHeight(50); hyperlink.setMinHeight(50);
@ -91,18 +104,20 @@ public class PopoverPage extends AbstractPage {
return hyperlink; return hyperlink;
} }
private TextFlow textFlow(int wordCount) { private TextFlow createTextFlow(int wordCount) {
var textFlow = new TextFlow(new Text(FAKER.lorem().sentence(wordCount))); var textFlow = new TextFlow(new Text(FAKER.lorem().sentence(wordCount)));
textFlow.setPrefWidth(300); textFlow.setPrefWidth(300);
return textFlow; return textFlow;
} }
private Hyperlink arrowPositionBlock(ArrowLocation arrowLocation) { private Hyperlink createArrowPositionBlock(ArrowLocation arrowLocation) {
var link = hyperlink(String.valueOf(arrowLocation)); var popover = new Popover(createTextFlow(50));
var popover = new Popover(textFlow(50));
popover.setHeaderAlwaysVisible(false); popover.setHeaderAlwaysVisible(false);
popover.setArrowLocation(arrowLocation); popover.setArrowLocation(arrowLocation);
var link = createHyperlink(String.valueOf(arrowLocation));
link.setOnAction(e -> popover.show(link)); link.setOnAction(e -> popover.show(link));
return link; return link;
} }
} }

@ -1,8 +1,8 @@
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
package atlantafx.sampler.page.components; package atlantafx.sampler.page.components;
import atlantafx.base.theme.Styles;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import atlantafx.sampler.theme.CSSFragment; import atlantafx.sampler.theme.CSSFragment;
import javafx.concurrent.Task; import javafx.concurrent.Task;
@ -18,9 +18,12 @@ import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.scene.text.Text; import javafx.scene.text.Text;
// Indeterminate (animated) progress bar and also progress indicator are very expensive. import static atlantafx.base.theme.Styles.*;
// It consumes single CPU core and a lot of memory. import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
// #javafx-bug import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
// #javafx-bug Indeterminate (animated) progress bar and also progress indicator
// are VERY resource expensive. It consumes a single CPU core and a lot of memory.
public class ProgressPage extends AbstractPage { public class ProgressPage extends AbstractPage {
public static final String NAME = "Progress"; public static final String NAME = "Progress";
@ -30,50 +33,44 @@ public class ProgressPage extends AbstractPage {
public ProgressPage() { public ProgressPage() {
super(); super();
createView(); setUserContent(new VBox(Page.PAGE_VGAP,
expandingHBox(basicBarSample(), basicIndicatorSample()),
expandingHBox(barSizeSample(), colorChangeSample())
));
} }
private void createView() { private SampleBlock basicBarSample() {
userContent.getChildren().addAll( var flowPane = new FlowPane(
basicBarSamples().getRoot(), BLOCK_HGAP, BLOCK_VGAP,
basicIndicatorSamples().getRoot(), createBar(0, false),
barSizeSamples().getRoot(), createBar(0.5, false),
colorChangeSample().getRoot() createBar(1, false),
createBar(0.5, true)
); );
}
private SampleBlock basicBarSamples() {
var flowPane = new FlowPane(20, 20);
flowPane.setAlignment(Pos.CENTER_LEFT); flowPane.setAlignment(Pos.CENTER_LEFT);
flowPane.getChildren().addAll(
progressBar(0, false),
progressBar(0.5, false),
progressBar(1, false),
progressBar(0.5, true)
);
return new SampleBlock("Progress Bar", flowPane); return new SampleBlock("Progress Bar", flowPane);
} }
private SampleBlock basicIndicatorSamples() { private SampleBlock basicIndicatorSample() {
var flowPane = new FlowPane(20, 20); var flowPane = new FlowPane(
flowPane.getChildren().addAll( BLOCK_HGAP, BLOCK_VGAP,
progressIndicator(0, false), createIndicator(0, false),
progressIndicator(0.5, false), createIndicator(0.5, false),
progressIndicator(1, false), createIndicator(1, false),
progressIndicator(0.5, true) createIndicator(0.5, true)
); );
flowPane.setAlignment(Pos.TOP_LEFT); flowPane.setAlignment(Pos.TOP_LEFT);
return new SampleBlock("Progress Indicator", flowPane); return new SampleBlock("Progress Indicator", flowPane);
} }
private SampleBlock barSizeSamples() { private SampleBlock barSizeSample() {
var container = new VBox( var container = new VBox(
10, BLOCK_VGAP,
new HBox(20, progressBar(0.5, false, Styles.SMALL), new Text("small")), new HBox(20, createBar(0.5, false, SMALL), new Text("small")),
new HBox(20, progressBar(0.5, false, Styles.MEDIUM), new Text("medium")), new HBox(20, createBar(0.5, false, MEDIUM), new Text("medium")),
new HBox(20, progressBar(0.5, false, Styles.LARGE), new Text("large")) new HBox(20, createBar(0.5, false, LARGE), new Text("large"))
); );
container.getChildren().forEach(c -> ((HBox) c).setAlignment(Pos.CENTER_LEFT)); container.getChildren().forEach(c -> ((HBox) c).setAlignment(Pos.CENTER_LEFT));
@ -83,10 +80,10 @@ public class ProgressPage extends AbstractPage {
private SampleBlock colorChangeSample() { private SampleBlock colorChangeSample() {
var stateSuccess = PseudoClass.getPseudoClass("state-success"); var stateSuccess = PseudoClass.getPseudoClass("state-success");
var stateDanger = PseudoClass.getPseudoClass("state-danger"); var stateDanger = PseudoClass.getPseudoClass("state-danger");
var width = 400; var width = 300;
var bar = new ProgressBar(0); var bar = new ProgressBar(0);
bar.getStyleClass().add(Styles.LARGE); bar.getStyleClass().add(LARGE);
bar.setPrefWidth(width); bar.setPrefWidth(width);
bar.setMaxWidth(width); bar.setMaxWidth(width);
@ -102,7 +99,7 @@ public class ProgressPage extends AbstractPage {
// ~ // ~
var content = new VBox(10); var content = new VBox(BLOCK_VGAP);
content.getChildren().setAll(barStack, runBtn); content.getChildren().setAll(barStack, runBtn);
content.setAlignment(Pos.CENTER_LEFT); content.setAlignment(Pos.CENTER_LEFT);
@ -127,7 +124,8 @@ public class ProgressPage extends AbstractPage {
.example:state-danger .label { .example:state-danger .label {
-fx-text-fill: -color-fg-emphasis; -fx-text-fill: -color-fg-emphasis;
} }
""").addTo(content); """
).addTo(content);
runBtn.setOnAction(e1 -> { runBtn.setOnAction(e1 -> {
var task = new Task<Void>() { var task = new Task<Void>() {
@ -162,17 +160,17 @@ public class ProgressPage extends AbstractPage {
new Thread(task).start(); new Thread(task).start();
}); });
return new SampleBlock("Live color change", content); return new SampleBlock("Dynamic Color Change", content);
} }
private ProgressIndicator progressBar(double progress, boolean disabled, String... styleClasses) { private ProgressIndicator createBar(double progress, boolean disabled, String... styleClasses) {
var bar = new ProgressBar(progress); var bar = new ProgressBar(progress);
bar.getStyleClass().addAll(styleClasses); bar.getStyleClass().addAll(styleClasses);
bar.setDisable(disabled); bar.setDisable(disabled);
return bar; return bar;
} }
private ProgressIndicator progressIndicator(double progress, boolean disabled) { private ProgressIndicator createIndicator(double progress, boolean disabled) {
var indicator = new ProgressIndicator(progress); var indicator = new ProgressIndicator(progress);
indicator.setMinSize(50, 50); indicator.setMinSize(50, 50);
indicator.setMaxSize(50, 50); indicator.setMaxSize(50, 50);

@ -2,12 +2,15 @@
package atlantafx.sampler.page.components; package atlantafx.sampler.page.components;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import javafx.scene.control.RadioButton; import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup; import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.HBox; import javafx.scene.layout.FlowPane;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
public class RadioButtonPage extends AbstractPage { public class RadioButtonPage extends AbstractPage {
public static final String NAME = "RadioButton"; public static final String NAME = "RadioButton";
@ -17,36 +20,30 @@ public class RadioButtonPage extends AbstractPage {
public RadioButtonPage() { public RadioButtonPage() {
super(); super();
createView(); setUserContent(new FlowPane(
Page.PAGE_HGAP, Page.PAGE_VGAP,
basicSample(),
groupSample(),
disabledSample()
));
} }
private void createView() { private SampleBlock basicSample() {
userContent.getChildren().addAll( var radio1 = new RadioButton("_Check Me");
basicSamples(), radio1.setMnemonicParsing(true);
groupSamples().getRoot()
); var radio2 = new RadioButton("Check Me");
return new SampleBlock("Basic", new VBox(BLOCK_VGAP, radio1, radio2));
} }
private HBox basicSamples() { private SampleBlock disabledSample() {
var basicRadio = new RadioButton("_Check Me"); var radio = new RadioButton("Check Me");
basicRadio.setMnemonicParsing(true); radio.setDisable(true);
basicRadio.setOnAction(PRINT_SOURCE); return new SampleBlock("Disabled", radio);
var basicBlock = new SampleBlock("Basic", basicRadio);
var disabledRadio = new RadioButton("Check Me");
disabledRadio.setDisable(true);
var disabledBlock = new SampleBlock("Disabled", disabledRadio);
var root = new HBox(20);
root.getChildren().addAll(
basicBlock.getRoot(),
disabledBlock.getRoot()
);
return root;
} }
private SampleBlock groupSamples() { private SampleBlock groupSample() {
var group = new ToggleGroup(); var group = new ToggleGroup();
var musicRadio = new RadioButton("Music"); var musicRadio = new RadioButton("Music");

@ -2,84 +2,86 @@
package atlantafx.sampler.page.components; package atlantafx.sampler.page.components;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import javafx.scene.control.ScrollPane; import javafx.scene.control.ScrollPane;
import javafx.scene.layout.FlowPane; import javafx.scene.layout.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
public class ScrollPanePage extends AbstractPage { public class ScrollPanePage extends AbstractPage {
public static final String NAME = "ScrollPane"; public static final String NAME = "ScrollPane";
private static final int SPACING = 1;
@Override @Override
public String getName() { return NAME; } public String getName() { return NAME; }
public ScrollPanePage() { public ScrollPanePage() {
super(); super();
createView(); setUserContent(new FlowPane(
} Page.PAGE_VGAP, Page.PAGE_HGAP,
horizontalScrollSample(),
private void createView() { verticalScrollSample(),
userContent.getChildren().setAll(new FlowPane(20, 20, gridScrollSample(),
hScrollBlock().getRoot(), disabledSample()
vScrollBlock().getRoot(),
gridScrollBlock().getRoot(),
disabledBlock().getRoot()
)); ));
} }
private SampleBlock hScrollBlock() { private SampleBlock horizontalScrollSample() {
var scrollPane = new ScrollPane(); var scrollPane = new ScrollPane();
scrollPane.setMaxHeight(100); scrollPane.setMaxHeight(100);
scrollPane.setMaxWidth(300); scrollPane.setMaxWidth(300);
scrollPane.setContent(new HBox(2, scrollPane.setContent(new HBox(SPACING,
new Rectangle(200, 100, Color.GREEN), createRegion(200, 100, "-color-success-emphasis"),
new Rectangle(200, 100, Color.RED) createRegion(200, 100, "-color-danger-emphasis")
)); ));
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
return new SampleBlock("Horizontal scrolling", scrollPane); return new SampleBlock("Horizontal Scrolling", scrollPane);
} }
private SampleBlock vScrollBlock() { private SampleBlock verticalScrollSample() {
var scrollPane = new ScrollPane(); var scrollPane = new ScrollPane();
scrollPane.setMaxHeight(100); scrollPane.setMaxHeight(100);
scrollPane.setMaxWidth(300); scrollPane.setMaxWidth(300);
scrollPane.setContent(new VBox(2, scrollPane.setContent(new VBox(SPACING,
new Rectangle(300, 75, Color.GREEN), createRegion(300, 75, "-color-success-emphasis"),
new Rectangle(300, 75, Color.RED) createRegion(300, 75, "-color-danger-emphasis")
)); ));
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
return new SampleBlock("Vertical scrolling", scrollPane); return new SampleBlock("Vertical Scrolling", scrollPane);
} }
private SampleBlock gridScrollBlock() { private SampleBlock gridScrollSample() {
var grid = new GridPane(); var grid = new GridPane();
grid.add(new Rectangle(200, 75, Color.GREEN), 0, 0); grid.add(createRegion(200, 75, "-color-success-emphasis"), 0, 0);
grid.add(new Rectangle(200, 75, Color.RED), 1, 0); grid.add(createRegion(200, 75, "-color-danger-emphasis"), 1, 0);
grid.add(new Rectangle(200, 75, Color.RED), 0, 1); grid.add(createRegion(200, 75, "-color-danger-emphasis"), 0, 1);
grid.add(new Rectangle(200, 75, Color.GREEN), 1, 1); grid.add(createRegion(200, 75, "-color-success-emphasis"), 1, 1);
grid.setHgap(2); grid.setHgap(SPACING);
grid.setVgap(2); grid.setVgap(SPACING);
var gridScroll = new ScrollPane(); var gridScroll = new ScrollPane();
gridScroll.setMaxHeight(100); gridScroll.setMaxHeight(100);
gridScroll.setMaxWidth(300); gridScroll.setMaxWidth(300);
gridScroll.setContent(grid); gridScroll.setContent(grid);
return new SampleBlock("Horizontal & vertical scrolling", gridScroll); return new SampleBlock("Scrolling", gridScroll);
} }
private SampleBlock disabledBlock() { private SampleBlock disabledSample() {
var block = gridScrollBlock(); var block = gridScrollSample();
block.setText("Disabled"); block.setTitle("Disabled");
block.getContent().setDisable(true); block.getContent().setDisable(true);
return block; return block;
} }
private Region createRegion(int width, int height, String bg) {
var r = new Region();
r.setMinSize(width, height);
r.setPrefSize(width, height);
r.setMaxSize(width, height);
r.setStyle("-fx-background-color:" + bg + ";");
return r;
}
} }

@ -3,6 +3,7 @@ package atlantafx.sampler.page.components;
import atlantafx.base.theme.Styles; import atlantafx.base.theme.Styles;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import javafx.geometry.Orientation; import javafx.geometry.Orientation;
import javafx.scene.control.Label; import javafx.scene.control.Label;
@ -16,89 +17,89 @@ import static javafx.geometry.Pos.CENTER;
public final class SeparatorPage extends AbstractPage { public final class SeparatorPage extends AbstractPage {
public static final String NAME = "Separator"; public static final String NAME = "Separator";
private static final int BRICK_SIZE = 100; private static final int SPACING = 50;
private static final int PANE_SIZE = 100;
@Override @Override
public String getName() { return NAME; } public String getName() { return NAME; }
public SeparatorPage() { public SeparatorPage() {
super(); super();
createView(); setUserContent(new FlowPane(
Page.PAGE_HGAP, Page.PAGE_VGAP,
orientationSample(),
sizeSample()
));
} }
private void createView() { private SampleBlock orientationSample() {
userContent.getChildren().setAll( var hBox = new HBox(
orientationSamples(), createPane("Left", VERTICAL),
sizeSamples() new Separator(VERTICAL),
createPane("Right", VERTICAL)
); );
}
private FlowPane orientationSamples() {
var hBox = new HBox(brick("Left", VERTICAL), new Separator(VERTICAL), brick("Right", VERTICAL));
hBox.setAlignment(CENTER); hBox.setAlignment(CENTER);
var hBlock = new SampleBlock("Vertical", hBox);
var vBox = new VBox(brick("Top", HORIZONTAL), new Separator(HORIZONTAL), brick("Bottom", HORIZONTAL)); var vBox = new VBox(
vBox.setAlignment(CENTER); createPane("Top", HORIZONTAL),
var vBlock = new SampleBlock("Horizontal", vBox); new Separator(HORIZONTAL),
createPane("Bottom", HORIZONTAL)
var root = new FlowPane(20, 20);
root.getChildren().setAll(
hBlock.getRoot(),
vBlock.getRoot()
); );
vBox.setAlignment(CENTER);
return root; return new SampleBlock("Orientation", new HBox(SPACING, hBox, vBox));
} }
private FlowPane sizeSamples() { private SampleBlock sizeSample() {
var smallSep = new Separator(VERTICAL); var smallSep = new Separator(VERTICAL);
smallSep.getStyleClass().add(Styles.SMALL); smallSep.getStyleClass().add(Styles.SMALL);
var smallBox = new HBox(brick("Left", VERTICAL), smallSep, brick("Right", VERTICAL)); var smallBox = new HBox(
createPane("Left", VERTICAL),
smallSep,
createPane("Right", VERTICAL)
);
smallBox.setAlignment(CENTER); smallBox.setAlignment(CENTER);
var smallBlock = new SampleBlock("Small", smallBox);
var mediumSep = new Separator(VERTICAL); var mediumSep = new Separator(VERTICAL);
mediumSep.getStyleClass().add(Styles.MEDIUM); mediumSep.getStyleClass().add(Styles.MEDIUM);
var mediumBox = new HBox(brick("Left", VERTICAL), mediumSep, brick("Right", VERTICAL)); var mediumBox = new HBox(
createPane("Left", VERTICAL),
mediumSep,
createPane("Right", VERTICAL)
);
mediumBox.setAlignment(CENTER); mediumBox.setAlignment(CENTER);
var mediumBlock = new SampleBlock("Medium", mediumBox);
var largeSep = new Separator(VERTICAL); var largeSep = new Separator(VERTICAL);
largeSep.getStyleClass().add(Styles.LARGE); largeSep.getStyleClass().add(Styles.LARGE);
var largeBox = new HBox(brick("Left", VERTICAL), largeSep, brick("Right", VERTICAL)); var largeBox = new HBox(
largeBox.setAlignment(CENTER); createPane("Left", VERTICAL),
var largeBlock = new SampleBlock("Large", largeBox); largeSep,
createPane("Right", VERTICAL)
var root = new FlowPane(20, 20);
root.getChildren().setAll(
smallBlock.getRoot(),
mediumBlock.getRoot(),
largeBlock.getRoot()
); );
largeBox.setAlignment(CENTER);
return root; return new SampleBlock("Size", new HBox(SPACING, smallBox, mediumBox, largeBox));
} }
private Pane brick(String text, Orientation orientation) { private Pane createPane(String text, Orientation orientation) {
var root = new StackPane(); var pane = new StackPane();
root.getChildren().setAll(new Label(text)); pane.getChildren().setAll(new Label(text));
root.getStyleClass().add("bordered"); pane.getStyleClass().add("bordered");
if (orientation == HORIZONTAL) { if (orientation == HORIZONTAL) {
root.setMinHeight(BRICK_SIZE); pane.setMinHeight(PANE_SIZE);
root.setPrefHeight(BRICK_SIZE); pane.setPrefHeight(PANE_SIZE);
root.setMaxHeight(BRICK_SIZE); pane.setMaxHeight(PANE_SIZE);
root.setMinWidth(BRICK_SIZE); pane.setMinWidth(PANE_SIZE);
} }
if (orientation == VERTICAL) { if (orientation == VERTICAL) {
root.setMinWidth(BRICK_SIZE); pane.setMinWidth(PANE_SIZE);
root.setPrefWidth(BRICK_SIZE); pane.setPrefWidth(PANE_SIZE);
root.setMaxWidth(BRICK_SIZE); pane.setMaxWidth(PANE_SIZE);
root.setMinHeight(BRICK_SIZE); pane.setMinHeight(PANE_SIZE);
} }
return root; return pane;
} }
} }

@ -2,10 +2,13 @@
package atlantafx.sampler.page.components; package atlantafx.sampler.page.components;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import javafx.scene.control.Slider; import javafx.scene.control.Slider;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import static javafx.geometry.Orientation.HORIZONTAL; import static javafx.geometry.Orientation.HORIZONTAL;
import static javafx.geometry.Orientation.VERTICAL; import static javafx.geometry.Orientation.VERTICAL;
@ -13,52 +16,52 @@ import static javafx.geometry.Orientation.VERTICAL;
public class SliderPage extends AbstractPage { public class SliderPage extends AbstractPage {
public static final String NAME = "Slider"; public static final String NAME = "Slider";
private static final int SLIDER_SIZE = 200;
private static final int SPACING = 40;
@Override @Override
public String getName() { return NAME; } public String getName() { return NAME; }
public SliderPage() { public SliderPage() {
super(); super();
createView(); setUserContent(new FlowPane(
Page.PAGE_HGAP, Page.PAGE_VGAP,
horizontalSample(),
verticalSample(),
disabledSample()
));
} }
private void createView() { private SampleBlock horizontalSample() {
userContent.getChildren().addAll(row1(), row2());
}
private Pane row1() {
var slider = new Slider(1, 5, 3); var slider = new Slider(1, 5, 3);
slider.setOrientation(HORIZONTAL); slider.setOrientation(HORIZONTAL);
var tickSlider = tickSlider(); var tickSlider = createTickSlider();
tickSlider.setMinWidth(200); tickSlider.setMinWidth(SLIDER_SIZE);
tickSlider.setMaxWidth(200); tickSlider.setMaxWidth(SLIDER_SIZE);
var hBlock = new SampleBlock("Horizontal", new HBox(20, slider, tickSlider)); return new SampleBlock("Horizontal", new VBox(SPACING, slider, tickSlider));
return new HBox(20, hBlock.getRoot());
} }
private Pane row2() { private Pane verticalSample() {
var slider = new Slider(1, 5, 3); var slider = new Slider(1, 5, 3);
slider.setOrientation(VERTICAL); slider.setOrientation(VERTICAL);
var tickSlider = tickSlider(); var tickSlider = createTickSlider();
tickSlider.setOrientation(VERTICAL); tickSlider.setOrientation(VERTICAL);
tickSlider.setMinHeight(200); tickSlider.setMinHeight(SLIDER_SIZE);
tickSlider.setMaxHeight(200); tickSlider.setMaxHeight(SLIDER_SIZE);
var vBlock = new SampleBlock("Vertical", new HBox(20, slider, tickSlider)); return new SampleBlock("Vertical", new HBox(SPACING, slider, tickSlider));
var disabledSlider = tickSlider();
disabledSlider.setDisable(true);
var disabledBlock = new SampleBlock("Disabled", new HBox(20, disabledSlider));
return new HBox(40, vBlock.getRoot(), disabledBlock.getRoot());
} }
private Slider tickSlider() { private Pane disabledSample() {
var disabledSlider = createTickSlider();
disabledSlider.setDisable(true);
return new SampleBlock("Disabled", new HBox(disabledSlider));
}
private Slider createTickSlider() {
var slider = new Slider(0, 5, 3); var slider = new Slider(0, 5, 3);
slider.setShowTickLabels(true); slider.setShowTickLabels(true);
slider.setShowTickMarks(true); slider.setShowTickMarks(true);
@ -66,7 +69,6 @@ public class SliderPage extends AbstractPage {
slider.setBlockIncrement(1); slider.setBlockIncrement(1);
slider.setMinorTickCount(5); slider.setMinorTickCount(5);
slider.setSnapToTicks(true); slider.setSnapToTicks(true);
return slider; return slider;
} }
} }

@ -3,6 +3,7 @@ package atlantafx.sampler.page.components;
import atlantafx.base.util.IntegerStringConverter; import atlantafx.base.util.IntegerStringConverter;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import javafx.scene.control.Spinner; import javafx.scene.control.Spinner;
import javafx.scene.layout.FlowPane; import javafx.scene.layout.FlowPane;
@ -17,82 +18,75 @@ public final class SpinnerPage extends AbstractPage {
public SpinnerPage() { public SpinnerPage() {
super(); super();
createView(); setUserContent(new FlowPane(
Page.PAGE_HGAP, Page.PAGE_VGAP,
basicSample(),
arrowsLeftVerticalSample(),
arrowsLeftHorizontalSample(),
arrowsRightHorizontalSample(),
arrowsSplitHorizontalSample(),
arrowsSplitVerticalSample(),
disabledSample()
));
} }
private void createView() { private SampleBlock basicSample() {
userContent.getChildren().addAll( var spinner = new Spinner<Integer>(1, 10, 1);
basicSamples(), IntegerStringConverter.createFor(spinner);
arrowPositionSamples() spinner.setPrefWidth(PREF_WIDTH);
); spinner.setEditable(true);
return new SampleBlock("Basic", spinner);
} }
private FlowPane basicSamples() { private SampleBlock disabledSample() {
var editableSpin = new Spinner<Integer>(1, 10, 1); var spinner = new Spinner<Integer>(1, 10, 1);
IntegerStringConverter.createFor(editableSpin); spinner.setPrefWidth(PREF_WIDTH);
editableSpin.setPrefWidth(PREF_WIDTH); spinner.setDisable(true);
editableSpin.setEditable(true); return new SampleBlock("Disabled", spinner);
var editableBlock = new SampleBlock("Editable", editableSpin);
var disabledSpin = new Spinner<Integer>(1, 10, 1);
disabledSpin.setPrefWidth(PREF_WIDTH);
disabledSpin.setDisable(true);
var disabledBlock = new SampleBlock("Disabled", disabledSpin);
var root = new FlowPane(20, 20);
root.getChildren().addAll(
editableBlock.getRoot(),
disabledBlock.getRoot()
);
return root;
} }
private FlowPane arrowPositionSamples() { private SampleBlock arrowsLeftVerticalSample() {
var leftVSpin = new Spinner<Integer>(1, 10, 1); var spinner = new Spinner<Integer>(1, 10, 1);
IntegerStringConverter.createFor(leftVSpin); IntegerStringConverter.createFor(spinner);
leftVSpin.getStyleClass().add(Spinner.STYLE_CLASS_ARROWS_ON_LEFT_VERTICAL); spinner.getStyleClass().add(Spinner.STYLE_CLASS_ARROWS_ON_LEFT_VERTICAL);
leftVSpin.setPrefWidth(PREF_WIDTH); spinner.setPrefWidth(PREF_WIDTH);
leftVSpin.setEditable(true); spinner.setEditable(true);
var leftVBlock = new SampleBlock("Arrows on left & vertical", leftVSpin); return new SampleBlock("Left & Vertical", spinner);
}
var leftHSpin = new Spinner<Integer>(1, 10, 1); private SampleBlock arrowsLeftHorizontalSample() {
IntegerStringConverter.createFor(leftHSpin); var spinner = new Spinner<Integer>(1, 10, 1);
leftHSpin.getStyleClass().add(Spinner.STYLE_CLASS_ARROWS_ON_LEFT_HORIZONTAL); IntegerStringConverter.createFor(spinner);
leftHSpin.setPrefWidth(PREF_WIDTH); spinner.getStyleClass().add(Spinner.STYLE_CLASS_ARROWS_ON_LEFT_HORIZONTAL);
leftHSpin.setEditable(true); spinner.setPrefWidth(PREF_WIDTH);
var leftHBlock = new SampleBlock("Arrows on left & horizontal", leftHSpin); spinner.setEditable(true);
return new SampleBlock("Left & Horizontal", spinner);
}
var rightHSpin = new Spinner<Integer>(1, 10, 1); private SampleBlock arrowsRightHorizontalSample() {
IntegerStringConverter.createFor(rightHSpin); var spinner = new Spinner<Integer>(1, 10, 1);
rightHSpin.getStyleClass().add(Spinner.STYLE_CLASS_ARROWS_ON_RIGHT_HORIZONTAL); IntegerStringConverter.createFor(spinner);
rightHSpin.setPrefWidth(PREF_WIDTH); spinner.getStyleClass().add(Spinner.STYLE_CLASS_ARROWS_ON_RIGHT_HORIZONTAL);
rightHSpin.setEditable(true); spinner.setPrefWidth(PREF_WIDTH);
var rightHBlock = new SampleBlock("Arrows on right & horizontal", rightHSpin); spinner.setEditable(true);
return new SampleBlock("Right & Horizontal", spinner);
}
var splitHSpin = new Spinner<Integer>(1, 10, 1); private SampleBlock arrowsSplitHorizontalSample() {
IntegerStringConverter.createFor(splitHSpin); var spinner = new Spinner<Integer>(1, 10, 1);
splitHSpin.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL); IntegerStringConverter.createFor(spinner);
splitHSpin.setPrefWidth(PREF_WIDTH); spinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
splitHSpin.setEditable(true); spinner.setPrefWidth(PREF_WIDTH);
var splitHBlock = new SampleBlock("Split arrows & horizontal", splitHSpin); spinner.setEditable(true);
return new SampleBlock("Split & Horizontal", spinner);
}
var splitVSpin = new Spinner<Integer>(1, 10, 1); private SampleBlock arrowsSplitVerticalSample() {
IntegerStringConverter.createFor(splitVSpin); var spinner = new Spinner<Integer>(1, 10, 1);
splitVSpin.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_VERTICAL); IntegerStringConverter.createFor(spinner);
splitVSpin.setEditable(true); spinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_VERTICAL);
splitVSpin.setPrefWidth(40); spinner.setEditable(true);
var splitVBlock = new SampleBlock("Split arrows & vertical", splitVSpin); spinner.setPrefWidth(40);
return new SampleBlock("Split & Vertical", spinner);
var root = new FlowPane(20, 20);
root.getChildren().addAll(
leftVBlock.getRoot(),
leftHBlock.getRoot(),
rightHBlock.getRoot(),
splitHBlock.getRoot(),
splitVBlock.getRoot()
);
return root;
} }
} }

@ -2,6 +2,7 @@
package atlantafx.sampler.page.components; package atlantafx.sampler.page.components;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import javafx.geometry.Orientation; import javafx.geometry.Orientation;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@ -21,51 +22,46 @@ public class SplitPanePage extends AbstractPage {
public SplitPanePage() { public SplitPanePage() {
super(); super();
createView(); setUserContent(new FlowPane(
} Page.PAGE_VGAP, Page.PAGE_HGAP,
hSplitSample(),
private void createView() { vSplitSample(),
userContent.getChildren().setAll(new FlowPane(20, 20, disabledSample(),
hSplitBlock().getRoot(), gridSample()
vSplitBlock().getRoot(),
disabledSplitBlock().getRoot(),
gridSplitBlock().getRoot()
)); ));
} }
private SampleBlock hSplitBlock() { private SampleBlock hSplitSample() {
var splitPane = new SplitPane(); var splitPane = new SplitPane();
splitPane.setOrientation(Orientation.HORIZONTAL); splitPane.setOrientation(Orientation.HORIZONTAL);
splitPane.setDividerPositions(0.5); splitPane.setDividerPositions(0.5);
splitPane.getItems().setAll(hBrick("Left"), hBrick("Right")); splitPane.getItems().setAll(createBox("Left"), createBox("Right"));
splitPane.setMinSize(200, 100); splitPane.setMinSize(200, 100);
splitPane.setMaxSize(200, 100); splitPane.setMaxSize(200, 100);
return new SampleBlock("Horizontal", splitPane); return new SampleBlock("Horizontal", splitPane);
} }
private SampleBlock vSplitBlock() { private SampleBlock vSplitSample() {
var splitPane = new SplitPane(); var splitPane = new SplitPane();
splitPane.setOrientation(Orientation.VERTICAL); splitPane.setOrientation(Orientation.VERTICAL);
splitPane.setDividerPositions(0.5); splitPane.setDividerPositions(0.5);
splitPane.getItems().setAll(vBrick("Top"), hBrick("Bottom")); splitPane.getItems().setAll(createBox("Top"), createBox("Bottom"));
splitPane.setMinSize(100, 200); splitPane.setMinSize(100, 200);
splitPane.setMaxSize(100, 200); splitPane.setMaxSize(100, 200);
return new SampleBlock("Vertical", splitPane); return new SampleBlock("Vertical", splitPane);
} }
private SampleBlock gridSplitBlock() { private SampleBlock gridSample() {
var topSplitPane = new SplitPane(); var topSplitPane = new SplitPane();
topSplitPane.setOrientation(Orientation.HORIZONTAL); topSplitPane.setOrientation(Orientation.HORIZONTAL);
topSplitPane.setDividerPositions(0.5); topSplitPane.setDividerPositions(0.5);
topSplitPane.getItems().setAll(vBrick("Quarter 4"), hBrick("Quarter 1")); topSplitPane.getItems().setAll(createBox("Quarter 4"), createBox("Quarter 1"));
VBox.setVgrow(topSplitPane, Priority.ALWAYS); VBox.setVgrow(topSplitPane, Priority.ALWAYS);
var bottomSplitPane = new SplitPane(); var bottomSplitPane = new SplitPane();
bottomSplitPane.setOrientation(Orientation.HORIZONTAL); bottomSplitPane.setOrientation(Orientation.HORIZONTAL);
bottomSplitPane.setDividerPositions(0.5); bottomSplitPane.setDividerPositions(0.5);
bottomSplitPane.getItems().setAll(vBrick("Quarter 3"), hBrick("Quarter 2")); bottomSplitPane.getItems().setAll(createBox("Quarter 3"), createBox("Quarter 2"));
VBox.setVgrow(bottomSplitPane, Priority.ALWAYS); VBox.setVgrow(bottomSplitPane, Priority.ALWAYS);
var doubleSplitPane = new SplitPane(); var doubleSplitPane = new SplitPane();
@ -81,23 +77,17 @@ public class SplitPanePage extends AbstractPage {
return new SampleBlock("Nested", doubleSplitPane); return new SampleBlock("Nested", doubleSplitPane);
} }
private SampleBlock disabledSplitBlock() { private SampleBlock disabledSample() {
var block = hSplitBlock(); var block = hSplitSample();
block.setText("Disabled"); block.setTitle("Disabled");
block.getContent().setDisable(true); block.getContent().setDisable(true);
return block; return block;
} }
private HBox hBrick(String text) { private HBox createBox(String text) {
var brick = new HBox(new Text(text)); var brick = new HBox(new Text(text));
brick.setAlignment(Pos.CENTER); brick.setAlignment(Pos.CENTER);
return brick; return brick;
} }
private VBox vBrick(String text) {
var brick = new VBox(new Text(text));
brick.setAlignment(Pos.CENTER);
return brick;
}
} }

@ -1,10 +1,11 @@
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
package atlantafx.sampler.page.components; package atlantafx.sampler.page.components;
import atlantafx.base.theme.Styles;
import atlantafx.base.controls.ToggleSwitch;
import atlantafx.base.controls.Spacer; import atlantafx.base.controls.Spacer;
import atlantafx.base.controls.ToggleSwitch;
import atlantafx.base.theme.Styles;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.SampleBlock;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@ -14,8 +15,8 @@ import javafx.scene.layout.*;
import org.kordamp.ikonli.feather.Feather; import org.kordamp.ikonli.feather.Feather;
import org.kordamp.ikonli.javafx.FontIcon; import org.kordamp.ikonli.javafx.FontIcon;
import static atlantafx.base.theme.Styles.BUTTON_ICON;
import static atlantafx.base.theme.Styles.ACCENT; import static atlantafx.base.theme.Styles.ACCENT;
import static atlantafx.base.theme.Styles.BUTTON_ICON;
import static javafx.scene.control.TabPane.TabClosingPolicy.ALL_TABS; import static javafx.scene.control.TabPane.TabClosingPolicy.ALL_TABS;
import static javafx.scene.control.TabPane.TabClosingPolicy.UNAVAILABLE; import static javafx.scene.control.TabPane.TabClosingPolicy.UNAVAILABLE;
@ -36,7 +37,7 @@ public class TabPanePage extends AbstractPage {
} }
private void createView() { private void createView() {
var tabs = tabPane(); var tabs = createTabPane();
var tabsLayer = new BorderPane(); var tabsLayer = new BorderPane();
tabsLayer.setTop(tabs); tabsLayer.setTop(tabs);
tabs.getTabs().addListener((ListChangeListener<Tab>) c -> updateTabsWidth(tabsLayer, tabs, fullWidth)); tabs.getTabs().addListener((ListChangeListener<Tab>) c -> updateTabsWidth(tabsLayer, tabs, fullWidth));
@ -52,7 +53,7 @@ public class TabPanePage extends AbstractPage {
root.getChildren().addAll(tabsLayer, controllerLayer); root.getChildren().addAll(tabsLayer, controllerLayer);
VBox.setVgrow(root, Priority.ALWAYS); VBox.setVgrow(root, Priority.ALWAYS);
userContent.getChildren().setAll(root); setUserContent(new SampleBlock("Playground", root));
} }
private TitledPane createController(BorderPane borderPane, TabPane tabs) { private TitledPane createController(BorderPane borderPane, TabPane tabs) {
@ -76,7 +77,7 @@ public class TabPanePage extends AbstractPage {
var appendBtn = new Button("", new FontIcon(Feather.PLUS)); var appendBtn = new Button("", new FontIcon(Feather.PLUS));
appendBtn.getStyleClass().addAll(BUTTON_ICON, ACCENT); appendBtn.getStyleClass().addAll(BUTTON_ICON, ACCENT);
appendBtn.setOnAction(e -> tabs.getTabs().add(randomTab())); appendBtn.setOnAction(e -> tabs.getTabs().add(createRandomTab()));
var buttonsPane = new BorderPane(); var buttonsPane = new BorderPane();
buttonsPane.setMinSize(120, 120); buttonsPane.setMinSize(120, 120);
@ -112,6 +113,16 @@ public class TabPanePage extends AbstractPage {
if (val != null) { Styles.toggleStyleClass(tabs, TabPane.STYLE_CLASS_FLOATING); } if (val != null) { Styles.toggleStyleClass(tabs, TabPane.STYLE_CLASS_FLOATING); }
}); });
var animatedToggle = new ToggleSwitch();
animatedToggle.setSelected(true);
animatedToggle.selectedProperty().addListener((obs, old, val) -> {
if (val != null && val) {
tabs.setStyle("");
} else {
tabs.setStyle("-fx-open-tab-animation:none;-fx-close-tab-animation:none;");
}
});
var fullWidthToggle = new ToggleSwitch(); var fullWidthToggle = new ToggleSwitch();
fullWidthToggle.selectedProperty().addListener((obs, old, val) -> { fullWidthToggle.selectedProperty().addListener((obs, old, val) -> {
if (val != null) { if (val != null) {
@ -129,17 +140,20 @@ public class TabPanePage extends AbstractPage {
togglesGrid.setHgap(10); togglesGrid.setHgap(10);
togglesGrid.setVgap(10); togglesGrid.setVgap(10);
togglesGrid.add(gridLabel("Closeable"), 0, 0); togglesGrid.add(createGridLabel("Closeable"), 0, 0);
togglesGrid.add(closeableToggle, 1, 0); togglesGrid.add(closeableToggle, 1, 0);
togglesGrid.add(gridLabel("Floating"), 0, 1); togglesGrid.add(createGridLabel("Floating"), 0, 1);
togglesGrid.add(floatingToggle, 1, 1); togglesGrid.add(floatingToggle, 1, 1);
togglesGrid.add(gridLabel("Full width"), 0, 2); togglesGrid.add(createGridLabel("Animated"), 0, 2);
togglesGrid.add(fullWidthToggle, 1, 2); togglesGrid.add(animatedToggle, 1, 2);
togglesGrid.add(gridLabel("Disable"), 0, 3); togglesGrid.add(createGridLabel("Full width"), 0, 3);
togglesGrid.add(disableToggle, 1, 3); togglesGrid.add(fullWidthToggle, 1, 3);
togglesGrid.add(createGridLabel("Disable"), 0, 4);
togglesGrid.add(disableToggle, 1, 4);
// == LAYOUT == // == LAYOUT ==
@ -151,11 +165,7 @@ public class TabPanePage extends AbstractPage {
); );
controls.setAlignment(Pos.CENTER); controls.setAlignment(Pos.CENTER);
var content = new VBox(20); var root = new TitledPane("Controller", controls);
content.getChildren().setAll(controls);
content.setAlignment(Pos.CENTER);
var root = new TitledPane("Controller", content);
root.setCollapsible(false); root.setCollapsible(false);
return root; return root;
@ -194,7 +204,7 @@ public class TabPanePage extends AbstractPage {
} }
} }
private TabPane tabPane() { private TabPane createTabPane() {
var tabs = new TabPane(); var tabs = new TabPane();
tabs.setTabClosingPolicy(UNAVAILABLE); tabs.setTabClosingPolicy(UNAVAILABLE);
tabs.setMinHeight(TAB_MIN_HEIGHT); tabs.setMinHeight(TAB_MIN_HEIGHT);
@ -203,9 +213,9 @@ public class TabPanePage extends AbstractPage {
// like disabled. To prevent it from closing one can use "black hole" // like disabled. To prevent it from closing one can use "black hole"
// event handler. #javafx-bug // event handler. #javafx-bug
tabs.getTabs().addAll( tabs.getTabs().addAll(
randomTab(), createRandomTab(),
randomTab(), createRandomTab(),
randomTab() createRandomTab()
); );
return tabs; return tabs;
@ -229,13 +239,13 @@ public class TabPanePage extends AbstractPage {
}); });
} }
private Tab randomTab() { private Tab createRandomTab() {
var tab = new Tab(FAKER.cat().name()); var tab = new Tab(FAKER.cat().name());
tab.setGraphic(new FontIcon(randomIcon())); tab.setGraphic(new FontIcon(randomIcon()));
return tab; return tab;
} }
private Label gridLabel(String text) { private Label createGridLabel(String text) {
var label = new Label(text); var label = new Label(text);
label.setAlignment(Pos.CENTER_RIGHT); label.setAlignment(Pos.CENTER_RIGHT);
label.setMaxWidth(Double.MAX_VALUE); label.setMaxWidth(Double.MAX_VALUE);

@ -4,8 +4,10 @@ package atlantafx.sampler.page.components;
import atlantafx.base.controls.CaptionMenuItem; import atlantafx.base.controls.CaptionMenuItem;
import atlantafx.base.controls.Spacer; import atlantafx.base.controls.Spacer;
import atlantafx.base.controls.ToggleSwitch; import atlantafx.base.controls.ToggleSwitch;
import atlantafx.base.theme.Tweaks;
import atlantafx.sampler.fake.domain.Product; import atlantafx.sampler.fake.domain.Product;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.SampleBlock;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.binding.StringBinding; import javafx.beans.binding.StringBinding;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
@ -15,9 +17,11 @@ import javafx.geometry.Pos;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.control.cell.*; import javafx.scene.control.cell.*;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.util.Callback; import javafx.util.Callback;
import org.kordamp.ikonli.feather.Feather; import org.kordamp.ikonli.feather.Feather;
import org.kordamp.ikonli.javafx.FontIcon;
import org.kordamp.ikonli.javafx.FontIconTableCell; import org.kordamp.ikonli.javafx.FontIconTableCell;
import java.util.List; import java.util.List;
@ -26,8 +30,9 @@ import java.util.stream.IntStream;
import static atlantafx.base.theme.Styles.*; import static atlantafx.base.theme.Styles.*;
import static atlantafx.base.theme.Tweaks.*; import static atlantafx.base.theme.Tweaks.*;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
import static javafx.collections.FXCollections.observableArrayList; import static javafx.collections.FXCollections.observableArrayList;
import static javafx.geometry.Orientation.HORIZONTAL;
public class TablePage extends AbstractPage { public class TablePage extends AbstractPage {
@ -43,16 +48,15 @@ public class TablePage extends AbstractPage {
public TablePage() { public TablePage() {
super(); super();
createView();
var sample = new SampleBlock("Playground", createPlayground());
sample.setFillHeight(true);
setUserContent(sample);
} }
private void createView() { private VBox createPlayground() {
userContent.getChildren().setAll( // == FOOTER ==
playground()
);
}
private VBox playground() {
var bordersToggle = new ToggleSwitch("Bordered"); var bordersToggle = new ToggleSwitch("Bordered");
bordersToggle.selectedProperty().addListener((obs, old, val) -> toggleStyleClass(table, BORDERED)); bordersToggle.selectedProperty().addListener((obs, old, val) -> toggleStyleClass(table, BORDERED));
@ -62,29 +66,31 @@ public class TablePage extends AbstractPage {
var stripesToggle = new ToggleSwitch("Striped"); var stripesToggle = new ToggleSwitch("Striped");
stripesToggle.selectedProperty().addListener((obs, old, val) -> toggleStyleClass(table, STRIPED)); stripesToggle.selectedProperty().addListener((obs, old, val) -> toggleStyleClass(table, STRIPED));
var disableToggle = new ToggleSwitch("Disable"); var edge2edgeToggle = new ToggleSwitch("Edge to edge");
disableToggle.selectedProperty().addListener((obs, old, val) -> { edge2edgeToggle.selectedProperty().addListener(
if (val != null) { table.setDisable(val); } (obs, old, value) -> toggleStyleClass(table, Tweaks.EDGE_TO_EDGE)
}); );
var maxValue = 100; var maxRowCount = 100;
var rowCountChoice = new ComboBox<>(observableArrayList(0, 5, 10, 25, maxValue)); var rowCountChoice = new ComboBox<>(observableArrayList(0, 5, 10, 25, maxRowCount));
rowCountChoice.setValue(maxValue); rowCountChoice.setValue(maxRowCount);
var rowCountBox = new HBox(10, new Label("rows"), rowCountChoice); var rowCountBox = new HBox(BLOCK_HGAP, new Label("rows"), rowCountChoice);
rowCountBox.setAlignment(Pos.CENTER_LEFT); rowCountBox.setAlignment(Pos.CENTER_LEFT);
var togglesBox = new HBox(20, var footer = new HBox(
BLOCK_HGAP,
new Spacer(),
bordersToggle, bordersToggle,
denseToggle, denseToggle,
stripesToggle, stripesToggle,
disableToggle, edge2edgeToggle,
new Spacer(HORIZONTAL), new Spacer(),
rowCountBox rowCountBox
); );
togglesBox.setAlignment(Pos.CENTER_LEFT); footer.setAlignment(Pos.CENTER_LEFT);
// ~ // == TABLE ==
var filteredData = new FilteredList<>(observableArrayList(dataList)); var filteredData = new FilteredList<>(observableArrayList(dataList));
filteredData.predicateProperty().bind(Bindings.createObjectBinding( filteredData.predicateProperty().bind(Bindings.createObjectBinding(
@ -94,32 +100,69 @@ public class TablePage extends AbstractPage {
var sortedData = new SortedList<>(filteredData); var sortedData = new SortedList<>(filteredData);
table = table(); table = createTable();
table.setItems(sortedData); table.setItems(sortedData);
sortedData.comparatorProperty().bind(table.comparatorProperty()); sortedData.comparatorProperty().bind(table.comparatorProperty());
VBox.setVgrow(table, Priority.ALWAYS);
// == HEADER ==
var alignGroup = new ToggleGroup();
var alignLeftBtn = new ToggleButton("", new FontIcon(Feather.ALIGN_LEFT));
alignLeftBtn.getStyleClass().add(".left-pill");
alignLeftBtn.setToggleGroup(alignGroup);
alignLeftBtn.setSelected(true);
alignLeftBtn.setOnAction(e -> {
for (TableColumn<?, ?> c : table.getColumns()) {
c.getStyleClass().removeAll(ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT);
}
});
var alignCenterBtn = new ToggleButton("", new FontIcon(Feather.ALIGN_CENTER));
alignCenterBtn.getStyleClass().add(".center-pill");
alignCenterBtn.setToggleGroup(alignGroup);
alignCenterBtn.selectedProperty().addListener((obs, old, val) -> {
for (TableColumn<?, ?> c : table.getColumns()) {
addStyleClass(c, ALIGN_CENTER, ALIGN_LEFT, ALIGN_RIGHT);
}
});
var alignRightBtn = new ToggleButton("", new FontIcon(Feather.ALIGN_RIGHT));
alignRightBtn.getStyleClass().add(".right-pill");
alignRightBtn.setToggleGroup(alignGroup);
alignRightBtn.selectedProperty().addListener((obs, old, val) -> {
for (TableColumn<?, ?> c : table.getColumns()) {
addStyleClass(c, ALIGN_RIGHT, ALIGN_LEFT, ALIGN_CENTER);
}
});
var alignBox = new HBox(alignLeftBtn, alignCenterBtn, alignRightBtn);
var disableToggle = new ToggleSwitch("Disable");
disableToggle.selectedProperty().addListener((obs, old, val) -> {
if (val != null) { table.setDisable(val); }
});
var header = new HBox(
createTablePropertiesMenu(table),
new Spacer(),
alignBox,
new Spacer(),
disableToggle
);
header.setAlignment(Pos.CENTER_LEFT);
// ~ // ~
var topBox = new HBox( var playground = new VBox(BLOCK_VGAP, header, table, footer);
new Label("Example:"),
new Spacer(),
settingsMenu(table)
);
topBox.setAlignment(Pos.CENTER_LEFT);
var playground = new VBox(10);
playground.setMinHeight(100); playground.setMinHeight(100);
playground.getChildren().setAll(
topBox,
table,
togglesBox
);
return playground; return playground;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private TableView<Product> table() { private TableView<Product> createTable() {
var stateCol = new TableColumn<Product, Boolean>("Selected"); var stateCol = new TableColumn<Product, Boolean>("Selected");
stateCol.setCellValueFactory(new PropertyValueFactory<>("state")); stateCol.setCellValueFactory(new PropertyValueFactory<>("state"));
stateCol.setCellFactory(CheckBoxTableCell.forTableColumn(stateCol)); stateCol.setCellFactory(CheckBoxTableCell.forTableColumn(stateCol));
@ -142,21 +185,21 @@ public class TablePage extends AbstractPage {
iconCol.setCellFactory(FontIconTableCell.forTableColumn()); iconCol.setCellFactory(FontIconTableCell.forTableColumn());
iconCol.setEditable(false); iconCol.setEditable(false);
var brandCol = new TableColumn<Product, String>("Brand "); var brandCol = new TableColumn<Product, String>("Brand 🖉");
brandCol.setCellValueFactory(new PropertyValueFactory<>("brand")); brandCol.setCellValueFactory(new PropertyValueFactory<>("brand"));
brandCol.setCellFactory(ChoiceBoxTableCell.forTableColumn( brandCol.setCellFactory(ChoiceBoxTableCell.forTableColumn(
generate(() -> FAKER.commerce().brand(), 10).toArray(String[]::new) generate(() -> FAKER.commerce().brand(), 10).toArray(String[]::new)
)); ));
brandCol.setEditable(true); brandCol.setEditable(true);
var nameCol = new TableColumn<Product, String>("Name "); var nameCol = new TableColumn<Product, String>("Name 🖉");
nameCol.setCellValueFactory(new PropertyValueFactory<>("name")); nameCol.setCellValueFactory(new PropertyValueFactory<>("name"));
nameCol.setCellFactory(ComboBoxTableCell.forTableColumn( nameCol.setCellFactory(ComboBoxTableCell.forTableColumn(
generate(() -> FAKER.commerce().productName(), 10).toArray(String[]::new) generate(() -> FAKER.commerce().productName(), 10).toArray(String[]::new)
)); ));
nameCol.setEditable(true); nameCol.setEditable(true);
var priceCol = new TableColumn<Product, String>("Price "); var priceCol = new TableColumn<Product, String>("Price 🖉");
priceCol.setCellValueFactory(new PropertyValueFactory<>("price")); priceCol.setCellValueFactory(new PropertyValueFactory<>("price"));
priceCol.setCellFactory(TextFieldTableCell.forTableColumn()); priceCol.setCellFactory(TextFieldTableCell.forTableColumn());
priceCol.setEditable(true); priceCol.setEditable(true);
@ -179,7 +222,7 @@ public class TablePage extends AbstractPage {
return table; return table;
} }
private MenuButton settingsMenu(TableView<Product> table) { private MenuButton createTablePropertiesMenu(TableView<Product> table) {
var resizePolicyCaption = new CaptionMenuItem("Resize Policy"); var resizePolicyCaption = new CaptionMenuItem("Resize Policy");
var resizePolicyGroup = new ToggleGroup(); var resizePolicyGroup = new ToggleGroup();
resizePolicyGroup.selectedToggleProperty().addListener((obs, old, val) -> { resizePolicyGroup.selectedToggleProperty().addListener((obs, old, val) -> {
@ -227,66 +270,13 @@ public class TablePage extends AbstractPage {
table.getSelectionModel().cellSelectionEnabledProperty().bind(cellSelectionItem.selectedProperty()); table.getSelectionModel().cellSelectionEnabledProperty().bind(cellSelectionItem.selectedProperty());
cellSelectionItem.setSelected(false); cellSelectionItem.setSelected(false);
var edge2edgeItem = new CheckMenuItem("Edge to edge");
edge2edgeItem.selectedProperty().addListener((obs, old, val) -> {
if (!val) {
table.getStyleClass().remove(EDGE_TO_EDGE);
} else {
table.getStyleClass().add(EDGE_TO_EDGE);
}
});
// ~
var alignToggleGroup = new ToggleGroup();
var alignLeftItem = new RadioMenuItem("Left");
alignLeftItem.setToggleGroup(alignToggleGroup);
alignLeftItem.selectedProperty().addListener((obs, old, val) -> {
for (TableColumn<?, ?> c : table.getColumns()) {
addStyleClass(c, ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT);
}
});
var alignCenterItem = new RadioMenuItem("Center");
alignCenterItem.setToggleGroup(alignToggleGroup);
alignCenterItem.selectedProperty().addListener((obs, old, val) -> {
for (TableColumn<?, ?> c : table.getColumns()) {
addStyleClass(c, ALIGN_CENTER, ALIGN_LEFT, ALIGN_RIGHT);
}
});
var alignRightItem = new RadioMenuItem("Right");
alignRightItem.setToggleGroup(alignToggleGroup);
alignRightItem.selectedProperty().addListener((obs, old, val) -> {
for (TableColumn<?, ?> c : table.getColumns()) {
addStyleClass(c, ALIGN_RIGHT, ALIGN_LEFT, ALIGN_CENTER);
}
});
var alignDefaultItem = new MenuItem("Default");
alignDefaultItem.setOnAction(e -> {
for (TableColumn<?, ?> c : table.getColumns()) {
c.getStyleClass().removeAll(ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT);
}
});
var alignMenu = new Menu("Align columns");
alignMenu.getItems().setAll(
alignLeftItem,
alignCenterItem,
alignRightItem,
new SeparatorMenuItem(),
alignDefaultItem
);
// ~ // ~
var menuButtonItem = new CheckMenuItem("Show menu button"); var menuButtonItem = new CheckMenuItem("Show menu button");
table.tableMenuButtonVisibleProperty().bind(menuButtonItem.selectedProperty()); table.tableMenuButtonVisibleProperty().bind(menuButtonItem.selectedProperty());
menuButtonItem.setSelected(true); menuButtonItem.setSelected(true);
return new MenuButton("Settings") {{ return new MenuButton("Properties") {{
getItems().setAll( getItems().setAll(
resizePolicyCaption, resizePolicyCaption,
unconstrainedResizeItem, unconstrainedResizeItem,
@ -297,8 +287,6 @@ public class TablePage extends AbstractPage {
new SeparatorMenuItem(), new SeparatorMenuItem(),
editCellsItem, editCellsItem,
cellSelectionItem, cellSelectionItem,
alignMenu,
edge2edgeItem,
menuButtonItem menuButtonItem
); );
}}; }};

@ -23,59 +23,63 @@ public class TextAreaPage extends AbstractPage {
public TextAreaPage() { public TextAreaPage() {
super(); super();
createView(); setUserContent(new FlowPane(
PAGE_HGAP, PAGE_VGAP,
basicSample(),
promptSample(),
scrollSample(),
readonlySample(),
successSample(),
dangerSample(),
disabledSample()
));
} }
private void createView() { private SampleBlock basicSample() {
userContent.getChildren().setAll(samples()); var textArea = createTextArea("Text");
textArea.setWrapText(true);
return new SampleBlock("Basic", textArea);
} }
private FlowPane samples() { private SampleBlock promptSample() {
var basicArea = textArea("Text"); var textArea = createTextArea(null);
basicArea.setWrapText(true); textArea.setPromptText("Prompt text");
var basicBlock = new SampleBlock("Basic", basicArea); return new SampleBlock("Prompt", textArea);
}
var promptArea = textArea(null); private SampleBlock scrollSample() {
promptArea.setPromptText("Prompt text"); var textArea = createTextArea(
var promptBlock = new SampleBlock("Prompt", promptArea);
var scrollArea = textArea(
Stream.generate(() -> FAKER.lorem().paragraph()).limit(10).collect(Collectors.joining("\n")) Stream.generate(() -> FAKER.lorem().paragraph()).limit(10).collect(Collectors.joining("\n"))
); );
scrollArea.setWrapText(false); textArea.setWrapText(false);
var scrollBlock = new SampleBlock("Scrolling", scrollArea); return new SampleBlock("Scrolling", textArea);
var readonlyArea = textArea("Text");
readonlyArea.setEditable(false);
var readonlyBlock = new SampleBlock("Readonly", readonlyArea);
var disabledArea = textArea("Text");
disabledArea.setDisable(true);
var disabledBlock = new SampleBlock("Disabled", disabledArea);
var successArea = textArea("Text");
successArea.pseudoClassStateChanged(STATE_SUCCESS, true);
var successBlock = new SampleBlock("Success", successArea);
var dangerArea = textArea("Text");
dangerArea.pseudoClassStateChanged(STATE_DANGER, true);
var dangerBlock = new SampleBlock("Danger", dangerArea);
var flowPane = new FlowPane(20, 20);
flowPane.getChildren().setAll(
basicBlock.getRoot(),
promptBlock.getRoot(),
scrollBlock.getRoot(),
readonlyBlock.getRoot(),
disabledBlock.getRoot(),
successBlock.getRoot(),
dangerBlock.getRoot()
);
return flowPane;
} }
private TextArea textArea(String text) { private SampleBlock readonlySample() {
var textArea = createTextArea("Text");
textArea.setEditable(false);
return new SampleBlock("Readonly", textArea);
}
private SampleBlock successSample() {
var textArea = createTextArea("Text");
textArea.pseudoClassStateChanged(STATE_SUCCESS, true);
return new SampleBlock("Success", textArea);
}
private SampleBlock dangerSample() {
var textArea = createTextArea("Text");
textArea.pseudoClassStateChanged(STATE_DANGER, true);
return new SampleBlock("Danger", textArea);
}
private SampleBlock disabledSample() {
var textArea = createTextArea("Text");
textArea.setDisable(true);
return new SampleBlock("Disabled", textArea);
}
private TextArea createTextArea(String text) {
var textArea = new TextArea(text); var textArea = new TextArea(text);
textArea.setMinWidth(CONTROL_WIDTH); textArea.setMinWidth(CONTROL_WIDTH);
textArea.setMinHeight(CONTROL_HEIGHT); textArea.setMinHeight(CONTROL_HEIGHT);

@ -20,57 +20,63 @@ public class TextFieldPage extends AbstractPage {
public TextFieldPage() { public TextFieldPage() {
super(); super();
createView(); setUserContent(new FlowPane(
PAGE_HGAP, PAGE_VGAP,
basicSample(),
promptSample(),
passwordSample(),
readonlySample(),
successSample(),
dangerSample(),
roundedSample(),
disabledSample()
));
} }
private void createView() { private SampleBlock basicSample() {
userContent.getChildren().setAll(samples()); var field = new TextField("Text");
return new SampleBlock("Basic", field);
} }
private FlowPane samples() { private SampleBlock passwordSample() {
var basicField = new TextField("Text"); var field = new PasswordField();
var basicBlock = new SampleBlock("Basic", basicField); field.setText("qwerty");
return new SampleBlock("Password", field);
}
var passwordField = new PasswordField(); private SampleBlock promptSample() {
passwordField.setText("qwerty"); var field = new TextField();
var passwordBlock = new SampleBlock("Password", passwordField); field.setPromptText("Prompt text");
return new SampleBlock("Prompt", field);
}
var promptField = new TextField(); private SampleBlock readonlySample() {
promptField.setPromptText("Prompt text"); var field = new TextField("Text");
var promptBlock = new SampleBlock("Prompt", promptField); field.setEditable(false);
return new SampleBlock("Readonly", field);
}
var readonlyField = new TextField("Text"); private SampleBlock successSample() {
readonlyField.setEditable(false); var field = new TextField("Text");
var readonlyBlock = new SampleBlock("Readonly", readonlyField); field.pseudoClassStateChanged(STATE_SUCCESS, true);
return new SampleBlock("Success", field);
}
var disabledField = new TextField("Text"); private SampleBlock dangerSample() {
disabledField.setDisable(true); var field = new TextField("Text");
var disabledBlock = new SampleBlock("Disabled", disabledField); field.pseudoClassStateChanged(STATE_DANGER, true);
return new SampleBlock("Danger", field);
}
var successField = new TextField("Text"); private SampleBlock roundedSample() {
successField.pseudoClassStateChanged(STATE_SUCCESS, true); var field = new TextField("Text");
var successBlock = new SampleBlock("Success", successField); field.getStyleClass().add(Styles.ROUNDED);
return new SampleBlock("Rounded", field);
}
var dangerField = new TextField("Text"); private SampleBlock disabledSample() {
dangerField.pseudoClassStateChanged(STATE_DANGER, true); var field = new TextField("Text");
var dangerBlock = new SampleBlock("Danger", dangerField); field.setDisable(true);
return new SampleBlock("Disabled", field);
var roundedField = new TextField("Text");
roundedField.getStyleClass().add(Styles.ROUNDED);
var roundedBlock = new SampleBlock("Rounded", roundedField);
var flowPane = new FlowPane(20, 20);
flowPane.getChildren().setAll(
basicBlock.getRoot(),
passwordBlock.getRoot(),
promptBlock.getRoot(),
readonlyBlock.getRoot(),
disabledBlock.getRoot(),
successBlock.getRoot(),
dangerBlock.getRoot(),
roundedBlock.getRoot()
);
return flowPane;
} }
} }

@ -1,9 +1,10 @@
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
package atlantafx.sampler.page.components; package atlantafx.sampler.page.components;
import atlantafx.base.controls.ToggleSwitch;
import atlantafx.base.controls.Spacer; import atlantafx.base.controls.Spacer;
import atlantafx.base.controls.ToggleSwitch;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.CheckBox; import javafx.scene.control.CheckBox;
import javafx.scene.control.Label; import javafx.scene.control.Label;
@ -18,6 +19,8 @@ import javafx.scene.text.TextFlow;
import static atlantafx.base.theme.Styles.ELEVATED_2; import static atlantafx.base.theme.Styles.ELEVATED_2;
import static atlantafx.base.theme.Styles.INTERACTIVE; import static atlantafx.base.theme.Styles.INTERACTIVE;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
public class TitledPanePage extends AbstractPage { public class TitledPanePage extends AbstractPage {
@ -33,13 +36,22 @@ public class TitledPanePage extends AbstractPage {
} }
private void createView() { private void createView() {
var samples = new HBox(20, interactivePane(), disabledCard(), untitledCard()); var samples = new HBox(
PAGE_HGAP,
interactivePane(),
disabledPane(),
untitledPane()
);
samples.getChildren().forEach(c -> ((TitledPane) c).setPrefSize(500, 120)); samples.getChildren().forEach(c -> ((TitledPane) c).setPrefSize(500, 120));
userContent.getChildren().setAll(new VBox(20, playground(), samples)); setUserContent(new VBox(
Page.PAGE_VGAP,
createPlayground(),
samples
));
} }
private TitledPane playground() { private TitledPane createPlayground() {
var playground = new TitledPane(); var playground = new TitledPane();
playground.setText("_Playground"); playground.setText("_Playground");
playground.setMnemonicParsing(true); playground.setMnemonicParsing(true);
@ -79,7 +91,7 @@ public class TitledPanePage extends AbstractPage {
animateToggle.setSelected(true); animateToggle.setSelected(true);
playground.animatedProperty().bind(animateToggle.selectedProperty()); playground.animatedProperty().bind(animateToggle.selectedProperty());
var controls = new HBox(20); var controls = new HBox(BLOCK_HGAP);
controls.setMinHeight(80); controls.setMinHeight(80);
controls.setFillHeight(false); controls.setFillHeight(false);
controls.setAlignment(Pos.CENTER_LEFT); controls.setAlignment(Pos.CENTER_LEFT);
@ -91,7 +103,7 @@ public class TitledPanePage extends AbstractPage {
animateToggle animateToggle
); );
var content = new VBox(20, textFlow, controls); var content = new VBox(BLOCK_VGAP, textFlow, controls);
VBox.setVgrow(textFlow, Priority.ALWAYS); VBox.setVgrow(textFlow, Priority.ALWAYS);
playground.setContent(content); playground.setContent(content);
@ -105,14 +117,14 @@ public class TitledPanePage extends AbstractPage {
return titledPane; return titledPane;
} }
private TitledPane disabledCard() { private TitledPane disabledPane() {
var titledPane = new TitledPane("Disabled", new CheckBox("This checkbox is disabled.")); var titledPane = new TitledPane("Disabled", new CheckBox("This checkbox is disabled."));
titledPane.setCollapsible(false); titledPane.setCollapsible(false);
titledPane.setDisable(true); titledPane.setDisable(true);
return titledPane; return titledPane;
} }
private TitledPane untitledCard() { private TitledPane untitledPane() {
var titledPane = new TitledPane("This pane has no title.", new Text()); var titledPane = new TitledPane("This pane has no title.", new Text());
titledPane.setCollapsible(false); titledPane.setCollapsible(false);
return titledPane; return titledPane;

@ -2,6 +2,7 @@
package atlantafx.sampler.page.components; package atlantafx.sampler.page.components;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay; import javafx.scene.control.ContentDisplay;
@ -12,6 +13,7 @@ import org.kordamp.ikonli.feather.Feather;
import org.kordamp.ikonli.javafx.FontIcon; import org.kordamp.ikonli.javafx.FontIcon;
import static atlantafx.base.theme.Styles.*; import static atlantafx.base.theme.Styles.*;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
import static atlantafx.sampler.util.Controls.toggleButton; import static atlantafx.sampler.util.Controls.toggleButton;
import static javafx.scene.layout.GridPane.REMAINING; import static javafx.scene.layout.GridPane.REMAINING;
@ -29,15 +31,15 @@ public class ToggleButtonPage extends AbstractPage {
private void createView() { private void createView() {
var grid = new GridPane(); var grid = new GridPane();
grid.setHgap(40); grid.setHgap(Page.PAGE_HGAP);
grid.setVgap(40); grid.setVgap(Page.PAGE_VGAP);
grid.add(basicSample().getRoot(), 0, 0, REMAINING, 1); grid.add(basicSample(), 0, 0, REMAINING, 1);
grid.add(wizardSample().getRoot(), 0, 1); grid.add(wizardSample(), 0, 1);
grid.add(iconOnlySample().getRoot(), 1, 1); grid.add(iconOnlySample(), 1, 1);
grid.add(disabledSample().getRoot(), 0, 2); grid.add(disabledSample(), 0, 2);
userContent.getChildren().addAll(grid); setUserContent(grid);
} }
private SampleBlock basicSample() { private SampleBlock basicSample() {
@ -45,15 +47,12 @@ public class ToggleButtonPage extends AbstractPage {
var leftPill = toggleButton("._left-pill", null, threeButtonGroup, true, LEFT_PILL); var leftPill = toggleButton("._left-pill", null, threeButtonGroup, true, LEFT_PILL);
leftPill.setMnemonicParsing(true); leftPill.setMnemonicParsing(true);
leftPill.setOnAction(PRINT_SOURCE);
var centerPill = toggleButton("._center-pill", null, threeButtonGroup, false, CENTER_PILL); var centerPill = toggleButton("._center-pill", null, threeButtonGroup, false, CENTER_PILL);
centerPill.setMnemonicParsing(true); centerPill.setMnemonicParsing(true);
centerPill.setOnAction(PRINT_SOURCE);
var rightPill = toggleButton("._right-pill", null, threeButtonGroup, false, RIGHT_PILL); var rightPill = toggleButton("._right-pill", null, threeButtonGroup, false, RIGHT_PILL);
rightPill.setMnemonicParsing(true); rightPill.setMnemonicParsing(true);
rightPill.setOnAction(PRINT_SOURCE);
var threeButtonBox = new HBox(leftPill, centerPill, rightPill); var threeButtonBox = new HBox(leftPill, centerPill, rightPill);
@ -63,18 +62,14 @@ public class ToggleButtonPage extends AbstractPage {
toggleButton(".right-pill", null, twoButtonGroup, false, RIGHT_PILL) toggleButton(".right-pill", null, twoButtonGroup, false, RIGHT_PILL)
); );
var content = new HBox(10); return new SampleBlock("Basic", new HBox(BLOCK_HGAP, threeButtonBox, twoButtonBox));
content.getChildren().setAll(threeButtonBox, twoButtonBox);
return new SampleBlock("Basic", content);
} }
private SampleBlock wizardSample() { private SampleBlock wizardSample() {
var group = new ToggleGroup(); var group = new ToggleGroup();
var prevBtn = new Button("\f"); var prevBtn = new Button("\f", new FontIcon(Feather.CHEVRON_LEFT));
prevBtn.getStyleClass().addAll(BUTTON_ICON, LEFT_PILL); prevBtn.getStyleClass().addAll(BUTTON_ICON, LEFT_PILL);
prevBtn.setGraphic(new FontIcon(Feather.CHEVRON_LEFT));
prevBtn.setOnAction(e -> { prevBtn.setOnAction(e -> {
int selected = group.getToggles().indexOf(group.getSelectedToggle()); int selected = group.getToggles().indexOf(group.getSelectedToggle());
if (selected > 0) { if (selected > 0) {
@ -82,9 +77,8 @@ public class ToggleButtonPage extends AbstractPage {
} }
}); });
var nextBtn = new Button("\f"); var nextBtn = new Button("\f", new FontIcon(Feather.CHEVRON_RIGHT));
nextBtn.getStyleClass().addAll(BUTTON_ICON, RIGHT_PILL); nextBtn.getStyleClass().addAll(BUTTON_ICON, RIGHT_PILL);
nextBtn.setGraphic(new FontIcon(Feather.CHEVRON_RIGHT));
nextBtn.setContentDisplay(ContentDisplay.RIGHT); nextBtn.setContentDisplay(ContentDisplay.RIGHT);
nextBtn.setOnAction(e -> { nextBtn.setOnAction(e -> {
int selected = group.getToggles().indexOf(group.getSelectedToggle()); int selected = group.getToggles().indexOf(group.getSelectedToggle());

@ -3,9 +3,9 @@ package atlantafx.sampler.page.components;
import atlantafx.base.controls.ToggleSwitch; import atlantafx.base.controls.ToggleSwitch;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import javafx.geometry.Pos; import atlantafx.sampler.page.Page;
import javafx.scene.control.Label; import atlantafx.sampler.page.SampleBlock;
import javafx.scene.layout.VBox; import javafx.scene.layout.FlowPane;
public class ToggleSwitchPage extends AbstractPage { public class ToggleSwitchPage extends AbstractPage {
@ -16,17 +16,16 @@ public class ToggleSwitchPage extends AbstractPage {
public ToggleSwitchPage() { public ToggleSwitchPage() {
super(); super();
createView(); setUserContent(new FlowPane(
Page.PAGE_HGAP, Page.PAGE_VGAP,
basicSample()
));
} }
private void createView() { private SampleBlock basicSample() {
var toggle = new ToggleSwitch(); var toggle = new ToggleSwitch();
toggle.selectedProperty().addListener((obs, old, val) -> toggle.setText(val ? "Disable" : "Enable")); toggle.selectedProperty().addListener((obs, old, val) -> toggle.setText(val ? "Disable" : "Enable"));
toggle.setSelected(true); toggle.setSelected(true);
return new SampleBlock("Basic", toggle);
var box = new VBox(20, new Label("Nothing fancy here."), toggle);
box.setAlignment(Pos.CENTER);
userContent.getChildren().setAll(box);
} }
} }

@ -6,6 +6,7 @@ import atlantafx.base.controls.ToggleSwitch;
import atlantafx.base.theme.Styles; import atlantafx.base.theme.Styles;
import atlantafx.sampler.fake.SampleMenuBar; import atlantafx.sampler.fake.SampleMenuBar;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.SampleBlock;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.geometry.Orientation; import javafx.geometry.Orientation;
@ -22,6 +23,7 @@ import java.util.ArrayList;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import static atlantafx.base.theme.Styles.*; import static atlantafx.base.theme.Styles.*;
import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
import static atlantafx.sampler.util.Controls.*; import static atlantafx.sampler.util.Controls.*;
import static javafx.geometry.Orientation.HORIZONTAL; import static javafx.geometry.Orientation.HORIZONTAL;
import static javafx.geometry.Orientation.VERTICAL; import static javafx.geometry.Orientation.VERTICAL;
@ -41,7 +43,7 @@ public class ToolBarPage extends AbstractPage {
} }
private void createView() { private void createView() {
var toolbar = new ToolBar(toolBarButtons(HORIZONTAL)); var toolbar = new ToolBar(createButtons(HORIZONTAL));
var toolbarLayer = new BorderPane(); var toolbarLayer = new BorderPane();
toolbarLayer.setTop(new TopBar(toolbar)); toolbarLayer.setTop(new TopBar(toolbar));
@ -56,7 +58,7 @@ public class ToolBarPage extends AbstractPage {
root.getChildren().addAll(toolbarLayer, controllerLayer); root.getChildren().addAll(toolbarLayer, controllerLayer);
VBox.setVgrow(root, Priority.ALWAYS); VBox.setVgrow(root, Priority.ALWAYS);
userContent.getChildren().setAll(root); setUserContent(new SampleBlock("Playground", root));
} }
private TitledPane createController(BorderPane borderPane, ToolBar toolbar) { private TitledPane createController(BorderPane borderPane, ToolBar toolbar) {
@ -130,10 +132,10 @@ public class ToolBarPage extends AbstractPage {
togglesGrid.setHgap(10); togglesGrid.setHgap(10);
togglesGrid.setVgap(10); togglesGrid.setVgap(10);
togglesGrid.add(gridLabel("Show menu bar"), 0, 0); togglesGrid.add(createLabel("Show menu bar"), 0, 0);
togglesGrid.add(menuBarToggle, 1, 0); togglesGrid.add(menuBarToggle, 1, 0);
togglesGrid.add(gridLabel("Disable"), 0, 1); togglesGrid.add(createLabel("Disable"), 0, 1);
togglesGrid.add(disableToggle, 1, 1); togglesGrid.add(disableToggle, 1, 1);
// == LAYOUT == // == LAYOUT ==
@ -141,7 +143,7 @@ public class ToolBarPage extends AbstractPage {
var controls = new HBox(40, new Spacer(), buttonsPane, togglesGrid, new Spacer()); var controls = new HBox(40, new Spacer(), buttonsPane, togglesGrid, new Spacer());
controls.setAlignment(Pos.CENTER); controls.setAlignment(Pos.CENTER);
var content = new VBox(10); var content = new VBox(BLOCK_VGAP);
content.getChildren().setAll(controls); content.getChildren().setAll(controls);
content.setAlignment(Pos.CENTER); content.setAlignment(Pos.CENTER);
@ -171,32 +173,32 @@ public class ToolBarPage extends AbstractPage {
case TOP -> { case TOP -> {
toolbar.setOrientation(HORIZONTAL); toolbar.setOrientation(HORIZONTAL);
Styles.addStyleClass(toolbar, TOP, RIGHT, BOTTOM, LEFT); Styles.addStyleClass(toolbar, TOP, RIGHT, BOTTOM, LEFT);
toolbar.getItems().setAll(toolBarButtons(HORIZONTAL)); toolbar.getItems().setAll(createButtons(HORIZONTAL));
topBar.setToolBar(toolbar); topBar.setToolBar(toolbar);
} }
case RIGHT -> { case RIGHT -> {
toolbar.setOrientation(VERTICAL); toolbar.setOrientation(VERTICAL);
Styles.addStyleClass(toolbar, RIGHT, TOP, BOTTOM, LEFT); Styles.addStyleClass(toolbar, RIGHT, TOP, BOTTOM, LEFT);
toolbar.getItems().setAll(toolBarButtons(VERTICAL)); toolbar.getItems().setAll(createButtons(VERTICAL));
borderPane.setRight(toolbar); borderPane.setRight(toolbar);
} }
case BOTTOM -> { case BOTTOM -> {
toolbar.setOrientation(HORIZONTAL); toolbar.setOrientation(HORIZONTAL);
Styles.addStyleClass(toolbar, BOTTOM, TOP, RIGHT, LEFT); Styles.addStyleClass(toolbar, BOTTOM, TOP, RIGHT, LEFT);
toolbar.getItems().setAll(toolBarButtons(HORIZONTAL)); toolbar.getItems().setAll(createButtons(HORIZONTAL));
borderPane.setBottom(toolbar); borderPane.setBottom(toolbar);
} }
case LEFT -> { case LEFT -> {
toolbar.setOrientation(VERTICAL); toolbar.setOrientation(VERTICAL);
Styles.addStyleClass(toolbar, LEFT, RIGHT, TOP, BOTTOM); Styles.addStyleClass(toolbar, LEFT, RIGHT, TOP, BOTTOM);
toolbar.getItems().setAll(toolBarButtons(VERTICAL)); toolbar.getItems().setAll(createButtons(VERTICAL));
borderPane.setLeft(toolbar); borderPane.setLeft(toolbar);
} }
} }
}); });
} }
public Node[] toolBarButtons(Orientation orientation) { public Node[] createButtons(Orientation orientation) {
var result = new ArrayList<Node>(); var result = new ArrayList<Node>();
result.add(iconButton(Feather.FILE, false)); result.add(iconButton(Feather.FILE, false));
result.add(iconButton(Feather.FOLDER, false)); result.add(iconButton(Feather.FOLDER, false));
@ -209,18 +211,18 @@ public class ToolBarPage extends AbstractPage {
result.add(new Separator()); result.add(new Separator());
var group = new ToggleGroup();
result.add(toggleButton("", Feather.BOLD, null, true, BUTTON_ICON, LEFT_PILL)); result.add(toggleButton("", Feather.BOLD, null, true, BUTTON_ICON, LEFT_PILL));
result.add(toggleButton("", Feather.ITALIC, null, false, BUTTON_ICON, CENTER_PILL)); result.add(toggleButton("", Feather.ITALIC, null, false, BUTTON_ICON, CENTER_PILL));
result.add(toggleButton("", Feather.UNDERLINE, null, false, BUTTON_ICON, RIGHT_PILL)); result.add(toggleButton("", Feather.UNDERLINE, null, false, BUTTON_ICON, RIGHT_PILL));
result.add(new Spacer(5)); result.add(new Spacer(5));
var fontCombo = new ComboBox<>(FXCollections.observableArrayList(Font.getFamilies())); var fontCombo = new ComboBox<>(FXCollections.observableArrayList(Font.getFamilies()));
fontCombo.setPrefWidth(150); fontCombo.setPrefWidth(150);
fontCombo.getSelectionModel().selectFirst(); fontCombo.getSelectionModel().selectFirst();
result.add(fontCombo); result.add(fontCombo);
var settingsMenu = new MenuButton("Settings", new FontIcon(Feather.SETTINGS), menuItems(5)); var settingsMenu = new MenuButton("Settings", new FontIcon(Feather.SETTINGS), createItems(5));
settingsMenu.getStyleClass().add(FLAT); settingsMenu.getStyleClass().add(FLAT);
result.add(new Spacer()); result.add(new Spacer());
result.add(settingsMenu); result.add(settingsMenu);
@ -236,14 +238,14 @@ public class ToolBarPage extends AbstractPage {
return result.toArray(Node[]::new); return result.toArray(Node[]::new);
} }
private Label gridLabel(String text) { private Label createLabel(String text) {
var label = new Label(text); var label = new Label(text);
label.setAlignment(Pos.CENTER_RIGHT); label.setAlignment(Pos.CENTER_RIGHT);
label.setMaxWidth(Double.MAX_VALUE); label.setMaxWidth(Double.MAX_VALUE);
return label; return label;
} }
public static MenuItem[] menuItems(int count) { public static MenuItem[] createItems(int count) {
return IntStream.range(0, count).mapToObj(i -> new MenuItem(FAKER.babylon5().character())).toArray(MenuItem[]::new); return IntStream.range(0, count).mapToObj(i -> new MenuItem(FAKER.babylon5().character())).toArray(MenuItem[]::new);
} }

@ -2,15 +2,20 @@
package atlantafx.sampler.page.components; package atlantafx.sampler.page.components;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.Separator; import javafx.scene.control.Separator;
import javafx.scene.control.Tooltip; import javafx.scene.control.Tooltip;
import javafx.scene.layout.FlowPane; import javafx.scene.layout.FlowPane;
import javafx.scene.layout.VBox;
import javafx.stage.PopupWindow.AnchorLocation; import javafx.stage.PopupWindow.AnchorLocation;
import javafx.util.Duration; import javafx.util.Duration;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
import static javafx.geometry.Orientation.VERTICAL; import static javafx.geometry.Orientation.VERTICAL;
public class TooltipPage extends AbstractPage { public class TooltipPage extends AbstractPage {
@ -22,59 +27,63 @@ public class TooltipPage extends AbstractPage {
public TooltipPage() { public TooltipPage() {
super(); super();
createView(); setUserContent(new VBox(Page.PAGE_VGAP,
expandingHBox(
basicSample(),
textWrapSample(),
indefiniteSample()
),
positionSample()
));
} }
private void createView() { private SampleBlock basicSample() {
userContent.getChildren().setAll( var tooltip = new Tooltip(FAKER.harryPotter().spell());
basicSamples(), tooltip.setHideDelay(Duration.seconds(3));
positionSamples().getRoot()
); var label = createLabel("Hover me");
label.setTooltip(tooltip);
return new SampleBlock("Basic", label);
} }
private FlowPane basicSamples() { private SampleBlock textWrapSample() {
var basicTooltip = new Tooltip(FAKER.harryPotter().spell()); var tooltip = new Tooltip(FAKER.lorem().paragraph(5));
basicTooltip.setHideDelay(Duration.seconds(3)); tooltip.setHideDelay(Duration.seconds(3));
var basicLabel = label("Hover me"); tooltip.setPrefWidth(200);
basicLabel.setTooltip(basicTooltip); tooltip.setWrapText(true);
var basicBlock = new SampleBlock("Basic", basicLabel);
var textWrapTooltip = new Tooltip(FAKER.lorem().paragraph(5)); var label = createLabel("Hover me");
textWrapTooltip.setHideDelay(Duration.seconds(3)); label.setTooltip(tooltip);
textWrapTooltip.setPrefWidth(200);
textWrapTooltip.setWrapText(true);
var textWrapLabel = label("Hover me");
textWrapLabel.setTooltip(textWrapTooltip);
var textWrapBlock = new SampleBlock("Text wrapping", textWrapLabel);
var indefiniteTooltip = new Tooltip(FAKER.harryPotter().spell()); return new SampleBlock("Text Wrap", label);
indefiniteTooltip.setHideDelay(Duration.INDEFINITE);
var indefiniteLabel = label("Hover me");
indefiniteLabel.setTooltip(basicTooltip);
var indefiniteBlock = new SampleBlock("Indefinite", indefiniteLabel);
return new FlowPane(20, 10,
basicBlock.getRoot(),
textWrapBlock.getRoot(),
indefiniteBlock.getRoot()
);
} }
private SampleBlock positionSamples() { private SampleBlock indefiniteSample() {
var topLeftLabel = label("Top Left"); var tooltip = new Tooltip(FAKER.harryPotter().spell());
topLeftLabel.setTooltip(tooltip("Top Left", AnchorLocation.WINDOW_BOTTOM_RIGHT)); tooltip.setHideDelay(Duration.INDEFINITE);
var topRightLabel = label("Top Right"); var label = createLabel("Hover me");
topRightLabel.setTooltip(tooltip("Top Right", AnchorLocation.WINDOW_BOTTOM_LEFT)); label.setTooltip(tooltip);
var bottomLeftLabel = label("Bottom Left"); return new SampleBlock("Indefinite", label);
bottomLeftLabel.setTooltip(tooltip("Bottom Left", AnchorLocation.WINDOW_TOP_RIGHT)); }
var bottomRightLabel = label("Bottom Right"); private SampleBlock positionSample() {
bottomRightLabel.setTooltip(tooltip("Bottom Right", AnchorLocation.WINDOW_TOP_LEFT)); var topLeftLabel = createLabel("Top Left");
topLeftLabel.setTooltip(createTooltip("Top Left", AnchorLocation.WINDOW_BOTTOM_RIGHT));
var flowPane = new FlowPane(20, 10); var topRightLabel = createLabel("Top Right");
flowPane.getChildren().setAll( topRightLabel.setTooltip(createTooltip("Top Right", AnchorLocation.WINDOW_BOTTOM_LEFT));
var bottomLeftLabel = createLabel("Bottom Left");
bottomLeftLabel.setTooltip(createTooltip("Bottom Left", AnchorLocation.WINDOW_TOP_RIGHT));
var bottomRightLabel = createLabel("Bottom Right");
bottomRightLabel.setTooltip(createTooltip("Bottom Right", AnchorLocation.WINDOW_TOP_LEFT));
var flowPane = new FlowPane(
BLOCK_HGAP, BLOCK_VGAP,
topLeftLabel, topLeftLabel,
new Separator(VERTICAL), new Separator(VERTICAL),
topRightLabel, topRightLabel,
@ -87,17 +96,19 @@ public class TooltipPage extends AbstractPage {
return new SampleBlock("Position", flowPane); return new SampleBlock("Position", flowPane);
} }
private Label label(String text) { private Label createLabel(String text) {
Label label = new Label(text); Label label = new Label(text);
label.setMinWidth(50); label.setMinWidth(50);
label.setMinHeight(50); label.setMinHeight(50);
label.setPadding(new Insets(10));
label.setStyle("-fx-background-color:-color-accent-subtle;");
label.setAlignment(Pos.CENTER_LEFT); label.setAlignment(Pos.CENTER_LEFT);
return label; return label;
} }
private Tooltip tooltip(String text, AnchorLocation anchorLocation) { private Tooltip createTooltip(String text, AnchorLocation arrowPos) {
var tooltip = new Tooltip(text); var tooltip = new Tooltip(text);
tooltip.setAnchorLocation(anchorLocation); tooltip.setAnchorLocation(arrowPos);
return tooltip; return tooltip;
} }
} }

@ -5,13 +5,16 @@ import atlantafx.base.controls.Spacer;
import atlantafx.base.controls.ToggleSwitch; import atlantafx.base.controls.ToggleSwitch;
import atlantafx.base.theme.Tweaks; import atlantafx.base.theme.Tweaks;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import javafx.geometry.Orientation; import atlantafx.sampler.page.SampleBlock;
import javafx.geometry.Pos;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.control.cell.CheckBoxTreeCell; import javafx.scene.control.cell.CheckBoxTreeCell;
import javafx.scene.control.cell.ChoiceBoxTreeCell; import javafx.scene.control.cell.ChoiceBoxTreeCell;
import javafx.scene.control.cell.ComboBoxTreeCell; import javafx.scene.control.cell.ComboBoxTreeCell;
import javafx.scene.control.cell.TextFieldTreeCell; import javafx.scene.control.cell.TextFieldTreeCell;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.util.StringConverter; import javafx.util.StringConverter;
import org.kordamp.ikonli.feather.Feather; import org.kordamp.ikonli.feather.Feather;
@ -25,6 +28,8 @@ import java.util.function.Supplier;
import static atlantafx.base.theme.Styles.DENSE; import static atlantafx.base.theme.Styles.DENSE;
import static atlantafx.base.theme.Styles.toggleStyleClass; import static atlantafx.base.theme.Styles.toggleStyleClass;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
public class TreePage extends AbstractPage { public class TreePage extends AbstractPage {
@ -33,34 +38,20 @@ public class TreePage extends AbstractPage {
private static final int[] TREE_DICE = { -1, 0, 1 }; private static final int[] TREE_DICE = { -1, 0, 1 };
@Override @Override
public String getName() { public String getName() { return NAME; }
return NAME;
}
private VBox playground; private final BorderPane treeWrapper = new BorderPane();
private ComboBox<Example> exampleSelect; private final ComboBox<Example> exampleSelect = createExampleSelect();
public TreePage() { public TreePage() {
super(); super();
createView();
var sample = new SampleBlock("Playground", createPlayground());
sample.setFillHeight(true);
setUserContent(sample);
} }
private void createView() { private VBox createPlayground() {
exampleSelect = exampleSelect();
playground = playground(exampleSelect);
userContent.getChildren().setAll(playground);
}
@Override
protected void onRendered() {
super.onRendered();
exampleSelect.getSelectionModel().selectFirst();
}
private VBox playground(ComboBox<Example> exampleSelect) {
var playground = new VBox(10);
playground.setMinHeight(100);
var denseToggle = new ToggleSwitch("Dense"); var denseToggle = new ToggleSwitch("Dense");
denseToggle.selectedProperty().addListener( denseToggle.selectedProperty().addListener(
(obs, old, value) -> findDisplayedTree().ifPresent(tv -> toggleStyleClass(tv, DENSE)) (obs, old, value) -> findDisplayedTree().ifPresent(tv -> toggleStyleClass(tv, DENSE))
@ -82,34 +73,29 @@ public class TreePage extends AbstractPage {
if (val != null) { tv.setDisable(val); } if (val != null) { tv.setDisable(val); }
})); }));
var controls = new HBox(20, var controls = new HBox(BLOCK_HGAP, denseToggle, showRootToggle, edge2edgeToggle);
new Spacer(), controls.setAlignment(Pos.CENTER);
denseToggle,
showRootToggle,
edge2edgeToggle,
disableToggle,
new Spacer()
);
playground.getChildren().setAll( VBox.setVgrow(treeWrapper, Priority.ALWAYS);
new Label("Select an example:"),
var playground = new VBox(
BLOCK_VGAP,
new HBox(new Label("Select an example:"), new Spacer(), disableToggle),
exampleSelect, exampleSelect,
new Spacer(Orientation.VERTICAL), // placeholder for TreeView<?> treeWrapper,
controls controls
); );
playground.setMinHeight(100);
return playground; return playground;
} }
private ComboBox<Example> exampleSelect() { private ComboBox<Example> createExampleSelect() {
var select = new ComboBox<Example>(); var select = new ComboBox<Example>();
select.setMaxWidth(Double.MAX_VALUE); select.setMaxWidth(Double.MAX_VALUE);
select.getItems().setAll(Example.values()); select.getItems().setAll(Example.values());
select.getSelectionModel().selectedItemProperty().addListener((obs, old, val) -> { select.getSelectionModel().selectedItemProperty().addListener((obs, old, val) -> {
if (val == null) { return; } if (val == null) { return; }
if (playground.getChildren().size() != 4) {
throw new RuntimeException("Unexpected container size.");
}
TreeView<String> newTree = createTree(val); TreeView<String> newTree = createTree(val);
@ -123,10 +109,9 @@ public class TreePage extends AbstractPage {
newTree.setDisable(tv.isDisable()); newTree.setDisable(tv.isDisable());
}); });
playground.getChildren().set(2, newTree); treeWrapper.setCenter(newTree);
}); });
select.setConverter(new StringConverter<>() { select.setConverter(new StringConverter<>() {
@Override @Override
public String toString(Example example) { public String toString(Example example) {
return example == null ? "" : example.getName(); return example == null ? "" : example.getName();
@ -141,12 +126,16 @@ public class TreePage extends AbstractPage {
return select; return select;
} }
@Override
protected void onRendered() {
super.onRendered();
exampleSelect.getSelectionModel().selectFirst();
}
private Optional<TreeView<?>> findDisplayedTree() { private Optional<TreeView<?>> findDisplayedTree() {
if (playground == null) { return Optional.empty(); } return treeWrapper.getChildren().size() > 0 ?
return playground.getChildren().stream() Optional.of((TreeView<?>) treeWrapper.getChildren().get(0)) :
.filter(c -> c instanceof TreeView<?>) Optional.empty();
.findFirst()
.map(c -> (TreeView<?>) c);
} }
private TreeView<String> createTree(Example example) { private TreeView<String> createTree(Example example) {

@ -7,13 +7,17 @@ import atlantafx.base.controls.ToggleSwitch;
import atlantafx.base.theme.Tweaks; import atlantafx.base.theme.Tweaks;
import atlantafx.sampler.fake.domain.Product; import atlantafx.sampler.fake.domain.Product;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.SampleBlock;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.control.cell.*; import javafx.scene.control.cell.*;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.util.Callback; import javafx.util.Callback;
import org.kordamp.ikonli.feather.Feather;
import org.kordamp.ikonli.javafx.FontIcon;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -21,6 +25,8 @@ import java.util.stream.IntStream;
import static atlantafx.base.theme.Styles.*; import static atlantafx.base.theme.Styles.*;
import static atlantafx.base.theme.Tweaks.*; import static atlantafx.base.theme.Tweaks.*;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
public class TreeTablePage extends AbstractPage { public class TreeTablePage extends AbstractPage {
@ -33,16 +39,15 @@ public class TreeTablePage extends AbstractPage {
public TreeTablePage() { public TreeTablePage() {
super(); super();
createView();
var sample = new SampleBlock("Playground", createPlayground());
sample.setFillHeight(true);
setUserContent(sample);
} }
private void createView() { private VBox createPlayground() {
userContent.getChildren().setAll( // == FOOTER ==
playground()
);
}
private VBox playground() {
var bordersToggle = new ToggleSwitch("Bordered"); var bordersToggle = new ToggleSwitch("Bordered");
bordersToggle.selectedProperty().addListener((obs, old, val) -> toggleStyleClass(treeTable, BORDERED)); bordersToggle.selectedProperty().addListener((obs, old, val) -> toggleStyleClass(treeTable, BORDERED));
@ -52,20 +57,15 @@ public class TreeTablePage extends AbstractPage {
var stripesToggle = new ToggleSwitch("Striped"); var stripesToggle = new ToggleSwitch("Striped");
stripesToggle.selectedProperty().addListener((obs, old, val) -> toggleStyleClass(treeTable, STRIPED)); stripesToggle.selectedProperty().addListener((obs, old, val) -> toggleStyleClass(treeTable, STRIPED));
var disableToggle = new ToggleSwitch("Disable"); var edge2edgeToggle = new ToggleSwitch("Edge to edge");
disableToggle.selectedProperty().addListener((obs, old, val) -> { edge2edgeToggle.selectedProperty().addListener(
if (val != null) { treeTable.setDisable(val); } (obs, old, value) -> toggleStyleClass(treeTable, Tweaks.EDGE_TO_EDGE)
});
var togglesBox = new HBox(20,
bordersToggle,
denseToggle,
stripesToggle,
disableToggle
); );
togglesBox.setAlignment(Pos.CENTER_LEFT);
// ~ var footer = new HBox(BLOCK_HGAP, bordersToggle, denseToggle, stripesToggle, edge2edgeToggle);
footer.setAlignment(Pos.CENTER);
// == TREE TABLE ==
var rootVal = Product.empty(0); var rootVal = Product.empty(0);
rootVal.setBrand("Root"); rootVal.setBrand("Root");
@ -78,35 +78,72 @@ public class TreeTablePage extends AbstractPage {
var group = new TreeItem<>(groupVal); var group = new TreeItem<>(groupVal);
group.getChildren().setAll( group.getChildren().setAll(
treeItems(idx * 100, FAKER.random().nextInt(5, 10), brand) createTreeItems(idx * 100, FAKER.random().nextInt(5, 10), brand)
); );
root.getChildren().add(group); root.getChildren().add(group);
} }
treeTable = treeTable(); treeTable = createTreeTable();
treeTable.setRoot(root); treeTable.setRoot(root);
VBox.setVgrow(treeTable, Priority.ALWAYS);
// == HEADER ==
var alignGroup = new ToggleGroup();
var alignLeftBtn = new ToggleButton("", new FontIcon(Feather.ALIGN_LEFT));
alignLeftBtn.getStyleClass().add(".left-pill");
alignLeftBtn.setToggleGroup(alignGroup);
alignLeftBtn.setSelected(true);
alignLeftBtn.setOnAction(e -> {
for (TreeTableColumn<?, ?> c : treeTable.getColumns()) {
c.getStyleClass().removeAll(ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT);
}
});
var alignCenterBtn = new ToggleButton("", new FontIcon(Feather.ALIGN_CENTER));
alignCenterBtn.getStyleClass().add(".center-pill");
alignCenterBtn.setToggleGroup(alignGroup);
alignCenterBtn.selectedProperty().addListener((obs, old, val) -> {
for (TreeTableColumn<?, ?> c : treeTable.getColumns()) {
addStyleClass(c, ALIGN_CENTER, ALIGN_LEFT, ALIGN_RIGHT);
}
});
var alignRightBtn = new ToggleButton("", new FontIcon(Feather.ALIGN_RIGHT));
alignRightBtn.getStyleClass().add(".right-pill");
alignRightBtn.setToggleGroup(alignGroup);
alignRightBtn.selectedProperty().addListener((obs, old, val) -> {
for (TreeTableColumn<?, ?> c : treeTable.getColumns()) {
addStyleClass(c, ALIGN_RIGHT, ALIGN_LEFT, ALIGN_CENTER);
}
});
var alignBox = new HBox(alignLeftBtn, alignCenterBtn, alignRightBtn);
var disableToggle = new ToggleSwitch("Disable");
disableToggle.selectedProperty().addListener((obs, old, val) -> {
if (val != null) { treeTable.setDisable(val); }
});
var header = new HBox(
createPropertiesMenu(treeTable),
new Spacer(),
alignBox,
new Spacer(),
disableToggle
);
header.setAlignment(Pos.CENTER_LEFT);
// ~ // ~
var topBox = new HBox( var playground = new VBox(BLOCK_VGAP, header, treeTable, footer);
new Label("Example:"),
new Spacer(),
settingsMenu(treeTable)
);
topBox.setAlignment(Pos.CENTER_LEFT);
var playground = new VBox(10);
playground.setMinHeight(100); playground.setMinHeight(100);
playground.getChildren().setAll(
topBox,
treeTable,
togglesBox
);
return playground; return playground;
} }
private List<TreeItem<Product>> treeItems(int startId, int count, String brand) { private List<TreeItem<Product>> createTreeItems(int startId, int count, String brand) {
return IntStream.range(startId, startId + count + 1).boxed() return IntStream.range(startId, startId + count + 1).boxed()
.map(id -> Product.random(id, brand, FAKER)) .map(id -> Product.random(id, brand, FAKER))
.map(TreeItem::new) .map(TreeItem::new)
@ -114,7 +151,7 @@ public class TreeTablePage extends AbstractPage {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private TreeTableView<Product> treeTable() { private TreeTableView<Product> createTreeTable() {
var arrowCol = new TreeTableColumn<Product, String>("#"); var arrowCol = new TreeTableColumn<Product, String>("#");
// This is placeholder column for disclosure nodes. We need to fill it // This is placeholder column for disclosure nodes. We need to fill it
// with empty strings or all .tree-table-cell will be marked as :empty, // with empty strings or all .tree-table-cell will be marked as :empty,
@ -138,14 +175,14 @@ public class TreeTablePage extends AbstractPage {
idCol.setEditable(false); idCol.setEditable(false);
idCol.setMinWidth(80); idCol.setMinWidth(80);
var brandCol = new TreeTableColumn<Product, String>("Brand "); var brandCol = new TreeTableColumn<Product, String>("Brand 🖉");
brandCol.setCellValueFactory(new TreeItemPropertyValueFactory<>("brand")); brandCol.setCellValueFactory(new TreeItemPropertyValueFactory<>("brand"));
brandCol.setCellFactory(ChoiceBoxTreeTableCell.forTreeTableColumn( brandCol.setCellFactory(ChoiceBoxTreeTableCell.forTreeTableColumn(
generate(() -> FAKER.commerce().brand(), 10).toArray(String[]::new) generate(() -> FAKER.commerce().brand(), 10).toArray(String[]::new)
)); ));
brandCol.setEditable(true); brandCol.setEditable(true);
var nameCol = new TreeTableColumn<Product, String>("Name "); var nameCol = new TreeTableColumn<Product, String>("Name 🖉");
nameCol.setCellValueFactory(new TreeItemPropertyValueFactory<>("name")); nameCol.setCellValueFactory(new TreeItemPropertyValueFactory<>("name"));
nameCol.setCellFactory(ComboBoxTreeTableCell.forTreeTableColumn( nameCol.setCellFactory(ComboBoxTreeTableCell.forTreeTableColumn(
generate(() -> FAKER.commerce().productName(), 10).toArray(String[]::new) generate(() -> FAKER.commerce().productName(), 10).toArray(String[]::new)
@ -153,7 +190,7 @@ public class TreeTablePage extends AbstractPage {
nameCol.setEditable(true); nameCol.setEditable(true);
nameCol.setMinWidth(200); nameCol.setMinWidth(200);
var priceCol = new TreeTableColumn<Product, String>("Price "); var priceCol = new TreeTableColumn<Product, String>("Price 🖉");
priceCol.setCellValueFactory(new TreeItemPropertyValueFactory<>("price")); priceCol.setCellValueFactory(new TreeItemPropertyValueFactory<>("price"));
priceCol.setCellFactory(TextFieldTreeTableCell.forTreeTableColumn()); priceCol.setCellFactory(TextFieldTreeTableCell.forTreeTableColumn());
priceCol.setEditable(true); priceCol.setEditable(true);
@ -164,7 +201,7 @@ public class TreeTablePage extends AbstractPage {
return table; return table;
} }
private MenuButton settingsMenu(TreeTableView<Product> treeTable) { private MenuButton createPropertiesMenu(TreeTableView<Product> treeTable) {
var resizePolicyCaption = new CaptionMenuItem("Resize Policy"); var resizePolicyCaption = new CaptionMenuItem("Resize Policy");
var resizePolicyGroup = new ToggleGroup(); var resizePolicyGroup = new ToggleGroup();
resizePolicyGroup.selectedToggleProperty().addListener((obs, old, val) -> { resizePolicyGroup.selectedToggleProperty().addListener((obs, old, val) -> {
@ -216,66 +253,13 @@ public class TreeTablePage extends AbstractPage {
treeTable.getSelectionModel().cellSelectionEnabledProperty().bind(cellSelectionItem.selectedProperty()); treeTable.getSelectionModel().cellSelectionEnabledProperty().bind(cellSelectionItem.selectedProperty());
cellSelectionItem.setSelected(false); cellSelectionItem.setSelected(false);
var edge2edgeItem = new CheckMenuItem("Edge to edge");
edge2edgeItem.selectedProperty().addListener((obs, old, val) -> {
if (!val) {
treeTable.getStyleClass().remove(Tweaks.EDGE_TO_EDGE);
} else {
treeTable.getStyleClass().add(Tweaks.EDGE_TO_EDGE);
}
});
// ~
var alignToggleGroup = new ToggleGroup();
var alignLeftItem = new RadioMenuItem("Left");
alignLeftItem.setToggleGroup(alignToggleGroup);
alignLeftItem.selectedProperty().addListener((obs, old, val) -> {
for (TreeTableColumn<?, ?> c : treeTable.getColumns()) {
addStyleClass(c, ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT);
}
});
var alignCenterItem = new RadioMenuItem("Center");
alignCenterItem.setToggleGroup(alignToggleGroup);
alignCenterItem.selectedProperty().addListener((obs, old, val) -> {
for (TreeTableColumn<?, ?> c : treeTable.getColumns()) {
addStyleClass(c, ALIGN_CENTER, ALIGN_LEFT, ALIGN_RIGHT);
}
});
var alignRightItem = new RadioMenuItem("Right");
alignRightItem.setToggleGroup(alignToggleGroup);
alignRightItem.selectedProperty().addListener((obs, old, val) -> {
for (TreeTableColumn<?, ?> c : treeTable.getColumns()) {
addStyleClass(c, ALIGN_RIGHT, ALIGN_LEFT, ALIGN_CENTER);
}
});
var alignDefaultItem = new MenuItem("Default");
alignDefaultItem.setOnAction(e -> {
for (TreeTableColumn<?, ?> c : treeTable.getColumns()) {
c.getStyleClass().removeAll(ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT);
}
});
var alignMenu = new Menu("Align columns");
alignMenu.getItems().setAll(
alignLeftItem,
alignCenterItem,
alignRightItem,
new SeparatorMenuItem(),
alignDefaultItem
);
// ~ // ~
var menuButtonItem = new CheckMenuItem("Show menu button"); var menuButtonItem = new CheckMenuItem("Show menu button");
treeTable.tableMenuButtonVisibleProperty().bind(menuButtonItem.selectedProperty()); treeTable.tableMenuButtonVisibleProperty().bind(menuButtonItem.selectedProperty());
menuButtonItem.setSelected(true); menuButtonItem.setSelected(true);
return new MenuButton("Settings") {{ return new MenuButton("Properties") {{
getItems().setAll( getItems().setAll(
resizePolicyCaption, resizePolicyCaption,
unconstrainedResizeItem, unconstrainedResizeItem,
@ -287,8 +271,6 @@ public class TreeTablePage extends AbstractPage {
showRootItem, showRootItem,
editCellsItem, editCellsItem,
cellSelectionItem, cellSelectionItem,
alignMenu,
edge2edgeItem,
menuButtonItem menuButtonItem
); );
}}; }};

@ -5,6 +5,7 @@ import atlantafx.base.theme.Styles;
import atlantafx.sampler.event.DefaultEventBus; import atlantafx.sampler.event.DefaultEventBus;
import atlantafx.sampler.event.ThemeEvent; import atlantafx.sampler.event.ThemeEvent;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.Page;
import atlantafx.sampler.theme.SamplerTheme; import atlantafx.sampler.theme.SamplerTheme;
import atlantafx.sampler.theme.ThemeManager; import atlantafx.sampler.theme.ThemeManager;
import javafx.geometry.HPos; import javafx.geometry.HPos;
@ -13,6 +14,7 @@ import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.Tooltip; import javafx.scene.control.Tooltip;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text; import javafx.scene.text.Text;
import javafx.scene.text.TextFlow; import javafx.scene.text.TextFlow;
import javafx.util.Duration; import javafx.util.Duration;
@ -25,6 +27,8 @@ import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
import static atlantafx.sampler.event.ThemeEvent.EventType.*; import static atlantafx.sampler.event.ThemeEvent.EventType.*;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
import static atlantafx.sampler.util.Controls.hyperlink; import static atlantafx.sampler.util.Controls.hyperlink;
public class ThemePage extends AbstractPage { public class ThemePage extends AbstractPage {
@ -46,29 +50,25 @@ public class ThemePage extends AbstractPage {
private final ColorPalette colorPalette = new ColorPalette(colorBlockActionHandler); private final ColorPalette colorPalette = new ColorPalette(colorBlockActionHandler);
private final ColorScale colorScale = new ColorScale(); private final ColorScale colorScale = new ColorScale();
private final ChoiceBox<SamplerTheme> themeSelector = themeSelector(); private final ChoiceBox<SamplerTheme> themeSelector = createThemeSelector();
private ThemeRepoManagerDialog themeRepoManagerDialog; private ThemeRepoManagerDialog themeRepoManagerDialog;
private ContrastCheckerDialog contrastCheckerDialog; private ContrastCheckerDialog contrastCheckerDialog;
@Override @Override
public String getName() { public String getName() { return NAME; }
return NAME;
}
@Override @Override
public boolean canDisplaySourceCode() { public boolean canDisplaySourceCode() { return false; }
return false;
}
@Override @Override
public boolean canChangeThemeSettings() { public boolean canChangeThemeSettings() { return false; }
return false;
}
public ThemePage() { public ThemePage() {
super(); super();
createView(); createView();
DefaultEventBus.getInstance().subscribe(ThemeEvent.class, e -> { DefaultEventBus.getInstance().subscribe(ThemeEvent.class, e -> {
if (e.getEventType() == THEME_ADD || e.getEventType() == THEME_REMOVE) { if (e.getEventType() == THEME_ADD || e.getEventType() == THEME_REMOVE) {
themeSelector.getItems().setAll(TM.getRepository().getAll()); themeSelector.getItems().setAll(TM.getRepository().getAll());
@ -91,32 +91,29 @@ public class ThemePage extends AbstractPage {
private void createView() { private void createView() {
var noteText = new TextFlow( var noteText = new TextFlow(
new Text("AtlantaFX follows "), new Text("AtlantaFX follows "),
hyperlink("Github Primer interface guidelines", hyperlink("Github Primer interface guidelines", URI.create("https://primer.style/design/foundations/color")),
URI.create("https://primer.style/design/foundations/color")
),
new Text(" and color system.") new Text(" and color system.")
); );
userContent.getChildren().addAll( setUserContent(new VBox(
optionsGrid(), Page.PAGE_VGAP,
createOptionsGrid(),
noteText, noteText,
colorPalette, colorPalette,
colorScale colorScale
); ));
selectCurrentTheme(); selectCurrentTheme();
} }
private GridPane optionsGrid() { private GridPane createOptionsGrid() {
var themeRepoBtn = new Button("", new FontIcon(Material2OutlinedMZ.SETTINGS)); var themeRepoBtn = new Button("", new FontIcon(Material2OutlinedMZ.SETTINGS));
themeRepoBtn.getStyleClass().addAll(Styles.BUTTON_ICON, Styles.FLAT); themeRepoBtn.getStyleClass().addAll(Styles.BUTTON_ICON, Styles.FLAT);
themeRepoBtn.setTooltip(new Tooltip("Settings")); themeRepoBtn.setTooltip(new Tooltip("Settings"));
themeRepoBtn.setOnAction(e -> { themeRepoBtn.setOnAction(e -> {
ThemeRepoManagerDialog dialog = getOrCreateThemeRepoManagerDialog(); ThemeRepoManagerDialog dialog = getOrCreateThemeRepoManagerDialog();
overlay.setContent(dialog, HPos.CENTER); overlay.setContent(dialog, HPos.CENTER);
dialog.getContent().update(); dialog.getContent().update();
overlay.toFront(); overlay.toFront();
}); });
@ -125,8 +122,8 @@ public class ThemePage extends AbstractPage {
// ~ // ~
var grid = new GridPane(); var grid = new GridPane();
grid.setVgap(20); grid.setHgap(BLOCK_HGAP);
grid.setHgap(20); grid.setVgap(BLOCK_VGAP);
grid.add(new Label("Color theme"), 0, 0); grid.add(new Label("Color theme"), 0, 0);
grid.add(themeSelector, 1, 0); grid.add(themeSelector, 1, 0);
@ -137,7 +134,7 @@ public class ThemePage extends AbstractPage {
return grid; return grid;
} }
private ChoiceBox<SamplerTheme> themeSelector() { private ChoiceBox<SamplerTheme> createThemeSelector() {
var selector = new ChoiceBox<SamplerTheme>(); var selector = new ChoiceBox<SamplerTheme>();
selector.getItems().setAll(TM.getRepository().getAll()); selector.getItems().setAll(TM.getRepository().getAll());
selector.getSelectionModel().selectedItemProperty().addListener((obs, old, val) -> { selector.getSelectionModel().selectedItemProperty().addListener((obs, old, val) -> {

@ -6,56 +6,54 @@ import atlantafx.sampler.event.ThemeEvent;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.SampleBlock; import atlantafx.sampler.page.SampleBlock;
import atlantafx.sampler.theme.ThemeManager; import atlantafx.sampler.theme.ThemeManager;
import atlantafx.sampler.util.NodeUtils;
import javafx.animation.KeyFrame; import javafx.animation.KeyFrame;
import javafx.animation.Timeline; import javafx.animation.Timeline;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.ComboBox; import javafx.scene.control.ComboBox;
import javafx.scene.control.Hyperlink; import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.Spinner; import javafx.scene.control.Spinner;
import javafx.scene.layout.GridPane; import javafx.scene.layout.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font; import javafx.scene.text.Font;
import javafx.scene.text.Text; import javafx.scene.text.Text;
import javafx.scene.text.TextFlow; import javafx.scene.text.TextFlow;
import javafx.util.Duration; import javafx.util.Duration;
import java.util.Map;
import java.util.stream.Collectors;
import static atlantafx.base.theme.Styles.*; import static atlantafx.base.theme.Styles.*;
import static atlantafx.sampler.event.ThemeEvent.EventType.FONT_CHANGE; import static atlantafx.sampler.event.ThemeEvent.EventType.FONT_CHANGE;
import static atlantafx.sampler.event.ThemeEvent.EventType.THEME_CHANGE; import static atlantafx.sampler.event.ThemeEvent.EventType.THEME_CHANGE;
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
import static atlantafx.sampler.page.SampleBlock.BLOCK_VGAP;
import static atlantafx.sampler.theme.ThemeManager.DEFAULT_FONT_FAMILY_NAME;
import static atlantafx.sampler.theme.ThemeManager.SUPPORTED_FONT_SIZE; import static atlantafx.sampler.theme.ThemeManager.SUPPORTED_FONT_SIZE;
public class TypographyPage extends AbstractPage { public class TypographyPage extends AbstractPage {
private static final double CONTROL_WIDTH = 200;
private static final String DEFAULT_FONT_ID = "Default";
public static final String NAME = "Typography"; public static final String NAME = "Typography";
private static final int CONTROL_WIDTH = 200;
@Override private static final String DEFAULT_FONT_ID = "Default";
public String getName() { private static final ThemeManager TM = ThemeManager.getInstance();
return NAME;
}
@Override
public boolean canDisplaySourceCode() {
return false;
}
@Override
public boolean canChangeThemeSettings() {
return false;
}
private Pane fontSizeSampleContent; private Pane fontSizeSampleContent;
@Override
public String getName() { return NAME; }
@Override
public boolean canDisplaySourceCode() { return false; }
@Override
public boolean canChangeThemeSettings() { return false; }
public TypographyPage() { public TypographyPage() {
super(); super();
createView(); createView();
DefaultEventBus.getInstance().subscribe(ThemeEvent.class, e -> { DefaultEventBus.getInstance().subscribe(ThemeEvent.class, e -> {
if (e.getEventType() == THEME_CHANGE || e.getEventType() == FONT_CHANGE) { if (e.getEventType() == THEME_CHANGE || e.getEventType() == FONT_CHANGE) {
@ -66,53 +64,53 @@ public class TypographyPage extends AbstractPage {
private void createView() { private void createView() {
var controlsGrid = new GridPane(); var controlsGrid = new GridPane();
controlsGrid.setVgap(10); controlsGrid.setHgap(BLOCK_HGAP);
controlsGrid.setHgap(20); controlsGrid.setVgap(BLOCK_VGAP);
controlsGrid.add(new Label("Font family"), 0, 0); controlsGrid.add(new Label("Font family"), 0, 0);
controlsGrid.add(fontFamilyChooser(), 1, 0); controlsGrid.add(createFontFamilyChooser(), 1, 0);
controlsGrid.add(new Label("Font size"), 0, 1); controlsGrid.add(new Label("Font size"), 0, 1);
controlsGrid.add(fontSizeSpinner(), 1, 1); controlsGrid.add(crateFontSizeSpinner(), 1, 1);
var fontSizeSample = fontSizeSample(); var fontSizeSample = fontSizeSample();
fontSizeSampleContent = (Pane) fontSizeSample.getContent(); fontSizeSampleContent = (Pane) fontSizeSample.getContent();
userContent.getChildren().setAll( setUserContent(new VBox(
PAGE_VGAP,
controlsGrid, controlsGrid,
fontSizeSample.getRoot(), fontSizeSample,
fontWeightSample().getRoot(), fontWeightSample(),
fontStyleSample().getRoot(), expandingHBox(fontStyleSample(), textColorSample(), hyperlinkSample()),
hyperlinkSample().getRoot(), textFlowSample()
textColorSample().getRoot(), ));
textFlowSample().getRoot()
);
} }
private ComboBox<String> fontFamilyChooser() { @Override
final var tm = ThemeManager.getInstance(); protected void onRendered() {
super.onRendered();
// font metrics can only be obtained by requesting from a rendered node
updateFontInfo(Duration.ZERO);
}
private ComboBox<String> createFontFamilyChooser() {
ComboBox<String> comboBox = new ComboBox<>(); ComboBox<String> comboBox = new ComboBox<>();
comboBox.getItems().add(tm.isDefaultFontFamily() ? DEFAULT_FONT_ID : tm.getFontFamily()); comboBox.getItems().add(TM.isDefaultFontFamily() ? DEFAULT_FONT_ID : TM.getFontFamily());
comboBox.getItems().addAll(FXCollections.observableArrayList(Font.getFamilies())); comboBox.getItems().addAll(FXCollections.observableArrayList(Font.getFamilies()));
comboBox.setPrefWidth(CONTROL_WIDTH); comboBox.setPrefWidth(CONTROL_WIDTH);
comboBox.getSelectionModel().select(tm.getFontFamily()); comboBox.getSelectionModel().select(TM.getFontFamily());
comboBox.valueProperty().addListener((obs, old, val) -> { comboBox.valueProperty().addListener((obs, old, val) -> {
if (val != null) { if (val != null) {
tm.setFontFamily(DEFAULT_FONT_ID.equals(val) ? ThemeManager.DEFAULT_FONT_FAMILY_NAME : val); TM.setFontFamily(DEFAULT_FONT_ID.equals(val) ? DEFAULT_FONT_FAMILY_NAME : val);
} }
}); });
return comboBox; return comboBox;
} }
private Spinner<Integer> fontSizeSpinner() { private Spinner<Integer> crateFontSizeSpinner() {
final var tm = ThemeManager.getInstance();
var spinner = new Spinner<Integer>( var spinner = new Spinner<Integer>(
SUPPORTED_FONT_SIZE.get(0), SUPPORTED_FONT_SIZE.get(0),
SUPPORTED_FONT_SIZE.get(SUPPORTED_FONT_SIZE.size() - 1), SUPPORTED_FONT_SIZE.get(SUPPORTED_FONT_SIZE.size() - 1),
tm.getFontSize() TM.getFontSize()
); );
spinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL); spinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
spinner.setPrefWidth(CONTROL_WIDTH); spinner.setPrefWidth(CONTROL_WIDTH);
@ -122,11 +120,11 @@ public class TypographyPage extends AbstractPage {
// we just keep current font size inside ThemeManager singleton. // we just keep current font size inside ThemeManager singleton.
// It works fine if ThemeManager default font size value matches // It works fine if ThemeManager default font size value matches
// default theme font size value. // default theme font size value.
spinner.getValueFactory().setValue(tm.getFontSize()); spinner.getValueFactory().setValue(TM.getFontSize());
spinner.valueProperty().addListener((obs, old, val) -> { spinner.valueProperty().addListener((obs, old, val) -> {
if (val != null) { if (val != null) {
tm.setFontSize(val); TM.setFontSize(val);
updateFontInfo(Duration.seconds(1)); updateFontInfo(Duration.seconds(1));
} }
}); });
@ -134,159 +132,153 @@ public class TypographyPage extends AbstractPage {
return spinner; return spinner;
} }
// font metrics can only be obtained by requesting from a rendered node
protected void onRendered() {
super.onRendered();
updateFontInfo(Duration.ZERO);
}
private void updateFontInfo(Duration delay) { private void updateFontInfo(Duration delay) {
var t = new Timeline(new KeyFrame(delay)); var t = new Timeline(new KeyFrame(delay));
t.setOnFinished(e -> { t.setOnFinished(e -> {
for (Node node : fontSizeSampleContent.getChildren()) { Map<String, Node> map = fontSizeSampleContent.getChildren().stream()
if (node instanceof Text textNode) { .collect(Collectors.toMap(
var font = textNode.getFont(); n -> GridPane.getColumnIndex(n).toString() + GridPane.getRowIndex(n).toString(),
textNode.setText( n -> n
String.format("%s = %.1fpx", textNode.getUserData(), Math.ceil(font.getSize())) ));
); ((Label) map.get("10")).setText(String.format("%.0fpx", getFontSize(map.get("00"))));
} ((Label) map.get("11")).setText(String.format("%.0fpx", getFontSize(map.get("01"))));
} ((Label) map.get("12")).setText(String.format("%.0fpx", getFontSize(map.get("02"))));
((Label) map.get("13")).setText(String.format("%.0fpx", getFontSize(map.get("03"))));
((Label) map.get("30")).setText(String.format("%.0fpx", getFontSize(map.get("20"))));
((Label) map.get("31")).setText(String.format("%.0fpx", getFontSize(map.get("21"))));
((Label) map.get("32")).setText(String.format("%.0fpx", getFontSize(map.get("22"))));
}); });
t.play(); t.play();
} }
private double getFontSize(Node node) {
return (node instanceof Text text) ? Math.ceil(text.getFont().getSize()) : 0;
}
private SampleBlock fontSizeSample() { private SampleBlock fontSizeSample() {
var grid = new GridPane(); var grid = new GridPane();
grid.setHgap(40); grid.setHgap(BLOCK_HGAP);
grid.setVgap(10); grid.setVgap(BLOCK_VGAP);
grid.add(text("Title 1", TITLE_1), 0, 0); grid.add(createText("Title 1", TITLE_1), 0, 0);
grid.add(text("Title 2", TITLE_2), 0, 1); grid.add(createFontSizeLabel(), 1, 0);
grid.add(text("Title 3", TITLE_3), 0, 2); grid.add(createText("Title 2", TITLE_2), 0, 1);
grid.add(text("Title 4", TITLE_4), 0, 3); grid.add(createFontSizeLabel(), 1, 1);
grid.add(createText("Title 3", TITLE_3), 0, 2);
grid.add(createFontSizeLabel(), 1, 2);
grid.add(createText("Title 4", TITLE_4), 0, 3);
grid.add(createFontSizeLabel(), 1, 3);
grid.add(text("Caption", TEXT_CAPTION), 1, 0); grid.add(createText("Caption", TEXT_CAPTION), 2, 0);
grid.add(text("Default"), 1, 1); grid.add(createFontSizeLabel(), 3, 0);
grid.add(text("Small", TEXT_SMALL), 1, 2); grid.add(createText("Default"), 2, 1);
grid.add(createFontSizeLabel(), 3, 1);
grid.add(createText("Small", TEXT_SMALL), 2, 2);
grid.add(createFontSizeLabel(), 3, 2);
grid.setAlignment(Pos.BASELINE_LEFT); grid.setAlignment(Pos.BASELINE_LEFT);
return new SampleBlock("Font size", grid); return new SampleBlock("Font Size", grid);
} }
private SampleBlock fontWeightSample() { private SampleBlock fontWeightSample() {
var sample1 = new HBox(10, var sample1 = new HBox(
text("Bold", TEXT_BOLD), BLOCK_HGAP,
text("Bolder", TEXT_BOLDER), createText("Bold", TEXT_BOLD),
text("Normal", TEXT_NORMAL), createText("Bolder", TEXT_BOLDER),
text("Lighter", TEXT_LIGHTER) createText("Normal", TEXT_NORMAL),
createText("Lighter", TEXT_LIGHTER)
); );
sample1.setAlignment(Pos.BASELINE_LEFT); sample1.setAlignment(Pos.BASELINE_LEFT);
var sample2 = new HBox(10, var sample2 = new HBox(
textInlineStyle("900", "-fx-font-weight:900;"), BLOCK_HGAP,
textInlineStyle("800", "-fx-font-weight:800;"), createStyledText("900", "-fx-font-weight:900;"),
textInlineStyle("700", "-fx-font-weight:700;"), createStyledText("800", "-fx-font-weight:800;"),
textInlineStyle("600", "-fx-font-weight:600;"), createStyledText("700", "-fx-font-weight:700;"),
textInlineStyle("500", "-fx-font-weight:500;"), createStyledText("600", "-fx-font-weight:600;"),
textInlineStyle("400", "-fx-font-weight:400;"), createStyledText("500", "-fx-font-weight:500;"),
textInlineStyle("300", "-fx-font-weight:300;"), createStyledText("400", "-fx-font-weight:400;"),
textInlineStyle("200", "-fx-font-weight:200;"), createStyledText("300", "-fx-font-weight:300;"),
textInlineStyle("100", "-fx-font-weight:100;") createStyledText("200", "-fx-font-weight:200;"),
createStyledText("100", "-fx-font-weight:100;")
); );
sample2.setAlignment(Pos.BASELINE_LEFT); sample2.setAlignment(Pos.BASELINE_LEFT);
var sample3 = new HBox(10, var sample3 = new HBox(
textInlineStyle("900", "-fx-font-family:'Inter Black';"), BLOCK_HGAP,
textInlineStyle("800", "-fx-font-family:'Inter Extra Bold';"), createStyledText("900", "-fx-font-family:'Inter Black';"),
textInlineStyle("700", "-fx-font-family:'Inter Bold';"), createStyledText("800", "-fx-font-family:'Inter Extra Bold';"),
textInlineStyle("600", "-fx-font-family:'Inter Semi Bold';"), createStyledText("700", "-fx-font-family:'Inter Bold';"),
textInlineStyle("500", "-fx-font-family:'Inter Medium';"), createStyledText("600", "-fx-font-family:'Inter Semi Bold';"),
textInlineStyle("400", "-fx-font-family:'Inter Regular';"), createStyledText("500", "-fx-font-family:'Inter Medium';"),
textInlineStyle("300", "-fx-font-family:'Inter Light';"), createStyledText("400", "-fx-font-family:'Inter Regular';"),
textInlineStyle("200", "-fx-font-family:'Inter Extra Light';"), createStyledText("300", "-fx-font-family:'Inter Light';"),
textInlineStyle("100", "-fx-font-family:'Inter Thin';") createStyledText("200", "-fx-font-family:'Inter Extra Light';"),
createStyledText("100", "-fx-font-family:'Inter Thin';")
); );
sample3.setAlignment(Pos.BASELINE_LEFT); sample3.setAlignment(Pos.BASELINE_LEFT);
// JDK-8090423: https://bugs.openjdk.org/browse/JDK-8090423 // JDK-8090423: https://bugs.openjdk.org/browse/JDK-8090423
// Workaround: https://edencoding.com/resources/css_properties/fx-font-weight/ // Workaround: https://edencoding.com/resources/css_properties/fx-font-weight/
return new SampleBlock("Font weight", new VBox(10, return new SampleBlock("Font Weight", new VBox(
BLOCK_VGAP,
sample1, sample1,
sample2, sample2,
sample3, sample3,
text("JavaFX only supports Bold or Regular font weight. See the source code for workaround.", createText("JavaFX only supports Bold or Regular font weight. See the source code for workaround.", TEXT, WARNING)
TEXT, TEXT_SMALL, DANGER
)
)); ));
} }
private SampleBlock fontStyleSample() { private SampleBlock fontStyleSample() {
var box = new HBox(10, var box = new FlowPane(
text("Italic", TEXT_ITALIC), BLOCK_HGAP, BLOCK_VGAP,
text("Oblique", TEXT_OBLIQUE), createText("Italic", TEXT_ITALIC),
text("Underlined", TEXT_UNDERLINED), createText("Oblique", TEXT_OBLIQUE),
text("Strikethrough", TEXT_STRIKETHROUGH) createText("Underlined", TEXT_UNDERLINED),
createText("Strikethrough", TEXT_STRIKETHROUGH)
); );
box.setAlignment(Pos.BASELINE_LEFT); box.setAlignment(Pos.BASELINE_LEFT);
return new SampleBlock("Font style", box); return new SampleBlock("Font Style", box);
} }
private SampleBlock textColorSample() { private SampleBlock textColorSample() {
var box = new HBox(10, var box = new FlowPane(
text("Accent", TEXT, ACCENT), BLOCK_HGAP, BLOCK_VGAP,
text("Success", TEXT, SUCCESS), createText("Accent", TEXT, ACCENT),
text("Warning", TEXT, WARNING), createText("Success", TEXT, SUCCESS),
text("Danger", TEXT, DANGER) createText("Warning", TEXT, WARNING),
createText("Danger", TEXT, DANGER)
); );
box.setAlignment(Pos.BASELINE_LEFT); box.setAlignment(Pos.BASELINE_LEFT);
return new SampleBlock("Text color", box); return new SampleBlock("Text Color", box);
} }
private SampleBlock hyperlinkSample() { private SampleBlock hyperlinkSample() {
var linkNormal = hyperlink("_Normal", false, false); var linkNormal = createHyperlink("_Normal", false, false);
linkNormal.setMnemonicParsing(true); linkNormal.setMnemonicParsing(true);
var linkVisited = hyperlink("_Visited", true, false); var linkVisited = createHyperlink("_Visited", true, false);
linkVisited.setMnemonicParsing(true); linkVisited.setMnemonicParsing(true);
var linkBroken = hyperlink("_Broken", true, false); var linkBroken = createHyperlink("_Broken", true, false);
linkBroken.setStyle("-color-link-fg-visited:-color-danger-fg;"); linkBroken.setStyle("-color-link-fg-visited:-color-danger-fg;");
linkBroken.setMnemonicParsing(true); linkBroken.setMnemonicParsing(true);
var box = new HBox(10, var box = new FlowPane(
BLOCK_HGAP, BLOCK_VGAP,
linkNormal, linkNormal,
linkVisited, linkVisited,
linkBroken, linkBroken,
hyperlink("Disabled", false, true) createHyperlink("Disabled", false, true)
); );
box.setAlignment(Pos.BASELINE_LEFT); box.setAlignment(Pos.BASELINE_LEFT);
return new SampleBlock("Hyperlink", box); return new SampleBlock("Hyperlink", box);
} }
private Text text(String text, String... styleClasses) {
var t = new Text(text);
t.getStyleClass().addAll(styleClasses);
t.setUserData(text);
return t;
}
private Text textInlineStyle(String text, String style) {
var t = new Text(text);
t.setStyle(style);
return t;
}
private Hyperlink hyperlink(String text, boolean visited, boolean disabled) {
var h = new Hyperlink(text);
h.setVisited(visited);
h.setDisable(disabled);
return h;
}
private SampleBlock textFlowSample() { private SampleBlock textFlowSample() {
var textFlow = new TextFlow( var textFlow = new TextFlow(
new Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. "), new Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. "),
@ -303,6 +295,32 @@ public class TypographyPage extends AbstractPage {
new Text(".") new Text(".")
); );
return new SampleBlock("Text flow", textFlow); return new SampleBlock("Text Flow", textFlow);
}
private Text createText(String text, String... styleClasses) {
var t = new Text(text);
t.getStyleClass().addAll(styleClasses);
t.setUserData(text);
return t;
}
private Text createStyledText(String text, String style) {
var t = new Text(text);
t.setStyle(style);
return t;
}
private Label createFontSizeLabel() {
var label = new Label();
label.setPadding(new Insets(5, 40, 5, 10));
return label;
}
private Hyperlink createHyperlink(String text, boolean visited, boolean disabled) {
var h = new Hyperlink(text);
h.setVisited(visited);
h.setDisable(disabled);
return h;
} }
} }

@ -1,7 +1,7 @@
package atlantafx.sampler.page.showcase; package atlantafx.sampler.page.showcase;
import atlantafx.base.controls.Spacer;
import atlantafx.sampler.page.AbstractPage; import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.util.NodeUtils;
import javafx.css.PseudoClass; import javafx.css.PseudoClass;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@ -41,30 +41,25 @@ public abstract class ShowcasePage extends AbstractPage {
expandBtn.setOnAction(e -> { expandBtn.setOnAction(e -> {
expandBtn.getScene().getRoot().pseudoClassStateChanged(SHOWCASE_MODE, true); expandBtn.getScene().getRoot().pseudoClassStateChanged(SHOWCASE_MODE, true);
VBox.setVgrow(showcase, Priority.ALWAYS); VBox.setVgrow(showcase, Priority.ALWAYS);
expandBox.setVisible(false); NodeUtils.toggleVisibility(expandBox, false);
expandBox.setManaged(false); NodeUtils.toggleVisibility(collapseBox, true);
collapseBox.setVisible(true);
collapseBox.setManaged(true);
}); });
expandBox.getChildren().setAll(new Spacer(), expandBtn, new Spacer()); expandBox.getChildren().setAll(expandBtn);
expandBox.setAlignment(Pos.CENTER_LEFT); expandBox.setAlignment(Pos.CENTER);
var collapseBtn = new Hyperlink("Exit showcase mode"); var collapseBtn = new Hyperlink("Exit showcase mode");
collapseBtn.setOnAction(e -> { collapseBtn.setOnAction(e -> {
expandBtn.getScene().getRoot().pseudoClassStateChanged(SHOWCASE_MODE, false); expandBtn.getScene().getRoot().pseudoClassStateChanged(SHOWCASE_MODE, false);
VBox.setVgrow(showcase, Priority.NEVER); VBox.setVgrow(showcase, Priority.NEVER);
expandBox.setVisible(true); NodeUtils.toggleVisibility(expandBox, true);
expandBox.setManaged(true); NodeUtils.toggleVisibility(collapseBox, false);
collapseBox.setVisible(false);
collapseBox.setManaged(false);
}); });
collapseBox.getChildren().setAll(new FontIcon(Feather.MINIMIZE_2), collapseBtn); collapseBox.getChildren().setAll(new FontIcon(Feather.MINIMIZE_2), collapseBtn);
collapseBox.setAlignment(Pos.CENTER_LEFT); collapseBox.setAlignment(Pos.CENTER_LEFT);
collapseBox.setPadding(new Insets(5)); collapseBox.setPadding(new Insets(5));
collapseBox.setVisible(false); NodeUtils.toggleVisibility(collapseBox, false);
collapseBox.setManaged(false);
userContent.getChildren().setAll(showcase, expandBox, collapseBox); setUserContent(new VBox(showcase, expandBox, collapseBox));
} }
@SuppressWarnings("SameParameterValue") @SuppressWarnings("SameParameterValue")

@ -85,7 +85,7 @@ final class PlayerPane extends VBox {
trackAlbum.setAlignment(CENTER); trackAlbum.setAlignment(CENTER);
trackAlbum.setMaxWidth(MAX_VALUE); trackAlbum.setMaxWidth(MAX_VALUE);
// == Media controls == // == MEDIA CONTROLS ==
var prevBtn = new Button("", new FontIcon(FAST_REWIND)); var prevBtn = new Button("", new FontIcon(FAST_REWIND));
prevBtn.getStyleClass().addAll(BUTTON_CIRCLE); prevBtn.getStyleClass().addAll(BUTTON_CIRCLE);
@ -112,7 +112,7 @@ final class PlayerPane extends VBox {
mediaControls.getChildren().setAll(prevBtn, playBtn, nextBtn); mediaControls.getChildren().setAll(prevBtn, playBtn, nextBtn);
mediaControls.setAlignment(CENTER); mediaControls.setAlignment(CENTER);
// == Time controls == // == TIME CONTROLS ==
timeSlider = new Slider(0, 1, 0); timeSlider = new Slider(0, 1, 0);
timeSlider.getStyleClass().add("time-slider"); timeSlider.getStyleClass().add("time-slider");
@ -129,7 +129,7 @@ final class PlayerPane extends VBox {
timeMarkersBox.getChildren().setAll(currentTimeLabel, new Spacer(), endTimeLabel); timeMarkersBox.getChildren().setAll(currentTimeLabel, new Spacer(), endTimeLabel);
timeMarkersBox.setMaxWidth(PANEL_MAX_WIDTH); timeMarkersBox.setMaxWidth(PANEL_MAX_WIDTH);
// == Extra controls == // == EXTRA CONTROLS ==
var clearPlaylistBtn = new Button("", new FontIcon(CLEAR_ALL)); var clearPlaylistBtn = new Button("", new FontIcon(CLEAR_ALL));
clearPlaylistBtn.getStyleClass().addAll(BUTTON_CIRCLE); clearPlaylistBtn.getStyleClass().addAll(BUTTON_CIRCLE);

@ -23,10 +23,12 @@
.page { .page {
>.scroll-pane>.viewport>*>.wrapper>.user-content { >.scroll-pane .user-content {
-fx-max-width: 4096px;
-fx-padding: 0; -fx-padding: 0;
-fx-spacing: 0;
>* {
-fx-max-width: 4096px;
}
} }
.about { .about {

@ -1,17 +0,0 @@
// SPDX-License-Identifier: MIT
.sample-block {
-fx-spacing: 1em;
>.title {
-fx-font-weight: bold;
}
}
.popover .date-picker-popup {
-color-date-border: transparent;
-color-date-bg: transparent;
-color-date-day-bg: transparent;
-color-date-month-year-bg: transparent;
-color-date-day-bg-hover: -color-bg-subtle;
}

@ -3,4 +3,3 @@
@use "main"; @use "main";
@use "overlay"; @use "overlay";
@use "page"; @use "page";
@use "components";

@ -1,19 +1,34 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
.page { .page {
>.scroll-pane { >.scroll-pane {
-fx-background-color: -color-bg-default; -fx-background-color: -color-bg-default;
>.viewport>*>.wrapper { // stack pane to center user content
-fx-min-width: 880px; .user-content {
-fx-alignment: TOP_CENTER; -fx-padding: 40px 0 40px 0; // vertical paddings
-fx-min-width: 860px; // horizontal paddings
>.user-content { >* {
-fx-padding: 40px 0 40px 0; // limit user content width
-fx-spacing: 40px; -fx-min-width: 800px;
-fx-max-width: 800px; -fx-max-width: 800px;
} }
} }
} }
} }
.sample-block {
-fx-background-color: -color-bg-default;
-fx-effect: dropshadow(gaussian, -color-shadow-default, 10, 0.4, 0, 0);
-fx-border-color: -color-border-muted;
-fx-border-width: 1px;
-fx-padding: 1em 1.5em 1.5em 1.5em;
-fx-spacing: 1em;
-fx-min-width: 220px;
>.title {
-fx-font-weight: bold;
-fx-padding: 0 0 10px 0;
}
}