JavaFX TreeTableView Remove Item ContextMenu - javafx

I have the following in my FXMLController:
#FXML
TreeTableView<FileModel> treeTblViewFiles;
//...
#Override
public void initialize(URL url, ResourceBundle rb) {
//...
final ObservableList<Song> data = FXCollections.observableArrayList(
new Song("Song#1", "/home/pm/songs/song1.mp3","12MB"),
new Song("Song#2", "/home/pm/songs/song2.mp3","12MB"),
new Song("Song#3", "/home/pm/songs/song3.mp3","12MB"),
new Song("Song#4", "/home/pm/songs/song4.mp3","12MB"),
new Song("Song#5", "/home/pm/songs/song5.mp3","12MB"),
new Song("Song#6", "/home/pm/songs/song6.mp3","12MB"),
new Song("Song#7", "/home/pm/songs/song7.mp3","12MB"),
new Song("Song#8", "/home/pm/songs/song8.mp3","12MB"),
new Song("Song#9", "/home/pm/songs/song9.mp3","12MB"),
new Song("Song#10", "/home/pm/songs/song10.mp3","12MB")
);
treeTblViewFiles.setRowFactory(new Callback<TreeTableView<FileModel>, TreeTableRow<FileModel>>(){
#Override
public TreeTableRow<FileModel> call(TreeTableView<FileModel> treeTableView) {
final TreeTableRow<FileModel> row = new TreeTableRow<>();
final ContextMenu rowMenu = new ContextMenu();
MenuItem removeItem = new MenuItem("Remove");
removeItem.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent t) {
data.remove(row.getItem());
treeTblViewFiles.getSelectionModel().clearSelection();
System.out.println("Context Menu -> ActionEvent");
}
});
rowMenu.getItems().add(removeItem);
row.contextMenuProperty().bind(Bindings.when(Bindings.isNotNull(row.itemProperty()))
.then(rowMenu)
.otherwise((ContextMenu)null));
return row;
}
});
//...
}
Song is a class that inherits from FileModel.
Basically what I do is create my custom row factory where I delete the selected item, but nothing happens. No item is deleted from treeTableView control, although it is removed from the ObservableList.
What am I missing or misunderstood?
Thanks in advance.

I haven't worked with TreeTableView, so this is a bit of a shot in the dark: but TreeTableViews (and TreeViews) aren't wired to the data quite as cleanly as TableViews. Each data item is wrapped in a TreeItem to give it the hierarchical structure. So I think you need something like
#Override
public void handle(ActionEvent t) {
data.remove(row.getItem());
TreeItem<FileModel> treeItem = row.getTreeItem();
// may need to check treeItem.getParent() is not null:
treeItem.getParent().getChildren().remove(treeItem);
treeTblViewFiles.getSelectionModel().clearSelection();
System.out.println("Context Menu -> ActionEvent");
}

Related

Context menu on TableRow<Object> does not show up on first right click

So I followed this example on using context menu with TableViews from here. I noticed that using this code
row.contextMenuProperty().bind(Bindings.when(Bindings.isNotNull(row.itemProperty()))
.then(rowMenu)
.otherwise((ContextMenu)null));
does not show up on first right click on a row with values. I need to right click on that row again for the context menu to show up. I also tried this code(which is my first approach, but not using it anymore because I've read somewhere that that guide is the best/good practice for anything related about context menu and tableview), and it displays the context menu immediately
if (row.getItem() != null) {
rowMenu.show(row, event.getScreenX(), event.getScreenY());
}
else {
// do nothing
}
but my problem with this code is it throws a NullPointerException whenever i try to right click on a row that has no data.
What could I possibly do to prevent NullPointerException while having the context menu show up immediately after a right click? In my code, I also have a code that a certain menu item in the context menu will be disabled based on the property of the myObject binded to row, that's why i need the context menu to pop up right away.
I noticed this too with the first block of code. Even if the property of myObject has already changed, it still has a menu item enabled/disabled unless I right click on that row again. I hope that you could help me. Thank you!
Here is a MCVE:
public class MCVE_TableView extends Application{
#Override
public void start(Stage primaryStage) throws Exception {
BorderPane myBorderPane = new BorderPane();
TableView<People> myTable = new TableView<>();
TableColumn<People, String> nameColumn = new TableColumn<>();
TableColumn<People, Integer> ageColumn = new TableColumn<>();
ContextMenu rowMenu = new ContextMenu();
ObservableList<People> peopleList = FXCollections.observableArrayList();
peopleList.add(new People("John Doe", 23));
nameColumn.setMinWidth(100);
nameColumn.setCellValueFactory(
new PropertyValueFactory<>("Name"));
ageColumn.setMinWidth(100);
ageColumn.setCellValueFactory(
new PropertyValueFactory<>("Age"));
myTable.setItems(peopleList);
myTable.getColumns().addAll(nameColumn, ageColumn);
myTable.setRowFactory(tv -> {
TableRow<People> row = new TableRow<>();
row.setOnContextMenuRequested((event) -> {
People selectedRow = row.getItem();
rowMenu.getItems().clear();
MenuItem sampleMenuItem = new MenuItem("Sample Button");
if (selectedRow != null) {
if (selectedRow.getAge() > 100) {
sampleMenuItem.setDisable(true);
}
rowMenu.getItems().add(sampleMenuItem);
}
else {
event.consume();
}
/*if (row.getItem() != null) { // this block comment displays the context menu instantly
rowMenu.show(row, event.getScreenX(), event.getScreenY());
}
else {
// do nothing
}*/
// this requires the row to be right clicked 2 times before displaying the context menu
row.contextMenuProperty().bind(Bindings.when(Bindings.isNotNull(row.itemProperty()))
.then(rowMenu)
.otherwise((ContextMenu)null));
});
return row;
});
myBorderPane.setCenter(myTable);
Scene scene = new Scene(myBorderPane, 500, 500);
primaryStage.setTitle("MCVE");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main (String[] args) {
launch(args);
}
}
Here is the People Class
public class People {
SimpleStringProperty name;
SimpleIntegerProperty age;
public People(String name, int age) {
this.name = new SimpleStringProperty(name);
this.age = new SimpleIntegerProperty(age);
}
public SimpleStringProperty NameProperty() {
return this.name;
}
public SimpleIntegerProperty AgeProperty() {
return this.age;
}
public String getName() {
return this.name.get();
}
public int getAge() {
return this.age.get();
}
}
Edit: MCVE added
Edit2: Updated the MCVE. Still requires to be right-clicked twice before the contextMenu pops up
Below's a code snippet as a quick demonstration of how-to/where-to instantiate and configure a per-row ContextMenu. It
creates a ContextMenu/MenuItem for each TableRow at the row's instantiation time
creates a conditional binding that binds the menu to the row's contextMenuProperty if not empty (just the same as you did)
configures the contextMenu in an onShowing handler, depending on the current item (note: no need for a guard against null, because the conditional binding will implicitly guarantee to not show the the menu in that case)
The snippet:
myTable.setRowFactory(tv -> {
TableRow<People> row = new TableRow<>() {
ContextMenu rowMenu = new ContextMenu();
MenuItem sampleMenuItem = new MenuItem("Sample Button");
{
rowMenu.getItems().addAll(sampleMenuItem);
contextMenuProperty()
.bind(Bindings
.when(Bindings.isNotNull(itemProperty()))
.then(rowMenu).otherwise((ContextMenu) null));
rowMenu.setOnShowing(e -> {
People selectedRow = getItem();
sampleMenuItem.setDisable(selectedRow.getAge() > 100);
});
}
};
return row;
});

JavaFX copying over a object from one tableview to another with a button

So I´m building a warband calculator for a tabletop game and currently it looks like this
What I wanna do is that when I click on a "add" button it copies that unit/creature over to the tableview on the right side(So if I click on the "add" button on the Zombie row, a zombie gets copied over the tableview on the right).
The problem is I can only make it work if you select the row THEN click the button, but I want to be able to rely solely on the button. I think the problem is that I use "getSelectionModel().getSelectedItem()" in the button class to get the object to be copied over, But I cant find any other way to do it.
The relevant code parts from the main class
//Creates the lists
ObservableList<Unit> rightSideList = FXCollections.observableArrayList();
ObservableList<Unit> leftSideList = FXCollections.observableArrayList();
// Puts some test data in the lists
public Main() {
rightSideList.add(new Unit("Skeleton",5,4,9,4,1,6,9));
rightSideList.add(new Unit("Ghoul",6,4,010,4,1,6,7));
rightSideList.add(new Unit("Zombie",4,5,1,3,1,6,5));
rightSideList.add(new Unit("Wraith",4,5,19,3,1,6,5));
rightSideList.add(new Unit("Spectre",4,5,1,3,1,6,5));
leftSideList.add(new Unit("Skeleton",5,4,0,4,1,6,9));
}
//Creates the tables
final TableView<Unit> table1 = new TableView<>(
rightSideList
);
final TableView<Unit> table2 = new TableView<>(
leftSideList
);
//Defines the table columns
//Columns for table 1
TableColumn<Unit,String> unitNameCol = new TableColumn<>("Unit");
unitNameCol.setCellValueFactory(new PropertyValueFactory("unitName"));
unitNameCol.setMinWidth(100);
TableColumn<Unit,Integer> speedCol = new TableColumn<>("Spd");
speedCol.setCellValueFactory(new PropertyValueFactory("speed"));
TableColumn<Unit,Integer> meleeCol = new TableColumn<>("Me");
meleeCol.setCellValueFactory(new PropertyValueFactory("melee"));
TableColumn<Unit,Integer> rangedCol = new TableColumn<>("Ra");
rangedCol.setCellValueFactory(new PropertyValueFactory("ranged"));
TableColumn<Unit,Integer> defenseCol = new TableColumn<>("Def");
defenseCol.setCellValueFactory(new PropertyValueFactory("defense"));
TableColumn<Unit,Integer> attackCol = new TableColumn<>("Att");
attackCol.setCellValueFactory(new PropertyValueFactory("attack"));
TableColumn<Unit,Integer> toughnessCol = new TableColumn<>("To");
toughnessCol.setCellValueFactory(new PropertyValueFactory("toughness"));
TableColumn<Unit,Integer> costCol = new TableColumn<>("Cost");
costCol.setCellValueFactory(new PropertyValueFactory("cost"));
TableColumn<Unit, Boolean> actionCol = new TableColumn<>("Action");
actionCol.setSortable(false);
actionCol.setMinWidth(35);
// define a simple boolean cell value for the action column so that the column will only be shown for non-empty rows for table 1
actionCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Unit, Boolean>, ObservableValue<Boolean>>() {
#Override public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Unit, Boolean> features) {
return new SimpleBooleanProperty(features.getValue() != null);
}
});
// create a cell value factory with an add button for each row in the table for table 1
actionCol.setCellFactory(new Callback<TableColumn<Unit, Boolean>, TableCell<Unit, Boolean>>() {
#Override public TableCell<Unit, Boolean> call(TableColumn<Unit, Boolean> unitBooleanTableColumn) {
return new AddUnitCell(mainStage, table1);
}
});
And here is the button class
/** A table cell containing a button for adding a unit */
private class AddUnitCell extends TableCell<Unit, Boolean> {
// a button for adding a new Unit.
final Button addButton = new Button("Add");
// pads and centers the add button in the cell.
final StackPane paddedButton = new StackPane();
/**
* AddUnitCell constructor
* #param stage the stage in which the table is placed.
* #param table the table to which a unit can be added.
*/
AddUnitCell(final Stage stage, final TableView<Unit> table) {
paddedButton.setPadding(new Insets(3));
paddedButton.getChildren().add(addButton);
addButton.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent actionEvent) {
Unit selectedUnit = table.getSelectionModel().getSelectedItem();
leftSideList.add(selectedUnit);
}
});
}
/** places an add button in the row only if the row is not empty. */
#Override protected void updateItem(Boolean item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
setGraphic(paddedButton);
} else {
setGraphic(null);
}
}
}
If you need to check in detail here is a link to the projects repository
https://github.com/MagnusLindstrom88/Star-Struck-City-Warband-Calculator/blob/master/src/application/Main.java
Instead of
Unit selectedUnit = table.getSelectionModel().getSelectedItem();
in the button event handler's handle() method, do
Unit selectedUnit = table.getItems().get(getIndex());
Instead of relying on the selection model to get the item, you should get the item from the TableRow:
Unit selectedUnit = (Unit) getTableRow().getItem();

Javafx combobox not updating dropdown size upon change on realtime?

I am using Javafx v8.0.25-b18.
The problem I occur is that the size of the dynamic combox's dropdown list doesn't change, so if I had initially two items in the dropdown, then the dropdown size will be good for two items, but if I now populate the dynamic combox with three items then I get a small scrollbar inside!?, If I remove an item - I will have a blank space in the combox !?
I want to "reset" the dropdown size each time I put values into it, so it will be the right size each time it gets populated at runtime.
To clarify even more I am adding three images:
1. The first screenshot shows the initial dropdown size of 2
The second screenshot shows the same combox, where now at runtime I am adding 2 values, I EXPECT it to have now a dropdown with the size of 4, but instead the dropdown size stays 2 and only adds an unwanted scrollbar
Last screenshot is when I remove items and only one item remains in the combox, I EXPECT to see a dropdown of 1 item, but instead I unfortunately see a dropdown the size of 2 thus an empty space instead of the second item
I am adding the simple code to create this scenario, I want to thank #Gikkman that helped getting this far and the code is actually his!
public class Test extends Application {
private int index = 0;
#Override
public void start(Stage primaryStage) throws IOException {
VBox vbox = new VBox();
vbox.setSpacing(10);
vbox.setAlignment(Pos.CENTER);
final ComboBox<String> box = new ComboBox<>();
box.setPrefWidth(200);
box.setVisibleRowCount(10);
Button add = new Button("Add");
Button remove = new Button("Remove");
add.setOnAction( new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
box.getItems().add("Item " + index++);
box.getItems().add("Item " + index++);
}
});
remove.setOnAction( new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
if( index > 0 )
box.getItems().remove(--index);
}
});
vbox.getChildren().addAll(add, remove, box);
Scene scene = new Scene(vbox);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Try this:
box.hide(); //before you set new visibleRowCount value
box.setVisibleRowCount(rows); // set new visibleRowCount value
box.show(); //after you set new visibleRowCount value
It works for me with editable comboBox and I think it will work in your case.
I had same problem and I solved it with a quick trick.
Just try to show and immediately hide !
add.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
box.getItems().add("Item " + index++);
box.getItems().add("Item " + index++);
box.show();
box.hide();
}
});
Just like to offer my two cents here. You may add the following codes to your combobox which define a custom listview popup that has variable height according to the current number of items. You can tweak the maximum number of items to be displayed in the popup.
yourComboBox.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
#Override
public ListCell<String> call(ListView<String> param) {
ListCell cell = new ListCell<String>() {
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
int numItems = getListView().getItems().size();
int height = 175; // set the maximum height of the popup
if (numItems <= 5) height = numItems * 35; // set the height of the popup if number of items is equal to or less than 5
getListView().setPrefHeight(height);
if (!empty) {
setText(item.toString());
} else {
setText(null);
}
}
};
return cell;
}
});
You don't have to change the number of entries to be displayed. The implementation will handle that automatically.
Say you want to display at most 10 items. Then, you use comboBox.setVisibleRowCount( 10 ); If there are less than 10 items at any time, Javafx will only show as many rows as there are items.
Actually, changing the number of visible rows at runtime can sometimes cause errors, from my experience, so you are better of with just having a set number.
Hope that helps.
I have some problems understanding what the problem is. I made a short example bellow, can you try it and then say what it doesn't do that you want to do.
public class Test extends Application{
private int index = 0;
#Override
public void start(Stage primaryStage) throws IOException{
VBox vbox = new VBox();
vbox.setSpacing(10);
vbox.setAlignment(Pos.CENTER);
ComboBox<String> box = new ComboBox<>();
box.setPrefWidth(200);
box.setVisibleRowCount(10);
Button add = new Button("Add");
Button remove = new Button("Remove");
add.setOnAction( new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
box.getItems().add("Item " + index++);
}
});
remove.setOnAction( new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
if( index > 0 )
box.getItems().remove(--index);
}
});
vbox.getChildren().addAll(add, remove, box);
Scene scene = new Scene(vbox);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
You can use two JavaFx list. First one is previous com box list, another one is final combo box list. then you can change dynamically using yourCombo.getItems().setAll(Your List);
Here is my sample code:
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ComboBoxTest extends Application {
#Override
public void start(final Stage primaryStage) throws Exception {
primaryStage.centerOnScreen();
primaryStage.setHeight(200);
primaryStage.setWidth(300);
List<String> list1 = new ArrayList<>();
list1.add("one");
list1.add("two");
list1.add("three");
List<String> list2 = new ArrayList<>();
list2.add("one");
list2.add("two");
list2.add("three");
list2.add("four");
final ComboBox<String> combo = new ComboBox<String>();
combo.getItems().setAll(list1);
Button button = new Button("Change combo contents");
button.setOnAction(event -> {
if ( combo.getItems().size() == 3 ) {
combo.getItems().setAll(list2);
} else {
combo.getItems().setAll(list1);
}
combo.show();
});
VBox box = new VBox(20, combo, button );
box.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
primaryStage.setScene(new Scene( new StackPane(box) ));
primaryStage.show();
}
public static void main(String[] args) throws Exception {
launch(args);
}
}

WebEngine not loading URL on button click

I am coding a Tabbed web browser in JAVAFx. The problem i am facing is :-
When I click on Home Button (HomeB) it is not loading the DEFAULT_URL in the current tab. Here is some useful part of my code. Some body please fix it. Thanks
class Browser extends Region{
final BorderPane borderPane;
final TabPane tabPane;
private final HBox toolbarMain;
WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
private String DEFAULT_URL= "http://www.google.com";
final TextField urlField = new TextField(DEFAULT_URL);
//Custom function for creation of New Tabs.
private Tab createAndSelectNewTab(final TabPane tabPane, final String title) {
Tab tab = new Tab(title);
webEngine.locationProperty().addListener(new ChangeListener<String>() {
#Override public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
urlField.setText(newValue);
}
});
final ObservableList<Tab> tabs = tabPane.getTabs();
tab.closableProperty().bind(Bindings.size(tabs).greaterThan(2));
tabs.add(tabs.size() - 1, tab);
tabPane.getSelectionModel().select(tab);
return tab;
}
//Initialization function of the program.
public Browser() {
borderPane = new BorderPane();
tabPane = new TabPane();
toolbarMain = new HBox();
Button HomeB = new Button();
HomeB.setText("HOME");
tabPane.setSide(Side.TOP);
final Tab newtab = new Tab();
newtab.setText("+");
newtab.setClosable(false); // this will not let the New Tab button(TAB) close
tabPane.getTabs().addAll(newtab); //Addition of New Tab to the tabpane.
createAndSelectNewTab(tabPane, " ");
//Function to add and display new tabs with default URL display.
tabPane.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>() {
#Override
public void changed(ObservableValue<? extends Tab> observable,
Tab oldSelectedTab, Tab newSelectedTab) {
if (newSelectedTab == newtab) {
Tab tab = new Tab();
//WebView - to display, browse web pages.
WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
webEngine.load(DEFAULT_URL);
EventHandler<ActionEvent> goAction = new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent event) {
webEngine.load(urlField.getText().startsWith("http://")
? urlField.getText()
: "http://" + urlField.getText());
}
};
urlField.setOnAction(goAction);
final VBox vBox = new VBox(5);
vBox.getChildren().setAll(browser);
VBox.setVgrow(browser, Priority.ALWAYS);
tab.setContent(vBox);
final ObservableList<Tab> tabs = tabPane.getTabs();
tab.closableProperty().bind(Bindings.size(tabs).greaterThan(2));
tabs.add(tabs.size() - 1, tab);
tabPane.getSelectionModel().select(tab);
}
}
});
//OnClick handling HomeB
HomeB.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event){
webEngine.load(DEFAULT_URL);
}
});
toolbarMain.getChildren().addAll(HomeB,urlField);
//Placement of elements in borderpane
borderPane.setCenter(tabPane);
borderPane.setTop(toolbarMain);
getChildren().add(borderPane);
}
}
When you click on the HomeB the default URL is loaded into the browser, a global WebView. That works, but you don't see the URL loaded, because you haven't added this browser to any of your tabs.
Assuming you create the first tab for the home button:
tabPane.getTabs().addAll(newtab); // tab 0, then moves to 1
// Here you create a new tab, but put it on the 0 index:
createAndSelectNewTab(tabPane, " ");
// You can add now your global browser to the first tab:
final VBox vBoxIni = new VBox(5);
vBoxIni.getChildren().setAll(browser);
VBox.setVgrow(browser, Priority.ALWAYS);
tabPane.getTabs().get(0).setContent(vBoxIni);
Other option will be using the local webView you have created for each tab, and load the default URL on the active tab:
HomeB.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event){
VBox vBox=(VBox)tabPane.getSelectionModel().getSelectedItem().getContent();
if(vBox!=null){
WebView webView=(WebView)vBox.getChildren().get(0);
webView.getEngine().load(DEFAULT_URL);
}
}
});
Note this won't work on the first tab, since you haven't set any content there.

Call event handler

I have a TabPane with test button which calls this code:
Button bt1 = new Button("Select");
bt1.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(final ActionEvent event)
{
TreeClass.getConnectedAgentsMap();
TreePane.getTreeView().getSelectionModel().clearAndSelect(3);
}
});
This code selects TreeNode into TreeView:
cell.setOnMouseClicked((MouseEvent me) ->
{
if (!cell.isEmpty())
{
/// some action
}
});
As you can see this event is triggered when mouse selects tree row.
I tried to call the tree cell action with this code:
cell.selectedProperty().addListener(new ChangeListener<Boolean>()
{
#Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue)
{
/// Some Action
}
});
But it's not the proper way to use it because several times new Tab is opened. Is there a way when I click the button to call action event?
final Point2D windowCoord = new Point2D(SCENE.getWindow().getX(), SCENE.getWindow().getY());
final Point2D sceneCoord = new Point2D(SCENE.getX(), Main.getStage().getScene().getY());
final Point2D nodeCoord = MYCONTROL.localToScene(0.0, 0.0);
final double x = Math.round(windowCoord.getX() + sceneCoord.getX() + nodeCoord.getX());
final double y = Math.round(windowCoord.getY() + sceneCoord.getY() + nodeCoord.getY());
try {
Robot robot = new Robot();
robot.mouseMove(new Double(x).intValue()+1, new Double(y).intValue());
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
} catch (AWTException ex) {
ex.printStackTrace();
}
Some of the code is borrowed from this website.

Resources