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(); }
}
Related
I try to set javafx HTMLEditor to get all free size on the container.
The next is the source code.
public class HtmlEditorTest extends Application {
#Override
public void start(Stage stage) {
stage.setTitle("HTMLEditor Sample");
stage.setWidth(400);
stage.setHeight(300);
final HTMLEditor htmlEditor = new HTMLEditor();
htmlEditor.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
MigPane migPane = new MigPane("fill, debug", "[fill]", "fill");
migPane.add(htmlEditor);
Scene scene = new Scene(migPane);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
If I'll replace HTMLEditor with TextArea I get the expected behaviour. You may see result here
setting htmlEditor.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE)
not solved the problem (based on this answer.
As you may see on the picture I use MigPane in debug mode. And actually the TextArea and HTMLEditor taking the whole container free space. However HTMLEditor text area and scroll bar don't take the free space within HTMLEditor.
How I may fix this problem?
The next addition solved this issue.
WebView webview = (WebView) editor.lookup("WebView");
GridPane.setHgrow(webview, Priority.ALWAYS);
GridPane.setVgrow(webview, Priority.ALWAYS);
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
I've been trying to work with the scaling transform in JavaFX, but haven't quite been able to wrap my head around it. Basically, I have a Pane containing a complex graph and would like to be able to rescale it. The scaling part itself works fine, however, the enclosing scroll pane will not adapt to the graph.
For simplicity's sake, i'll post a short example in which my graph is replaced by a label:
public class TestApp extends Application {
#Override public void start(final Stage stage) throws Exception {
final Label label = new Label("Hello World");
label.getTransforms().setAll(new Scale(0.5, 0.5));
label.setStyle("-fx-background-color:blue");
label.setFont(new Font(200));
final ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(label);
stage.setScene(new Scene(scrollPane));
stage.setWidth(200);
stage.setHeight(100);
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
The label will scale correctly, but the enclosing scroll pane's bars will still accomodate a component of the original size.
I've tried so far:
Playing around with the labels min and pref size
wrapping the label inside a Group (no scrollbars will appear whatsoever)
scaling the enclosing Group rather than the label
What am I missing? What can I do to make the ScrollPane adapt to the content view?
Thanks for your help.
According to the ScrollPane document you might try to wrap a Pane in a Group so the ScrollPane is scroll by visual bound not the actual layout bound.
ScrollPane layout calculations are based on the layoutBounds rather than the
boundsInParent (visual bounds) of the scroll node. If an application wants the
scrolling to be based on the visual bounds of the node (for scaled content etc.),
they need to wrap the scroll node in a Group.
I implemented scaling in a ScrollPane for Graphs and other nodes in
this example of scrollpane viewports, transforms and layout bounds in JavaFX.
The code was implemented when I was first learning JavaFX, so certainly the code could be cleaner and perhaps there are simpler ways to accomplish this (e.g. using a Group as the container for the scaled node as suggested in the ScrollPane documentation).
One key to getting the solution I wanted (ScrollBars only appearing when you are zoomed in and the node is larger than the visible viewport), was this code:
// create a container for the viewable node.
final StackPane nodeContainer = new StackPane();
nodeContainer.getChildren().add(node);
// place the container in the scrollpane and adjust the pane's viewports as required.
final ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(nodeContainer);
scrollPane.viewportBoundsProperty().addListener(
new ChangeListener<Bounds>() {
#Override public void changed(ObservableValue<? extends Bounds> observableValue, Bounds oldBounds, Bounds newBounds) {
nodeContainer.setPrefSize(
Math.max(node.getBoundsInParent().getMaxX(), newBounds.getWidth()),
Math.max(node.getBoundsInParent().getMaxY(), newBounds.getHeight())
);
}
});
...
// adjust the view layout based on the node scalefactor.
final ToggleButton scale = new ToggleButton("Scale");
scale.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent actionEvent) {
if (scale.isSelected()) {
node.setScaleX(3); node.setScaleY(3);
} else {
node.setScaleX(1); node.setScaleY(1);
}
// runlater as we want to size the container after a layout pass has been performed on the scaled node.
Platform.runLater(new Runnable() {
#Override public void run() {
nodeContainer.setPrefSize(
Math.max(nodeContainer.getBoundsInParent().getMaxX(), scrollPane.getViewportBounds().getWidth()),
Math.max(nodeContainer.getBoundsInParent().getMaxY(), scrollPane.getViewportBounds().getHeight())
);
}
});
}
});
i working little bit with the ListView from JavaFx2. I´m running into one issue.
Is it possible to turn off the clipping of the ListCell/ListView?
I add an ImageView that has to be wider than the ListView and JavaFx2 shows automatically a scrollbar.
This my code snipped how i add the ImageView to my List:
list.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
#Override
public ListCell<String> call(ListView<String> param) {
final ListCell<String> blub = new ListCell<String>() {
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item != null) {
StackPane p = new StackPane();
Label label = new Label(item);
p.getChildren().addAll(img, label);
setGraphic(p);
p.setAlignment(Pos.CENTER_LEFT);
}
}
};
blub.setStyle("-fx-background-color:transparent");
return blub;
}
});
Big thanks!
I don't think it's possible.
Maybe try to play with the Skin of the ListView. It seems that the scroll bar are managed in this class. It do not use a scroll pane.
Another solution could be replacing the ListView by a VBox in a ScrollPane.
Finally, you could try to modify img (by the way, where it come from, and what Class is it ?) to only show what you need.
Anyway, I'm interested by the solution you will use.
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