I'm trying to build a message window with App Bar on the top
This screen consist of Gluon App Bar on the top and VBox in bottom which has rest of the element shown in the screen.
Issue is when i click on the text area to enter text the App Bar goes out of scope.
Is there a way I can set App Bar to be always on top?
If you are deploying your app on Android, the TextField and TextArea controls include a built-in check: when those input controls get focused, if required the scene is moved up to prevent the software keyboard from hiding the control.
These translation affects the whole scene, so all the nodes in it (View, VBox, TextField, TextArea, AppBar, ...), will be translated as well.
So if you want to keep the AppBar node always visible and in the same top position, a possible fix could be counteracting that translation whenever it happens.
If you have a BasicView for instance (Gluon IDE plugin -> single view project), with a TextField control at the bottom of the view:
public BasicView() {
Label label = new Label("Hello JavaFX World!");
Button button = new Button("Change the World!");
button.setGraphic(new Icon(MaterialDesignIcon.LANGUAGE));
button.setOnAction(e -> label.setText("Hello JavaFX Universe!"));
VBox controls = new VBox(15.0, label, button, new TextField());
controls.setAlignment(Pos.BOTTOM_CENTER);
controls.setPadding(new Insets(20));
setCenter(controls);
}
you can modify it like this:
public BasicView() {
...
setOnShown(e -> {
MobileApplication.getInstance().getAppBar().translateYProperty()
.bind(controls.getScene().getRoot().translateYProperty().multiply(-1));
});
}
Make sure that the view is already added to the scene when you add this binding (to prevent a NPE).
Now when the textfield gets the focus, the whole scene will be moved up, and the appBar will be moved down the same amount:
Related
Summary
I would like to have more control over the Text rendering on a Button in Xamarin.Forms, so I am using a Grid which contains a Label and Button object. This gives me more control over the text, but it has the side effect of the Label being moved behind the Button when the Button is clicked.
Why does this happen? Shouldn't the ordering of UI be determined by the order in which the children are added to the Grid's Children?
Details
I have created the following code to test the problem in isolation:
// The grid can be added directly to a page
var grid = new Grid();
grid.Margin = new Thickness(100, 100);
grid.WidthRequest = 200;
grid.HeightRequest = 200;
var button = new Button();
button.WidthRequest = 80;
button.HorizontalOptions = LayoutOptions.Start;
button.VerticalOptions = LayoutOptions.Fill;
grid.Children.Add(button);
var label = new Label();
label.Text = "This is some text";
label.VerticalOptions = LayoutOptions.Fill;
label.InputTransparent = true;
grid.Children.Add(label);
The button is sized so that it only overlaps part of the text so that it is clear that the button moves in front of the Label.
Before tapping on the button, this is how the layout appears:
After tapping, the button moves in front of the label as shown in the following image:
I could make the Text have a tap gesture, but then the button wouldn't play its native effect when touched, so I'd like to keep that functionality by clicking on the button.
Is there a way to keep the label in front of the button after a click?
Edit
This has been tested on a Motorola Moto G7 running Android 10 and on an emulator running Android version 9.
Note that on the Android hardware the label remains behind the button permanently. On the emulator the label moves behind the button when the button is pushed, but then re-appears on top after the button is released.
I had done a demo and reappeared the problem. The issue will happend because of the fast renderers. Add the code 'Forms.SetFlags("UseLegacyRenderers");' to your MainActivity class before calling Forms.Init. Such as
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Forms.SetFlags("UseLegacyRenderers");
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
I thought this bug was supposed to be fixed a long time ago... but when I place a ComboBox near the bottom of a window it expands downward and off the screen. I think the reason it does this is because there are other controls above it, so rather than "bump" into those it just expands downward instead. Why doesn't the combo box expand over the the rest of the layout? All I know is that when I add some padding above it, it will expand upward instead of downward.
Example:
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
ObservableList<String> choiceList = FXCollections.observableArrayList();
choiceList.addAll("Choice1", "Choice2", "Choice3", "Choice4");
ComboBox<String> choices = new ComboBox<>(choiceList);
choices.setMinWidth(100);
Button button1 = new Button("First Button");
button1.setMinWidth(150);
Button button2 = new Button("Second Button");
button2.setMinWidth(150);
VBox layout = new VBox(10);
layout.setPadding(new Insets(10, 10, 10, 10));
layout.getChildren().addAll(button1, button2, choices);
Scene scene = new Scene(layout);
primaryStage.setScene(scene);
primaryStage.setTitle("Example");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Image of window displayed by the above code
Anybody got a fix for this?
Note, if in your case, you are moving your main application window to the bottom of the screen and the combo box is still dropping down and being cut off so that some contents of the popup are not visible, then it may well be a bug. But my guess is, that if that is what is happing, that it is a system specific issue as I cannot replicate such an issue on OS X. If that is the case, try a Java 9 early access release and see if the issue still replicates, and if it does you could file a bug report.
This is not bug, it is by design.
The ComboBox popup is internally implemented as a PopupControl. A PopupControl is a new window, which isn't constrained to lie within the bounds of its parent window (your main stage). JavaFX has logic to ensure that popups such as the ContextMenus and ComboBox popups are shown within the visible screen area, not the owning stage area.
If you move your main application towards the top of the screen, then open the combo box popup, the popup will drop down because there is room on the screen to display it. But if you move the main application towards the bottom of the screen, then the open the combo box popup, the popup will drop up (I don't know a better way to explain that concept ;-) because there is no room to display the popup if it were to drop down.
Drop up sample. Created by running your example code on OS X, moving the main application window near the bottom of the screen and opening the combo box popup.
Is there any way I can have an event that only triggers if I click the Title of a TitledPane?
I have several Nodes in a Graph Editor and currently they are draggable.
But I want them only to drag when i drag the Title not if I click anywhere on the pane.
the mouseClick event seems not to work for me.
Does anyone have suggestions?
Don't set the text on the titled pane, but instead create a label and set it as the graphic for the titled pane. Then you can register a mouse handler with the label:
private TitledPane createClickableTitledPane(String text) {
Label label = new Label(text);
label.setOnMouseClicked(e -> System.out.println("Click on "+text));
TitledPane titledPane = new TitledPane();
titledPane.setGraphic(label);
return titledPane ;
}
StackPane titleRegion = (StackPane) titledPane.lookup(".title");
titleRegion.setOnMouseClicked(System.out::println);
EDIT:
Sometimes titledPane.lookup(".title") returns null which means CSS is not applied to the node. To resolve this issue, you need to use applyCss() and layout() on the pane that contains the TitledPane.
See:
JavaFX TitledPane lookup(.title) returns null
I want to make a button on an AnchorPane without drag it from the library in the FXML file I want to do it progammatically: if the search button clicked, should show a new button not existed in the AnchorPane before I did this code but I don't know what is wrong with it:
private void searchButton(ActionEvent evt) {
Button tab = new Button();
tab.setLayoutX(147);
tab.setLayoutY(102);
tab.setText("Tab1");
tab.setPrefHeight(27);
tab.setPrefWidth(69);
WebView wb = new WebView();
wb.setLayoutX(-1);
wb.setLayoutY(128);
wb.setPrefWidth(1604);
wb.setPrefWidth(700);
}
I am assuming that you searchButton method is in controller attached to some FXML. Then all you need to do is this:
yourAnchorPane.getChildren().add(tab);
If you don't have already published reference to anchorPane in your controller, then add this into your controller
#FXML
AnchorPane yourAnchorPane;
And in SceneBuilder select your anchorPane, go to code tab and enter "yourAnchorPane" as fx:id.
Further info on working with anchorpane is javadoc.
You probably also want to set some constraints on the tab to locate it at a position within the AnchorPane. For instance, the following code will locate your button tab relative to the top left corner of the AnchorPane: Ten pixels down and fifteen pixels to the right.
AnchorPane.setTopAnchor(tab, 10.0);
AnchorPane.setLeftAnchor(tab, 15.0);
Simply put I only show buttons when I am hovered on the AnchorPane. I wanted a tooltip for a button, but when the mouse hovers on the tooltip this causes me to leave the anchorpane and everything disappears.
Any ideas? Using the stage for hovering to show or not doesn't seem to ever cause the buttons to hide.
//this is an AnchorPane
this.addEventHandler(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent>(){
#Override
public void handle(MouseEvent event) {
//Doesn't help: if(!micTooltip.isShowing() && !screenTooltip.isShowing())
showButtons(false);
}
});
similarly the mouse entered shows the buttons. And a tooltip is bound to the buttons.
Try this:
ObservableBooleanValue hover = this.hoverProperty()
.or(micTooltip.getScene().getRoot().hoverProperty())
.or(screenTooltip.getScene().getRoot().hoverProperty());
hover.addListener((obs, wasHovering, isNowHovering) -> showButtons(isNowHovering));
Depending on the exact behavior you need, you might want
hover = this.hoverProperty().or(micTooltip.showingProperty()) ;
etc
You might also find it more convenient to use bindings instead of the listener:
this.getChildren().forEach(button -> button.visibleProperty().bind(hover));
(assuming you want all contents of the anchor pane to appear and disappear on mouseover/out; this line needs to be called after you add the content, obviously).