Always show vertical scrollbar for JavaFX ListView - javafx-2

ListView appears to already have a scrollbar. I want the scrollbar to always be visible. The reason is because I'm putting a header on it and a button in the corner between the scrollbar and header. How can I get the ListView scrollbar to always display?

you could put it into a properly sized ScrollPane and set the vbar policy of the ScrollPane to ALWAYS:
#Override
public void start(Stage primaryStage) throws Exception {
ScrollPane pane = new ScrollPane();
ListView<String> list = new ListView<String>();
ObservableList<String> items = FXCollections.observableArrayList(
"Single", "Double", "Suite", "Family App");
list.setItems(items);
pane.prefWidthProperty().bind(list.widthProperty());
pane.prefHeightProperty().bind(list.heightProperty());
pane.setContent(list);
pane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
Group group = new Group();
group.getChildren().add(pane);
Scene scene = new Scene(group, 500, 500);
primaryStage.setScene(scene);
primaryStage.show();
}

Related

Add fixed positioned layer to FlowPane [duplicate]

This question already has answers here:
Add fixed positioned Combobox inside FlowPane
(2 answers)
Closed 9 years ago.
I have a FlowPane with panels which will be used to display data in front of the user.
![enter image description here][1]
I added also scrollpane when the number of the panels is bigger than the visible area.
I also want to add filter which will sort the panels by type and will display only the appropriate. The red area will hold the ComboBox which will be the filter.
And as you can see the red are pushes down the FlowPane which will make a gap between the top component and the scroll when I make the area transparent.
Is there a way to use the z-index and place the red are in front of the FlowPane? Or some other solution?
This is the result that I would like to get:
![enter image description here][2]
Investigate this example based on your code in previous questions:
public class Demo extends Application {
#Override
public void start(Stage stage) throws Exception {
StackPane stackPane = new StackPane();
stackPane.setAlignment(Pos.TOP_LEFT);
stackPane.getChildren().addAll(infrastructurePane(), getFilterPane());
Scene scene = new Scene(stackPane);
stage.setScene(scene);
stage.show();
}
public Pane getFilterPane() {
ObservableList<String> options =
FXCollections.observableArrayList(
"Option 1", "Option 2", "Option 3");
ComboBox<String> combo = new ComboBox<String>(options);
HBox pane = new HBox();
pane.setPadding(new Insets(20));
pane.setStyle("-fx-background-color: rgba(255,0,85,0.4)");
pane.getChildren().add(combo);
pane.setMaxHeight(40);
// Optional
//pane.setEffect(new DropShadow(15, Color.RED));
return pane;
}
public ScrollPane infrastructurePane() {
final FlowPane flow = new FlowPane();
flow.setPadding(new Insets(5, 5, 5, 5));
flow.setVgap(5);
flow.setHgap(5);
flow.setAlignment(Pos.CENTER);
final ScrollPane scroll = new ScrollPane();
scroll.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED); // Horizontal scroll bar
scroll.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED); // Vertical scroll bar
scroll.setFitToHeight(true);
scroll.setFitToWidth(true);
scroll.setContent(flow);
// scroll.viewportBoundsProperty().addListener(new ChangeListener<Bounds>() {
// #Override
// public void changed(ObservableValue<? extends Bounds> ov, Bounds oldBounds, Bounds bounds) {
// flow.setPrefWidth(bounds.getWidth());
// flow.setPrefHeight(bounds.getHeight());
// }
// });
//flow.setPrefWrapLength(170); // preferred width allows for two columns
flow.setStyle("-fx-background-color: yellow;");
for (int i = 0; i < 28; i++) {
flow.getChildren().add(generateRectangle());
}
String cssURL = "/com/dx57dc/css/ButtonsDemo.css";
String css = this.getClass().getResource(cssURL).toExternalForm();
flow.getStylesheets().add(css);
return scroll;
}
public Rectangle generateRectangle() {
final Rectangle rect2 = new Rectangle(10, 10, 10, 10);
rect2.setId("app");
rect2.setArcHeight(8);
rect2.setArcWidth(8);
//rect2.setX(10);
//rect2.setY(160);
rect2.setStrokeWidth(1);
rect2.setStroke(Color.WHITE);
rect2.setWidth(220);
rect2.setHeight(180);
rect2.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
rect2.setFill(Color.ALICEBLUE);
}
});
return rect2;
}
public static void main(String[] args) {
launch(args);
}
}
EDIT:
As per comment, here is the combo without pane. Since there is no pane the mouse events will not be blocked. Replace only this method with above one:
public ComboBox getFilterPane() {
ObservableList<String> options =
FXCollections.observableArrayList(
"Option 1", "Option 2", "Option 3");
ComboBox<String> combo = new ComboBox<String>(options);
combo.setTranslateX(10);
combo.setTranslateY(10);
return combo;
}
if you're using JavaFX 8, you can try a Notification Pane from ControlsFX project
It looks like:
It's pretty unclear to get which behaviour you don't want and which one you want.
This sentence "And as you can see the red are pushes down the FlowPane which will make a gap between the top component and the scroll when I make the area transparent." is particularly hard to understand.
But if you just want to "use the z-index and place the red are in front of the FlowPane?", maybe all you're asking for is just a StackPane ?
StackPane lays out its children in a back-to-front stack.
The z-order of the children is defined by the order of the children
list with the 0th child being the bottom and last child on top. If a
border and/or padding have been set, the children will be layed out
within those insets.
http://docs.oracle.com/javafx/2/api/javafx/scene/layout/StackPane.html
If you want the red area be part of the ScrollPane:
Create a VBox
Add The Red Area Component to VBox
Add the FlowPane to VBox
Set VBox as the ScrollPanes Content
If the Layout with VBox's doenst look statisfying try Borderpane and set the "Red Area" top and your flowpane as center.
Is there a way to use the z-index and place the red are in front of the FlowPane? Or some other solution?
see QuidNovi's answer

Set Icon for toggle button

I created Icon with Borderpane, image and text which I want to set as button icon.
#Override
public void start(Stage primaryStage)
{
final VBox vbox = new VBox();
// create 3 toggle buttons and a toogle group for them
ToggleButton tb1 = new ToggleButton();
tb1.setGraphic(newConnectionIcon());
ToggleButton tb2 = new ToggleButton();
ToggleButton tb3 = new ToggleButton();
final ToggleGroup group = new ToggleGroup();
tb1.setToggleGroup(group);
tb2.setToggleGroup(group);
tb3.setToggleGroup(group);
// select the first button to start with
group.selectToggle(tb1);
final Rectangle rect1 = new Rectangle(300, 300);
rect1.setFill(Color.DARKOLIVEGREEN);
final Rectangle rect2 = new Rectangle(300, 300);
rect2.setFill(Color.LAVENDER);
final Rectangle rect3 = new Rectangle(300, 300);
rect3.setFill(Color.LIGHTSLATEGREY);
tb1.setUserData(rect1);
tb2.setUserData(rect2);
tb3.setUserData(rect3);
group.selectedToggleProperty().addListener(new ChangeListener<Toggle>()
{
#Override
public void changed(ObservableValue<? extends Toggle> ov, Toggle toggle, Toggle new_toggle)
{
if (new_toggle == null)
{
}
else
{
vbox.getChildren().set(1, (Node) group.getSelectedToggle().getUserData());
}
}
});
HBox hBox = new HBox();
hBox.getChildren().addAll(tb1, tb2, tb3);
hBox.setPadding(new Insets(10, 10, 10, 10));
vbox.getChildren().addAll(hBox, (Node) group.getSelectedToggle().getUserData());
StackPane root = new StackPane();
root.getChildren().add(vbox);
Scene scene = new Scene(root, 800, 850);
primaryStage.setScene(scene);
primaryStage.show();
}
private static BorderPane newConnectionIcon() {
// Add background effect
DropShadow ds = new DropShadow();
ds.setOffsetY(2.0);
ds.setOffsetX(2.0);
ds.setColor(Color.GRAY);
// New BorderPane which will hold the components
bpi = new BorderPane();
bpi.setEffect(ds); // Add the effect
bpi.setCache(true);
// Set the size of the BorderPane
bpi.setPrefSize(30, 30);
bpi.setMaxSize(30, 30);
// Add style
bpi.setStyle("-fx-background-color: linear-gradient(#f2f2f2, #d4d4d4);"
+ " -fx-background-insets: 0 0 -1 0, 0, 1, 2;"
+ " -fx-background-radius: 3px, 3px, 2px, 1px;");
// Add Label to the Icon
Text inftx = new Text("New Connection");
inftx.setFont(Font.font ("Verdana", 5)); // Set font and font size
inftx.setFill(Color.WHITE); // Set font color
ncpic.setFitHeight(25); // Set size of the Icon picture
ncpic.setFitWidth(25);
// Internal StackPane which will hold the picture and the Icon Label
StackPane stack = new StackPane();
stack.getChildren().addAll(ncpic, inftx); // Add the picture and the Label
// Add the StackPane to the main BorderPane
bpi.setCenter(stack);
// Change the border of the Icon when the mouse is over the Icon
bpi = mouseOver(bpi);
// Navigate to new Panel when the user clicks on the Icon
bpi.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent t) {
}
});
return bpi;
}
How I can remove the default togglebutton and use the my custom icon as a button?
Use Labeled#setGraphic(Node). The ToggleButton is a Labeled and thus has the setGraphic(Node) method defined. Alternatively, you could use a specialized ToogleButton constructor too.
The argument you should pass to setGraphic() is your BorderPane! He is a Node =)
To be uber clear, here is a code snippet for you:
myToogleButton.setGraphic(myBorderPane);

How to set proper alignment in JavaFX

I want to create JavaFX example similar to this dialog:
I created this code:
public void aboutDialogPanel()
{
final Stage aboutDialog = new Stage();
aboutDialog.initModality(Modality.WINDOW_MODAL);
HBox phbox = new HBox();
phbox.setAlignment(Pos.CENTER);
// Image
ImageView iv = new ImageView(getClass().getResource("/images/splash.png").toExternalForm());
phbox.getChildren().add(iv);
HBox hbox = new HBox();
// Text Area
TextArea dataPane = new TextArea();
dataPane.setEditable(false);
dataPane.setLayoutX(160);
dataPane.setLayoutY(160);
hbox.setAlignment(Pos.CENTER);
hbox.setSpacing(1);
hbox.setPadding(new Insets(10, 0, 10, 0));
hbox.getChildren().add(dataPane);
HBox bhbox = new HBox();
// Close Button
Button closeButton = new Button("Close");
closeButton.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent arg0)
{
// Close the dialog when "Close" button is pressed
aboutDialog.close();
}
});
bhbox.setAlignment(Pos.CENTER);
bhbox.setSpacing(10);
bhbox.setPadding(new Insets(10, 10, 10, 10));
bhbox.getChildren().add(closeButton);
BorderPane borderpane = new BorderPane();
borderpane.setTop(phbox);
borderpane.setCenter(hbox);
borderpane.setBottom(bhbox);
// Configure dialog size and background color
Scene aboutDialogScene = new Scene(borderpane, 600, 500, Color.WHITE);
aboutDialog.setScene(aboutDialogScene);
aboutDialog.show();
}
But I cannot reproduce the same alignment similar to to the picture. Can you tell me how I can fix the layout of my code?
UPDATE
This is the visual result:
The text field is always restricted on left and right.
Add the line
dataPane.prefWidthProperty().bind(hbox.widthProperty());

How to align icon and text inside the big button?

I have quite a big button (minWidth and minHeight were explicitly set to big numbers), and inside that big button there is relatively small icon and some text. Icon and text do not consume all available space, and end up being placed in the center of the button.
I want to put icon and text to the left side of the button. But it seems that I do not understand what all those alignments mean, since setting alignment to BASELINE_LEFT or setting textAlignment to LEFT didn't change anything.
How can I fix it?
Property textAlignment controls alignment for multiline text so it wouldn't help you.
But both
btn.setStyle("-fx-alignment: LEFT;");
or
btn.setAlignment(Pos.BASELINE_LEFT);
should work for you. See example below.
public class ILoveBigButtonsAndICannotLie extends Application {
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Button");
btn.setGraphic(new Rectangle(10,10, Color.RED));
btn.setMinHeight(200);
btn.setMinWidth(250);
//btn.setStyle("-fx-alignment: LEFT;");
btn.setAlignment(Pos.BASELINE_LEFT);
StackPane root = new StackPane();
root.getChildren().add(btn);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
public static void main(String[] args) { launch(); }
}

setFocusTraversable behavior on MenuBar in JavaFX 2.0

I have noticed an issue with setFocusTraversable() on MenuBar control. If I call setFocusTraversable(false) on menuBar object the focus traverses (I can see the menubar getting highlighted/selected) to menu when I press Tab from TextField but the event (changed()) does not get fired. If I call setFocusTraversable(true) on menuBar object and press Tab when in TextField the focus does not visually traverses to MenuBar(TextField loses focus) but the event gets fired and additionally the focus can not be set on TextField using Tab or Shift + Tab. I am not sure if this is a bug or problem with my understanding.
Here is the code.
public class MenuTest extends Application
implements ChangeListener
{
MenuBar menuBar = new MenuBar();
TextField tf1 = new TextField("One");
public static void main(String[] args)
{
Application.launch(args);
}
#Override
public void start(Stage primaryStage)
{
Group content = new Group();
BorderPane paneLayout = new BorderPane();
final Menu menu1 = new Menu("File");
menuBar.getMenus().addAll(menu1);
Menu exit = new Menu("Exit");
menu1.getItems().add(exit);
content.getChildren().add(tf1);
paneLayout.setTop(menuBar);
paneLayout.setCenter(content);
Scene scene = new Scene(paneLayout, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
menuBar.setFocusTraversable(false);
menuBar.focusedProperty().addListener(this);
tf1.focusedProperty().addListener(this);
tf1.requestFocus();
}
public void changed(ObservableValue ov, Object t, Object t1)
{
System.out.println("focus gained - " + ov.toString());
}
}
Please help.
Thanks,
KK
PS: MenuBar API explicitly says that "MenuBar sets focusTraversable to false." but behaves differently.
Unfortunately you've met a bug: http://javafx-jira.kenai.com/browse/RT-20595

Resources