Set Focus on FlowPane in Javafx - javafx

i tried
public void ChangeFocus(Button browse, final FlowPane mFlowPane)
{
browse.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event)
{
if (event.getCode() == KeyCode.TAB)
{
System.out.println("TAB pressed");
mFlowPane.requestFocus();
event.consume(); // do nothing
}
}
});
}
in above code i set one ImageView inside Flowpane but when i press TAB button on my browse button i can't get focus on imageview how can i solve it?

FlowPane is not focustraversable by default. Call mFlowPane.setFocusTraversable(true) to make it part of the traverse story

some more detail to solve it. instead of focusing the flowpane you need to set the focus on whats in the flowpane, for example a textfield:
flowPane.setOnMouseClicked(new EventHandler<MouseEvent>()
{
public void handle(MouseEvent mouseEvent)
{
textfield.requestFocus();
}
});

Related

Function setonkeypress is not working with datepicker

In JavaFX the setOnKeyPressed event is not hitting in datepicker field through the program whereas for other fields its working properly.
It's not hitting,
dateOfBirth.setOnKeyPressed(new EventHandler<KeyEvent>(){
#Override
public void handle(KeyEvent event) {
if (event.getCode() == KeyCode.TAB) {
event.consume();
nationality.requestFocus();
}
}
});
I wanna get to know the reason and solution.

Graphic on TreeItem dissapears on drag and drop

I have this basic code which adds drag and drop functionality to tree views.
The code works just fine, but when one treeitem is dragged, dropped and added over to another treeitem, the graphic on the treeitem in the original treecell dissapears, while the graphic follows the dragged element and is visible in the new treeitem.
See the image for example, the treeitem "Name" has been dragged over to "Column Name" and lost it's graphic. Alltough the new TreeItem under "Column Name" still has it graphics.
The code for adding drag and drop is this:
private void addDragAndDrop(TreeCell<String> treeCell, MainFXMLController mainFXMLController) {
treeCell.setOnDragDetected(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
System.out.println("setOnDragDetected");
Dragboard db = treeCell.startDragAndDrop(TransferMode.ANY);
ClipboardContent content = new ClipboardContent();
content.putString(event.toString());
db.setContent(content);
DRAGGEDSOURCE = treeCell;
DRAGGEDINDEX = (treeCell.getTreeView().getSelectionModel().getSelectedIndex());
}
});
treeCell.setOnDragOver(new EventHandler<DragEvent>() {
//brukeren har dragget det over et element
public void handle(DragEvent event) {
DRAGGEDTARGET = treeCell.getTreeItem();
if (event.getGestureSource() != treeCell
&& event.getDragboard().hasString()) {
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
}
});
treeCell.setOnDragDropped(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
DRAGGEDTARGET.getChildren().add(DRAGGEDSOURCE.getTreeItem());
}
);
}
public void makeTreeViewDragAble(TreeView treeView, MainFXMLController mainFXMLController) {
treeView.setCellFactory(new Callback<TreeView<String>, TreeCell<String>>() {
#Override
public TreeCell<String> call(TreeView<String> stringTreeView) {
TreeCell<String> treeCell = new TreeCell<String>() {
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty && item != null) {
setText(item);
setGraphic(getTreeItem().getGraphic());
} else {
setText(null);
setGraphic(null);
}
}
};
addDragAndDrop(treeCell, mainFXMLController);
treeView.setEditable(true);
return treeCell;
}
});
}
As #James_D and I have concluded on, this is because I am trying to have two instances of the imageView. The solution is to set a new image view on the old item.

JavaFX contextmenu not hiding

I'm trying to show a context menu only when there is something selected in the list view.
So I called hide in its on showing event. However, this is not working. The context menu still shows up. Is this a bug, or not its intended use? Because JavaFX api seems to suggest hide() is suppose to do this.
Anyway this is the code.
ContextMenu menu = new ContextMenu();
menu.setOnShowing(new EventHandler<WindowEvent>() {
#Override
public void handle(final WindowEvent event) {
menu.hide();
}
});
It will probably work if you do
public void handle(final WindowEvent event) {
Platform.runLater(new Runnable() {
#Override
public void run() {
menu.hide();
}
});
}
but that really seems like a horrible hack.
Why not just set the context menu only if something is selected?
final ListView<T> listView = ... ;
final ContextMenu menu = new ContextMenu();
listView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<T>() {
#Override
public void changed(ObservableValue<? extends T> obs, T oldValue, T newValue) {
if (newValue == null) {
listView.setContextMenu(null);
} else {
listView.setContextMenu(menu);
}
}
});
(obviously replace T with whatever type your ListView is displaying).
private ContextMenu menu; private MenuItem deleteItem;
table.setOnContextMenuRequested(new EventHandler<ContextMenuEvent>() {
#Override
public void handle(ContextMenuEvent event) {
if (table.getSelectionModel().getSelectedIndex() != -1) {
deleteItem.setVisible(true);
deleteItem.setText("delete: " + table.getSelectionModel().getSelectedItem().getName());
contextMenu.show(table, event.getScreenX(), event.getScreenY());
} else {
deleteItem.setVisible(false);
}
event.consume();
}
});
primaryStage.getScene().addEventHandler(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) { menu.hide(); }});

setOnMouseEntered and setOnMouseExited foreverloop

I use a PopOver from controlsfx to display detail-data from a TableCell. I use a tableCellFactory to create individual PopOvers. I have a problem with this code:
public class PopupTableCell extends TableCell {
#Override
protected void updateItem(final Object item, boolean empty) {
super.updateItem(item, empty);
if (empty){
setText(null);
} //if
else {
setText(item.toString());
// PopUp Anzeigen.
final PopOver PopUp = new PopOver();
PopUp.setContentNode(new Label(item.toString()));
setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
Point MouseLocation = MouseInfo.getPointerInfo().getLocation();
PopUp.show(PopupTableCell.this, MouseLocation.getX(), MouseLocation.getY());
System.out.println("entered");
}
});
setOnMouseExited(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
System.out.println("exited");
PopUp.hide();
}
});
}
}
When I place the cursor over a cell, it begins firing the entered and the exited events forever (even with a non moving mouse cursor.
How can I achieve the wanted behavior:
Mouse inside table cell -> popover.show()
Mouse leaves table cell -> popover.hide()
This is how I solved the same problem for me.
owner.setOnMouseMoved(evt -> {
if (owner.getLayoutBounds().contains(evt.getX(), evt.getY())) {
if (!popOver.isShowing()) {
popOver.show(owner);
}
}
});
owner.setOnMouseExited(evt -> {
if (owner.getLayoutBounds().contains(evt.getX(), evt.getY())) {
if (!popOver.isShowing())
popOver.show(owner);
} else {
popOver.hide();
}
});

setOnMouseClick JavaFx Region not called

I have a Region-object inside of a Parent for that I want to set the mouseClick-method like this:
item.getNode().setOnMousePressed(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent me) {
// do something
}
});
The item is derived from Parent and is created like this:
public MyItem(Region node) {
init(node);
}
private void init(Node node) {
getChildren().addAll(node);
}
The problem is that my method handle is never called when I add a Region-object. If I add an ImageView-object the click is received.
Any ideas?
Parent usually calculates it's size according to it's children. Empty parent has size 0.
Take a look at the next example. Note that parent size was set manually and "click" output happens only if you click inside pane (red square):
#Override
public void start(Stage stage) throws Exception {
Pane parent = new Pane();
parent.setStyle("-fx-border-color:red;"); // to see pane's size visually
parent.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent t) {
System.out.println("click");
}
});
parent.setPrefSize(100, 100); // set size
stage.setScene(new Scene(new Group(parent),300,300));
stage.show();
}

Resources