I have an application with two menu bars (application menus and administration menus) on the top row and a search box in between them. The first menu bar is left justified with the search box immediately following while the second menu is right justified. This leaves room for additional application menus without moving the administration menus.
I tried an HBox, but can't get the second menu right justfied.
I tried using an AnchorPane and anchoring the application menu to the left and the admin menu to the right. This works fine until you resize it. When the display gets too small to show both menus it starts truncating letters. I want it to wrap the second menu to the next line.
I tried using a FlowPane which works great for getting one to flow under the other when resized, but I can't get the second menu reliable right justified. I tried a trick of putting a listener on the parent width and calculating the hgap to use, but the first time this gets called, the menu bars have a size of 0 and so the hgap is too big for the actual menus. After I resize it once, that trick works beautifully.
Even better would be a menuBar that could flow automatically so that I didn't have to break it up to allow it to wrap around. But if that capability exists, I've been unable to find it.
AFAIK MenuBar does not support wrapping its Menus.
There can be different approaches to achieve the layout you want. One of them at the below.
To align the second admin flowPane to the right, use HBox.setHgrow for flowPane. To align menu bars in flowPane, use flow.setAlignment(Pos.TOP_RIGHT):
#Override
public void start(Stage primaryStage) {
final Menu menu01 = new Menu("App Menu 1");
final Menu menu02 = new Menu("App Menu 2");
final Menu menu1 = new Menu("Admin Menu 1");
final Menu menu2 = new Menu("Admin Menu 2");
final Menu menu3 = new Menu("Admin Menu 3");
MenuBar menuBar0 = new MenuBar();
menuBar0.getMenus().addAll(menu01, menu02);
menuBar0.setMinWidth(220); // do not shrink
MenuBar menuBar1 = new MenuBar();
menuBar1.getMenus().addAll(menu1);
MenuBar menuBar2 = new MenuBar();
menuBar2.getMenus().addAll(menu2);
MenuBar menuBar3 = new MenuBar();
menuBar3.getMenus().addAll(menu3);
FlowPane flow = new FlowPane(Orientation.HORIZONTAL);
// flow.setStyle("-fx-background-color: gray; -fx-border-color: red"); // visual debug
flow.setAlignment(Pos.TOP_RIGHT);
flow.setHgap(0);
flow.getChildren().addAll(menuBar1, menuBar2, menuBar3);
TextField searchField = new TextField();
searchField.setPromptText("Search here..");
// make it unresizable
searchField.setMinWidth(200);
searchField.setMaxWidth(200);
HBox mainBox = new HBox(5);
mainBox.setAlignment(Pos.CENTER_LEFT);
HBox.setHgrow(flow, Priority.ALWAYS);
mainBox.getChildren().addAll(menuBar0, searchField, flow);
mainBox.setStyle("-fx-background-color: lightgray;");
VBox vBox = new VBox(0);
vBox.getChildren().addAll(mainBox, new Button("Demo"));
Scene scene = new Scene(vBox);
primaryStage.setScene(scene);
primaryStage.show();
}
Related
I would like to have a customized Dialog styling, having another background color and a rounded border, as it looks nicer than the gray rectangle that comes by default.
This is partially possible, by styling the Contentpane of the Dialog. The problem is, that the underlying Dialog Style is still there, in which the contentpane is shown. And it seems the Dialog UDID itself cannot be changed, nor can the "Dialog" style be overwritten in the designer nor by code.
Form hi = new Form();
hi.getUnselectedStyle().setBgColor(0xffffff);
Button but = new Button("open dialog");
but.addActionListener(e -> {
Dialog d = new Dialog(BoxLayout.y());
d.setUIID("Container"); // this line has no effect, the outside dialog component is still visible
Style s = d.getContentPane().getUnselectedStyle();
s.setBorder(RoundRectBorder.create());
s.setBgColor(0x00ff00);
s.setBgTransparency(255);
s.setMargin(5, 5, 5, 5); // adding some margin between contentpane and Dailog container, to be more obvious
d.setDisposeWhenPointerOutOfBounds(true);
// title
Label title = new Label();
title.setText("Confirmation");
d.add(title);
// body field with spanlabel info text
SpanLabel bodyLabel = new SpanLabel("Body Text");
d.add(bodyLabel);
// delete button
Button okButton = new Button("Ok");
okButton.addActionListener(e2 -> {
d.dispose();
});
// exit button
Button exitButton = new Button("Cancel");
exitButton.addActionListener(e3 -> {
d.dispose();
});
d.add(GridLayout.encloseIn(2, okButton, exitButton));
d.show();
});
hi.add(but);
hi.show();
In above image, the outermost dark gray is the tinted area outside the dialog. The green is the content pane with the intended rounded border. the light grey in between comes from the Dialog style that I would like to get rid off.
Can this be done?
Short answer: setDialogUIID("Container");
However dialogs are a bit problematic to customize via code, I would strongly recommend styling them via the designer/css as we just didn't design them for hand styling and so you're relying on internal implementation details that might break.
When you invoke getContentPane() on the Dialog you're styling the content pane of the Dialog. Not the Dialog itself so the dialog styling still has the non-transparent background. You can use getDialogStyle() to style the Dialog itself. I'm not sure how well that will work.
I want to add nodes into the TitledPane's header. The only way I found to do it is using setGraphic() method.
The problem of using that way is I cannot place them neatly. Here is what I get:
The Codes
TitledPane tpane = new TitledPane();
tpane.setContent(new Text("Content"));
tpane.setExpanded(false);
Button b = new Button("Delete");
BorderPane box = new BorderPane();
box.setLeft(new Text("1 "));
box.setCenter(new Text("Single Pane"));
box.setRight(b);
AnchorPane par = new AnchorPane(box);
tpane.setGraphic(par);
VBox vbox = new VBox();
vbox.getChildren().add(tpane);
The Goal
I want to put the Delete button to the right, that's why I am using Borderpane. So the BorderPane need to fill the entire of the TitledPane's header width minus the space for small triangle
How can it be done inside setGraphic() method? Or are there any better way to achieve it?
To fix your problem try setting the width of the BorderPane to the width of the scene minus the arrow like this.
TitledPane tpane = new TitledPane();
tpane.setContent(new Text("Content"));
tpane.setExpanded(false);
Button b = new Button("Delete");
BorderPane box = new BorderPane();
box.setLeft(new Text("1 "));
box.setCenter(new Text("Single Pane"));
box.setRight(b);
AnchorPane par = new AnchorPane(box);
tpane.setGraphic(par);
VBox vbox = new VBox();
vbox.getChildren().add(tpane);
box.setPrefWidth(scene.getWidth()-30);//You can adjust the number to fit your needs and change scene to whatever the name of your scene is
I hope this helped
Well, it seems that support for javafx users is not as massive as the mainstream framework.
After some tries by the suggestion from #Austin, I found the way to do what I want, and this is also give dynamic sizing.
box.prefWidthProperty().bind(scene.widthProperty().subtract(35));
TitledPane tpane = new TitledPane();
tpane.setContent(new Text("Content"));
tpane.setExpanded(false);
Button b = new Button("Delete");
BorderPane box = new BorderPane();
box.setLeft(new Text("1 "));
box.setCenter(new Text("Single Pane"));
box.setRight(b);
tpane.setGraphic(box);
box.prefWidthProperty().bind(scene.widthProperty().subtract(35));
VBox vbox = new VBox();
vbox.getChildren().add(tpane);
I have used two scroll bars for controlling brightness and contrast on image after the use i want to reset the scroll bars to their initial value with a button click
I am not getting any links for that to reset scroll bars on button clicks in JavaFX?
The question somewhat unclear. Need explanation of "not getting any links". Some sample code would be helpful. Based on an assumption, try this:
final ScrollBar scrollBar = new ScrollBar();
Button btn = new Button("Reset");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
scrollBar.setValue(scrollBar.getMin());
// Or if you have stored initial value somewhere use it
scrollBar.setValue(myInitialValue);
}
});
First of all, I'm a long time Java/Swing developer. I recently installed JavaFX 2.2 to play around with.
I'm creating a fairly simple app, whose main window has a toolbar on top and content in the rest of the window. The obvious way to accomplish this is to use a BorderPane, and stick a ToolBar into the top section. So far, so good. However, I would like some of the controls in the toolbar to be at the left edge of the window, and some at the right edge. I can find no way to do this. I can put an invisible spacer object into the toolbar, but I only know how to give it a fixed width; it doesn't resize when the window is resized.
So I thought that instead of using a ToolBar object, I'll just use an HBox; it should be equivalent to a horizontally-oriented Swing Box object, right? And the Swing Box class has a createHorizontalGlue() method that inserts an auto-sizing spacer. Well, I can't find an equivalent in the JavaFX HBox class. Is there no simple way to do this?
I figured out how to do it using an HBox instead of a ToolBar to hold the controls; the key is the HBox.setHgrow() method, which allows you to set a spacer object to grow to fill the available space. I still don't know if it's possible to do this with an actual ToolBar instance.
/**
* Creates and populates the Node that serves as the window toolbar.
*
* #return a newly constructed and populated toolbar component
*/
private Node makeToolbar() {
// Auto-sizing spacer
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
// Horizontal box containing toolbar controls
HBox box = new HBox();
box.setPadding(new Insets(8));
box.setAlignment(Pos.CENTER);
box.getChildren().addAll(openButton, spacer, resizeSlider);
// Colored background panel with drop shadow
Pane bgRect = new Pane();
bgRect.setStyle("-fx-background-color: #e0e0e0;");
bgRect.setEffect(DropShadowBuilder.create().width(1).build());
// StackPane to hold box and rectangle
StackPane stack = new StackPane();
stack.getChildren().addAll(bgRect, box);
return stack;
}
i do it this way:
private Node makeFooter(Node left, Node right) {
ToolBar footer = new ToolBar();
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
spacer.setMinWidth(Region.USE_PREF_SIZE);
footer.getItems().addAll(left, spacer, right);
return footer;
}
hope i could help someone
I have top bar, list and bottom bar.
this.setLayout(new BorderLayout());
this.addComponent(BorderLayout.NORTH, bottomBar);
this.addComponent(BorderLayout.CENTER, list);
this.addComponent(BorderLayout.SOUTH, bottomBar);
List is very long. bottomBar and bottomBar is hide. Scrolling is on the full screen.
How to make that scrolling was only for BorderLayout.CENTER. bottomBar and bottomBar will be visible.
Disable the scrollable in the Form. For example do like this,
Form f = new Form();
f.setLayout(new BorderLayout());
f.setScrollable(false);
f.addComponent(BorderLayout.NORTH, new Label("Top bar"));
f.addComponent(BorderLayout.CENTER, list);
f.addComponent(BorderLayout.SOUTH, new Label("Bottom bar"));
f.show();