How to add Scroll Pane into tabs - javafx-2

I have this simple example of JavaFX tabs
primaryStage.setTitle("Tabs Test");
Group root = new Group();
Scene scene = new Scene(root, 600, 500, Color.WHITE);
TabPane tabPane = new TabPane();
BorderPane mainPane = new BorderPane();
//Create Tabs
Tab tabA = new Tab();
tabA.setText("Main Component");
//Add something in Tab
StackPane tabA_stack = new StackPane();
tabA_stack.setAlignment(Pos.CENTER);
tabA_stack.getChildren().add(new Label("Label#Tab B"));
tabA.setContent(tabA_stack);
tabPane.getTabs().add(tabA);
Tab tabB = new Tab();
tabB.setText("Second Component");
//Add something in Tab
StackPane tabB_stack = new StackPane();
tabB_stack.setAlignment(Pos.CENTER);
tabB_stack.getChildren().add(new Label("Label#Tab B"));
tabB.setContent(tabB_stack);
tabPane.getTabs().add(tabB);
Tab tabC = new Tab();
tabC.setText("Last Component");
//Add something in Tab
StackPane tabC_vBox = new StackPane();
tabC_vBox.setAlignment(Pos.CENTER);
tabC_vBox.getChildren().add(new Label("Label#Tab C"));
tabC.setContent(tabC_vBox);
tabPane.getTabs().add(tabC);
mainPane.setCenter(tabPane);
mainPane.prefHeightProperty().bind(scene.heightProperty());
mainPane.prefWidthProperty().bind(scene.widthProperty());
root.getChildren().add(mainPane);
primaryStage.setScene(scene);
primaryStage.show();
How I can add horizontal and vertical scroll Pane into the tab's body. I want to display the scroll pane only when the data is bigger than the visible area. Is this possible?

Instead of setting contents of tabs to StackPane, call setContent method with ScrollPane object, and set the content of this ScrollPane to the corresponding StackPane.

Creating a basic javafx.scene.control.ScrollPane is easy, an example can be found in the JavaDoc. Here's the code that places a ScrollPane in your first Tab:
...
final Rectangle rect = new Rectangle(200, 200, 800, 600);
rect.setFill(Color.RED);
final ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(rect);
tabA.setContent(scrollPane);
tabPane.getTabs().add(tabA);
...
You can find a lot of useful examples in the JavaFX tutorials, too.

Related

How to make an OS X menubar in JavaFX

I'm unable to make a JavaFX MenuBar show as a standard OS X menu bar, at the top of the screen.
Here's what I've tried in my subclass of Application:
public void start(Stage primaryStage) throws Exception {
final Menu menu1 = new Menu("File");
final Menu menu2 = new Menu("Options");
final Menu menu3 = new Menu("Help");
MenuBar menuBar = new MenuBar();
menuBar.getMenus().addAll(menu1, menu2, menu3);
menuBar.setUseSystemMenuBar(true);
primaryStage.setTitle("Creating Menus with JavaFX 2.0");
final Group rootGroup = new Group();
final Scene scene = new Scene(rootGroup, 800, 400, Color.WHEAT);
rootGroup.getChildren().add(menuBar);
primaryStage.setScene(scene);
primaryStage.show();
}
I assumed that the use of
menuBar.setUseSystemMenuBar(true);
would do the trick, but actually it makes the menuBar disappear altogether.
I'm using Java 1.8.0-b132 on OS X 10.9
I've had success with this code:
MenuBar menuBar = new MenuBar();
final String os = System.getProperty("os.name");
if (os != null && os.startsWith("Mac"))
menuBar.useSystemMenuBarProperty().set(true);
BorderPane borderPane = new BorderPane();
borderPane.setTop(menuBar);
primaryStage.setScene(new Scene(borderPane));
It looks like OS X only displays the Menus if they have MenuItems inside them (which is a bit weird, as you can attach functionality to empty Menus).
I created a little project that gives you access to the auto-generated menu bar on OS X: NSMenuFX
Update: With the new pure JavaFX version, the API has slightly changed
It allows you to replace the default Mac OS menu bar items, so you can to something like this:
// Get the toolkit
MenuToolkit tk = MenuToolkit.toolkit();
// Create default application menu with app name "test"
Menu defaultApplicationMenu = tk.createDefaultApplicationMenu("test");
// Replace the autogenerated application menu
tk.setApplicationMenu(defaultApplicationMenu);
// Since we now have a reference to the menu, we can rename items
defaultApplicationMenu.getItems().get(1).setText("Hide all the otters");
You can of course also add new menu items as you do in your example above.
I just ran into this issue myself - I noticed that the system menubar wouldn't initially appear in OSX until I switched to another application and back.
Wrapping the setUseSystemMenuBar call in a runLater did the trick, so I unscientifically concluded there's more window setup required before OSX can successfully register an application menu.
Platform.runLater(() -> menuBar.setUseSystemMenuBar(true));
Credits to this tutorial that I have followed with success:
https://blog.codecentric.de/en/2015/04/tweaking-the-menu-bar-of-javafx-8-applications-on-os-x/
Below I paste the most important part to get an OS X menu bar compatible with Win classic menu bar:
#Override
public void start(Stage primaryStage) throws Exception {
MenuBar menuBar = new MenuBar();
menuBar.useSystemMenuBarProperty().set(true);
Menu menu = new Menu("java");
MenuItem item = new MenuItem("Test");
menu.getItems().add(item);
menuBar.getMenus().add(menu);
primaryStage.setScene(new Scene(new Pane(menuBar)));
primaryStage.show();
}
Building on dmolony with some corrections:
MenuBar menuBar = new MenuBar ();
if( System.getProperty("os.name","UNKNOWN").equals("Mac OS X")) {
menuBar.setUseSystemMenuBar(true);
}
BorderPane borderPane = new BorderPane ();
borderPane.setTop (menuBar);
primaryStage.setScene (new Scene (borderPane));

Gridpane positioning in Java Fx

I am new to Java Fx using Netbeans 7.3.1.I am experimenting new things with Gridpane and I just want to place a Gridpane in a another position other than the left topmost position of the window..The root.getChildren().add(gridpane); adds the gridpane to the topmost left corner of the window.. How can i place the Gridpane on another place of the window without adding any new child or root!!My root is just a group and the current code just overlaps the gridpane with the Menubar.. My full code is this!!
public class Menu extends Application {
#Override
public void start(Stage primaryStage){
Group root = new Group();
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
MenuBar menuBar = new MenuBar();
javafx.scene.control.Menu m = new javafx.scene.control.Menu("File");
m.getItems().add(new MenuItem("New"));
m.getItems().add(new SeparatorMenuItem());
m.getItems().add(new MenuItem("Exit"));
menuBar.getMenus().add(m);
javafx.scene.control.Menu tools = new javafx.scene.control.Menu("Cameras");
tools.getItems().add(CheckMenuItemBuilder.create()
.text("Show Camera 1")
.selected(false)
.build());
menuBar.getMenus().add(tools);
root.getChildren().add(menuBar);
GridPane gridpane = new GridPane();
gridpane.setPadding(new Insets(5));
gridpane.setHgap(5);
gridpane.setVgap(5);
Label fNameLbl = new Label("First Name");
TextField fNameFld = new TextField();
Label lNameLbl = new Label("First Name");
TextField lNameFld = new TextField();
Button saveButt = new Button("Save");
// First name label
GridPane.setHalignment(fNameLbl, HPos.RIGHT);
gridpane.add(fNameLbl, 0, 0);
// Last name label
GridPane.setHalignment(lNameLbl, HPos.RIGHT);
gridpane.add(lNameLbl, 0, 1);
// First name field
GridPane.setHalignment(fNameFld, HPos.LEFT);
gridpane.add(fNameFld, 1, 0);
// Last name field
GridPane.setHalignment(lNameFld, HPos.LEFT);
gridpane.add(lNameFld, 1, 1);
// Save button
GridPane.setHalignment(saveButt, HPos.RIGHT);
gridpane.add(saveButt, 1, 2);
root.getChildren().add(gridpane);
primaryStage.setScene(scene);
primaryStage.show();
}
try Scene Builder...it is used for designing javafx pages...
you can design all your pages according you need.
I'm not sure if it works but try using the following:
grid.setAlignment(Pos.CENTER);
Centre can be replaced with any other position as far as I am aware. I hope this helps somewhat.

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);

Always show vertical scrollbar for JavaFX ListView

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();
}

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());

Resources