Start Editing a TableCell on single click instead of double click - javafx

I would like to begin editing cells on my TableView on a single click rather than a double click.
I tried the following, but it does not work.
tableView.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
TablePosition selectedCellPosition = tableView.getFocusModel().getFocusedCell();
if ( selectedCellPosition != null ) {
tableView.edit(selectedCellPosition.getRow(), selectedCellPosition.getTableColumn());
}
}
});
How can I make it so the table cell begins editing on the first click rather than on a double click?

This worked for me. The Platform.runLater() was necessary for some reason.
tableView.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> {
if (newSelection != null) {
int row = tableView.getSelectionModel().getSelectedCells().get(0).getRow();
Platform.runLater(() -> tableView.edit(row, columnToEdit));
}
});

Related

JavaFX TableView custom row style on double click

I have a TableView in my JavaFX application.
I would like to style differently row when it is double-clicked on it, and differently when it is single-clicked.
Here is what I achieve:
final PseudoClass doubleClickPseudoClass = PseudoClass.getPseudoClass("new");
setRowFactory(tableView -> {
final TableRow<Bean> row = new TableRow<Bean>();
row.setOnMouseClicked(event -> {
if (event.getClickCount() == 2 && (! row.isEmpty())) {
row.pseudoClassStateChanged(doubleClickPseudoClass, true);
});
return row;
});
However, when the user doubles click on every new row, I want all previously double-clicked rows to be styled without applying "new" class:
row.pseudoClassStateChanged(doubleClickPseudoClass, false);
How can I do that?
Now I have cumulative styled all rows as they are double-clicked.
You shouldn't use TableRows to store the state themselves since new items may be assigned to a TableRow instance. Instead use a property to store the item double-clicked item and use a listener for styling the rows:
final ObjectProperty<Bean> doubleClickedObject = new SimpleObjectProperty<>();
setRowFactory(tableView -> new TableRow<Bean>() {
private void updateStyle() {
pseudoClassStateChanged(doubleClickPseudoClass, !isEmpty() && doubleClickedObject.get() == getItem());
}
private final InvalidationListener listener;
{
listener = o -> updateStyle();
doubleClickedObject.addListener(new WeakInvalidationListener(listener));
setOnMouseClicked(event -> {
if (!isEmpty() && event.getClickCount() == 2) {
doubleClickedObject.set(getItem());
}
});
}
#Override
protected void updateItem(Bean item, boolean empty) {
super.updateItem(item, empty);
updateStyle();
}
});

Selecting an entire line from TextArea on mouse click

I am using JavaFX for my application. In my application I have a button,on click on that button should display the results on textarea, that I am able to do. Now I would like to select the entire line on click from the text area. But The code which I have written is able to select only the value which I click which means like only word on which I have clicked. Please suggest me to modify this.
#FXML
public void find_btn_action(ActionEvent event) throws MWException
{
double[] peaks= {1.2,5.6,8.0,9.0};
StringBuilder sb = new StringBuilder(peaks.length);
for(int i= 0; i < peaks.length ; i++)
{
result[i] = peaks[i];
sb.append(result[i]+"\n");
}
auto.setText(sb.toString());
auto.setOnMouseClicked(new EventHandler<Event>()
{
#Override
public void handle(Event arg0)
{
selectedVal = auto.getSelectedText();
System.out.println("selected text:"+ selectedVal);
}
});
}
In your mouse click listener check, if the click was inside the content area and if this is the case, use the caret position to determine the next/previous line break in the TextArea's text and select this range:
textArea.setOnMouseClicked(evt -> {
if (evt.getButton() == MouseButton.PRIMARY) {
// check, if click was inside the content area
Node n = evt.getPickResult().getIntersectedNode();
while (n != textArea) {
if (n.getStyleClass().contains("content")) {
// find previous/next line break
int caretPosition = textArea.getCaretPosition();
String text = textArea.getText();
int lineBreak1 = text.lastIndexOf('\n', caretPosition - 1);
int lineBreak2 = text.indexOf('\n', caretPosition);
if (lineBreak2 < 0) {
// if no more line breaks are found, select to end of text
lineBreak2 = text.length();
}
textArea.selectRange(lineBreak1, lineBreak2);
evt.consume();
break;
}
n = n.getParent();
}
}
});

How to add multiple listener at treeview in javafx? (hover, focused)

I have made treeview. I want to make treeview like this.
when I enter mouse to item, that item should change image.
when I clcick mouse to item, that item should chnage image.
I know how the way getSelectionMode()... but I don't know hover event.
Please help me.
Not sure if I understand you correct.
But to change your image as soon as you click an image use a selectedItemProperty listener:
treeView.getSelectionModel().selectedItemProperty().addListener( new ChangeListener() {
#Override
public void changed(ObservableValue observable, Object oldValue,
Object newValue) {
TreeItem<String> selectedItem = (TreeItem<String>) newValue;
// do something
}
});
If you want it as soon as you hover over the item you can use a hoverProperty on the row:
treeView.setRowFactory(tableView -> {
final TableRow<Person> row = new TableRow<>();
row.hoverProperty().addListener((observable) -> {
final YourItem yourItem = row.getItem();
if (yourItem.isHover() ) {
// do something
} else {
// do something
}
});
return row;
});
(this code is from the answer here)
I missread, its about a TreeView. You can try an onMouseEntered or similiar within a cellfactory:
treeView.setCellFactory(tv -> {
final Tooltip tooltip = new Tooltip();
TreeCell<Path> cell = new TreeCell<Path>() {
#Override
public void updateItem(Path item, boolean empty) {
super.updateItem(item, empty);
}
};
cell.setOnMouseClicked(e -> {
// do something
});
cell.setOnMouseEntered(e -> {
// do something
});
return cell ;
});

javafx Minesweeper: how to tell between right and left mouse button input

I am working on a javafx Minesweeper game, and currently am only using left mouse button input. I would like to use the right mouse button also so users can flag possible bombs. I looked at the Oracle webpage for Button class, and it says:
"When a button is pressed and released a ActionEvent is sent. Your application can perform some action based on this event by implementing an EventHandler to process the ActionEvent. Buttons can also respond to mouse events by implementing an EventHandler to process the MouseEvent."
https://docs.oracle.com/javafx/2/api/javafx/scene/control/Button.html
Ive tried this several different ways, with no success.
Included is my current EventHandler code. If anyone can explain the best way to handle right/left mouse clicks, or point me in the right direction of where to find that information, it is greatly appreciated.
MineButton is a custom class that extends Button. I would like on right click to mark as "m" and change cell color, and left click would remain the same.
for (int row = 0; row < 8; row++){
for (int col = 0; col <8; col++){
MineButton button = new MineButton(row, col);
button.setPrefSize(100, 100);
button.setText("?");
button.setStyle("-fx-font: 22 arial; -fx-base:#dcdcdc;");
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
if ( button.isAMine() == true){
button.setText("B");
for( int row1 = 0; row1 < 8; row1++){
for ( int col1 = 0; col1 < 8; col1++){
if (mineButtons[row1][col1].isAMine() == true){
mineButtons[row1][col1].setText("B");
mineButtons[row1][col1].setStyle("-fx- font: 22 arial; -fx-base: #dc143c;");
}
}
}
}
else{
recursion(mineButtons, button.getX(), button.getY());
}
}
});
You cannot handle right clicks on a button by attaching an event handler on action event. Instead you need to add a handler to the mouse event:
button.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
if(mouseEvent.getButton().equals(MouseButton.SECONDARY)){
System.out.println("Set flag on the button");
}
}
});
If u wanna handle the MouseEvent use this code. It will work.
button.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
if(event.getButton() == MouseButton.SECONDARY){
// Type code to set flag here
}
}
});
scene.setOnMousePressed(event ->{
if(event.getButton() == MouseButton.PRIMARY) {
anchorX = event.getSceneX();
anchorY = event.getSceneY();
anchorAngleX = angleX.get();
anchorAngleY = angleY.get();
}
});
scene.setOnMouseDragged((MouseEvent event) -> {
if(event.getButton() == MouseButton.PRIMARY) {
angleX.set(anchorAngleX - (anchorY - event.getSceneY()));
angleY.set(anchorAngleY - (anchorX - event.getSceneX()));
}
});
This code rotates a JavaFX group in a scene with a left mouse button and a drag. You can print the event.getButton to make certain your primary and secondary are working. I have tried many other ways including JavaFXtras. This is by far the simplest way to handle the primary and secondary mouse click events.

how to use again an actionEvent in Other textField in javafx

I have a log in form that i was creating and i want the TextField ActionEvent to be used also in the Button but I don't know what to do. In Swing I've seen it that it can recycle an ActionEvent and use it in other like TextField but i don't know how to do it in JavaFX.
Here is a code for my TextField with an ActionEvent
and I want to apply this also to my Button so I dont have to create another method with just the same function but different Component. Thanks
passField.setOnKeyPressed(new EventHandler<KeyEvent>()
{
#Override
public void handle(KeyEvent e)
{
if(e.getCode().equals(KeyCode.ENTER))
{
if(admin.equals(userField.getText()) && password.equals(passField.getText()))
{
textInfo.setText("WELCOME " + passField.getText());
textInfo.setTextFill(Color.BLACK);
}
else
{
userField.clear();
passField.clear();
textInfo.setText("Incorrect username or password");
textInfo.setTextFill(Color.RED);
}
}
}
});
You will have to find a shared Event that both the Button and the TextField support.
In your example you are attaching a handler for a KeyEvent watching for the ENTER key, which is equivalent to an ActionEvent. luckily the Button supports it too.
Create a shared EventHandler:
final EventHandler<ActionEvent> myHandler = e -> {
if(admin.equals(userField.getText()) && password.equals(passField.getText())) {
textInfo.setText("WELCOME " + passField.getText());
textInfo.setTextFill(Color.BLACK);
}
else {
userField.clear();
passField.clear();
textInfo.setText("Incorrect username or password");
textInfo.setTextFill(Color.RED);
}
}
Which you can now attach twice (or even more often):
button.setOnAction(myHandler);
passField.setOnAction(myHandler);
EDIT
Without lambda expression:
final EventHandler<ActionEvent> myHandler = new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e)
{
if(admin.equals(userField.getText()) && password.equals(passField.getText())) {
textInfo.setText("WELCOME " + passField.getText());
textInfo.setTextFill(Color.BLACK);
}
else {
userField.clear();
passField.clear();
textInfo.setText("Incorrect username or password");
textInfo.setTextFill(Color.RED);
}
}
});

Resources