JavaFX 2.0 TreeView ContextMenu - java

I´m currently working on a TreeView and want to implement a ContextMenu which pops up on rightClick on a TreeCell. I´ve studied the examples but I´m not sure of how I can set the ContextMenu to popup on every cell, not just the ones that are filled with children.
Here my code (pretty much the sample code):
Constructor
.
.
.
this.setCellFactory(new Callback<TreeView<String>,TreeCell<String>>()
{
#Override
public TreeCell<String> call(TreeView<String> p)
{
return new TextFieldTreeCellImpl();
}
});
}
private final class TextFieldTreeCellImpl extends TreeCell<String>
{
private TextField textField;
private ContextMenu addMenu = new ContextMenu();
#SuppressWarnings({ "rawtypes", "unchecked" })
public TextFieldTreeCellImpl()
{
MenuItem addMenuItem = new MenuItem("Add Note");
addMenu.getItems().add(addMenuItem);
addMenuItem.setOnAction(new EventHandler()
{
public void handle(Event t)
{
ImageView noteIcon = new ImageView(new Image(getClass().getResourceAsStream("../icons/note.png")));
noteIcon.setFitHeight(16);
noteIcon.setFitWidth(16);
TreeItem newNote = new TreeItem<String>("New Note");
getTreeItem().getChildren().add(newNote);
}
});
}
#Override
public void startEdit()
{
super.startEdit();
if (textField == null)
{
createTextField();
}
setText(null);
setGraphic(textField);
textField.selectAll();
}
#Override
public void cancelEdit()
{
super.cancelEdit();
setText((String) getItem());
setGraphic(getTreeItem().getGraphic());
}
#Override
public void updateItem(String item, boolean empty)
{
super.updateItem(item, empty);
if (empty)
{
setText(null);
setGraphic(null);
}
else
{
if (isEditing())
{
if (textField != null)
{
textField.setText(getString());
}
setText(null);
setGraphic(textField);
}
else
{
setText(getString());
setGraphic(getTreeItem().getGraphic());
if (!getTreeItem().isLeaf()&&getTreeItem().getParent()!= null)
{
setContextMenu(addMenu);
}
}
}
}
private void createTextField()
{
textField = new TextField(getString());
textField.setOnKeyReleased(new EventHandler<KeyEvent>()
{
#Override
public void handle(KeyEvent t)
{
if (t.getCode() == KeyCode.ENTER)
{
commitEdit(textField.getText());
}
else if (t.getCode() == KeyCode.ESCAPE)
{
cancelEdit();
}
}
});
}
private String getString()
{
return getItem() == null ? "" : getItem().toString();
}
}
}

Showing contextMenu to "filled with children" cells only is controlled with lines:
if (!getTreeItem().isLeaf() && getTreeItem().getParent() != null) {
setContextMenu(addMenu);
}
remove if control to popup contextMenu to all nodes/cells.

Related

Still can't understand why my TableView change listener does not work

I know my problem is trivilant and solution is on the surface, but I still can't deal with it and so need help. The problem is that TableView ListChangeListener in my code does not show updated changes. I have read many topics, manuals and examples before asked a question
Javafx: Detect ALL changes made to tableView including addition/deletion of table rows and cell edits on any table rows
Java ListChangeListener WasUpdated() doesn't work
https://docs.oracle.com/javase/8/javafx/api/javafx/collections/ListChangeListener.Change.html#wasUpdated--
http://java-buddy.blogspot.com/2014/11/example-of-listchangelistener-for.html
but still can't understand why my code does not work. I have added extractor but it's not helped me.
Here is a part of my code
public class mainTableOverviewController {
#FXML
private TableView<EmailData> emailTableView;
#FXML
private TableColumn<EmailData, String> emailNameColumn;
#FXML
private TableColumn<EmailData, String> emailLoginColumn;
#FXML
private TableColumn<EmailData, String> emailPasswordColumn;
#FXML
private TableColumn<EmailData, String> emailCommentsColumn;
#FXML
private Button handleDeletePerson;
private MainApp mainApp;
public mainTableOverviewController() {
}
#FXML
private void initialize() {
emailTableView.setEditable(true);
emailTableView.getSelectionModel().setCellSelectionEnabled(true);
emailTableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
Callback<TableColumn<EmailData, String>, TableCell<EmailData, String>> cellFactory =
new Callback<TableColumn<EmailData, String>, TableCell<EmailData, String>>() {
public TableCell call(TableColumn p) {
return new EditingCell();
}
};
emailNameColumn.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
emailNameColumn.setCellFactory(cellFactory);
emailNameColumn.setOnEditCommit(
t -> t.getTableView().getItems().get(
t.getTablePosition().getRow()).setName(t.getNewValue())
);
emailLoginColumn.setCellValueFactory(cellData -> cellData.getValue().loginProperty());
emailLoginColumn.setCellFactory(cellFactory);
emailLoginColumn.setOnEditCommit(
t -> t.getTableView().getItems().get(
t.getTablePosition().getRow()).setLogin(t.getNewValue())
);
emailPasswordColumn.setCellValueFactory(cellData -> cellData.getValue().passwordProperty());
emailPasswordColumn.setCellFactory(cellFactory);
emailPasswordColumn.setOnEditCommit(
t -> t.getTableView().getItems().get(
t.getTablePosition().getRow()).setPassword(t.getNewValue())
);
emailCommentsColumn.setPrefWidth(120);
emailCommentsColumn.setCellValueFactory(cellData -> cellData.getValue().commentsProperty());
emailCommentsColumn.setCellFactory(cellFactory);
emailCommentsColumn.setOnEditCommit(
t -> t.getTableView().getItems().get(
t.getTablePosition().getRow()).setComments(t.getNewValue())
);
emailData.addListener((Change<? extends EmailData> c) -> {
while (c.next()) {
if (c.wasAdded()) {
System.out.println("Added:");
c.getAddedSubList().forEach(System.out::println);
System.out.println();
}
if (c.wasRemoved()) {
System.out.println("Removed:");
c.getRemoved().forEach(System.out::println);
System.out.println();
}
if (c.wasUpdated()) {
System.out.println("Updated:");
emailData.subList(c.getFrom(), c.getTo()).forEach(System.out::println);
System.out.println();
}
}
});
emailTableView.getColumns().setAll(emailNameColumn, emailLoginColumn, emailPasswordColumn, emailCommentsColumn, actionCol);
}
}
#FXML
private void handleDeletePerson() {
int selectedIndex = emailTableView.getSelectionModel().getSelectedIndex();
if (selectedIndex >= 0) {
deletedDataList.add(emailTableView.getItems().get(selectedIndex));
emailTableView.getItems().remove(selectedIndex);
menuItemDisable.set(false);
} else {
nothingSelected();
}
}
class EditingCell extends TableCell<EmailData, String> {
TextField textField;
EditingCell() {
}
#Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
if (textField == null) {
createTextField();
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
Platform.runLater(new Runnable() {
#Override
public void run() {
textField.requestFocus();
textField.selectAll();
}
});
}
}
#Override
public void cancelEdit() {
super.cancelEdit();
setText((String) getItem());
setGraphic(null);
}
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
} else {
emailTableView.getColumns().get(0).setVisible(false);
emailTableView.getColumns().get(0).setVisible(true);
setText(getString());
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()
* 2);
textField.focusedProperty().addListener(
new ChangeListener<Boolean>() {
#Override
public void changed(
ObservableValue<? extends Boolean> arg0,
Boolean arg1, Boolean arg2) {
if (!arg2) {
commitEdit(textField.getText());
}
}
});
textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
commitEdit(textField.getText());
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
} else if (t.getCode() == KeyCode.TAB) {
commitEdit(textField.getText());
TableColumn nextColumn = getNextColumn(!t.isShiftDown());
if (nextColumn != null) {
getTableView().edit(getTableRow().getIndex(),
nextColumn);
}
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem();
}
private TableColumn<EmailData, ?> getNextColumn(boolean forward) {
List<TableColumn<EmailData, ?>> columns = new ArrayList<>();
for (TableColumn<EmailData, ?> column : getTableView().getColumns()) {
columns.addAll(getLeaves(column));
}
// There is no other column that supports editing.
if (columns.size() < 2) {
return null;
}
int nextIndex = columns.indexOf(getTableColumn());
if (forward) {
nextIndex++;
if (nextIndex > columns.size() - 1) {
nextIndex = 0;
}
} else {
nextIndex--;
if (nextIndex < 0) {
nextIndex = columns.size() - 1;
}
}
return columns.get(nextIndex);
}
private List<TableColumn<EmailData, ?>> getLeaves(
TableColumn<EmailData, ?> root) {
List<TableColumn<EmailData, ?>> columns = new ArrayList<>();
if (root.getColumns().isEmpty()) {
if (root.isEditable()) {
columns.add(root);
}
return columns;
} else {
for (TableColumn<EmailData, ?> column : root.getColumns()) {
columns.addAll(getLeaves(column));
}
return columns;
}
}
}
}
And the Class where list declaration are:
public class MainApp extends Application {
public static ObservableList<EmailData> backupList = FXCollections.observableArrayList();
public static ObservableList<EmailData> emailData = FXCollections.observableArrayList(ed ->
new Observable[]{
ed.nameProperty(),
ed.loginProperty(),
ed.passwordProperty(),
ed.commentsProperty()
});
private BorderPane rootLayout;
public MainApp() {
}
public static void readCryptedData(String s) {
try {
switch (s) {
case "initData":
emailData = readDataFromStream(decryptFileBytes(libraryPath, salt, nonce));
break;
default:
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
launch(args);
}
public static ObservableList<EmailData> getEmailData() {
return emailData;
}
#Override
public void start(Stage primaryStage) {
MainApp.primaryStage = primaryStage;
MainApp.primaryStage.setResizable(false);
MainApp.primaryStage.getIcons().add(new Image(imageFile.toURI().toString()));
initRootLayout();
try {
showFirstView();
} catch (IOException e) {
e.printStackTrace();
}
}
private void initRootLayout() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("/fxml/RootLayout.fxml"));
rootLayout = loader.load();
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
menuItemDisable.set(true);
} catch (IOException e) {
e.printStackTrace();
}
}
public Stage getPrimaryStage() {
return primaryStage;
}
#Override
public void stop() {
if (emailData.size() != 0) {
saveDataToFile();
}
}
}
I will much appreciated for any help.
After looking for comments and minuses to my question, I saw that I need to search a problem in my code by myself. Hope somebody will find this question and answer usefull.
The problem was in my read method readDataFromStream(). Before reading topics mentioned above I used such way declaration of ObservableList
public static ObservableList<EmailData> emailData = FXCollections.observableArrayList();
And my readDataFromStream looked like:
public static ObservableList<EmailData> readDataFromStream(byte[] bytes) {
ObservableList<EmailData> emailData = FXCollections.observableArrayList();
try {
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
List<EmailData> list = (List<EmailData>) ois.readObject();
emailData = FXCollections.observableList(list);
bis.close();
ois.close();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
return emailData;
}
And then I have read that I need create the list with an extractor. And I changed ObservableList declaration to:
ObservableList<EmailData> emailData = FXCollections.observableArrayList(ed ->
new Observable[]{
ed.nameProperty(),
ed.loginProperty(),
ed.passwordProperty(),
ed.commentsProperty()
});
but my readDataFromStream() method remained the same. Now I changed it to:
public static ObservableList<EmailData> readDataFromStream(byte[] bytes) {
ObservableList<EmailData> emailData = FXCollections.observableArrayList(ed ->
new Observable[]{
ed.nameProperty(),
ed.loginProperty(),
ed.passwordProperty(),
ed.commentsProperty()
});
try {
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
List<EmailData> list = (List<EmailData>) ois.readObject();
emailData = FXCollections.observableList(
list,
(EmailData tp) -> new Observable[]{tp.nameProperty(), tp.passwordProperty(),
tp.loginProperty(), tp.commentsProperty()});
bis.close();
ois.close();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
return emailData;
}
and wasUpdated() method of ListChangeListener.Change now works like a charm.
Hope it will help newbies like me.

JavaFX tableview: top cell holding data from bellow cell by default in edit mode

I am fairly new to JavaFX. I have a table with multiple columns and rows. Where new rows can be added at the top of the table. Editing cell is also enabled. But I am facing a problem.
When I add new rows at the top and go to edit that, cell fills up with a value from the bellow cell automatically when edit starts!! But I don't want that. Is it a feature like excel? if yes how can I stop that? Here is a sample picture and my custom EditingCell.java
class EditingCell <S, T>extends TableCell<S, T> {
private TextField textField;
public EditingCell() {
}
#Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
if (textField == null) {
createTextField();
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
// textField.selectAll();
Platform.runLater(new Runnable() {
#Override
public void run() {
textField.requestFocus();
textField.selectAll();
}
});
}
}
#Override
public void cancelEdit() {
super.cancelEdit();
setText((String) getItem());
setGraphic(null);
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
#Override
public void updateItem (T item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
} else {
setText(getString());
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
}
#Override
public void commitEdit(T item) {
if (! isEditing() && ! item.equals(getItem())) {
TableView<S> table = getTableView();
if (table != null) {
TableColumn<S, T> column = getTableColumn();
CellEditEvent<S, T> event = new CellEditEvent<>(table,
new TablePosition<S,T>(table, getIndex(), column),
TableColumn.editCommitEvent(), item);
Event.fireEvent(column, event);
}
super.cancelEdit(); // this fires an invalid EditCancelEvent.
// update the item within this cell, so that it represents the new value
updateItem(item, false);
if (table != null) {
// reset the editing cell on the TableView
table.edit(-1, null);
}
}
super.commitEdit(item);
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
private void createTextField() {
textField = new TextField(getString());
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()
* 2);
textField.focusedProperty().addListener(
new ChangeListener<Boolean>() {
#Override
public void changed(
ObservableValue<? extends Boolean> arg0,
Boolean arg1, Boolean arg2) {
if (!arg2) {
commitEdit((T)textField.getText());
}
}
});
textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
commitEdit((T)textField.getText());
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
} else if (t.getCode() == KeyCode.TAB) {
commitEdit((T)textField.getText());
TableColumn nextColumn = getNextColumn(!t.isShiftDown());
if (nextColumn != null) {
getTableView().edit(getTableRow().getIndex(),
nextColumn);
}
}
else if (t.getCode() == KeyCode.RIGHT) {
commitEdit((T)textField.getText());
getTableView().getSelectionModel().selectRightCell();
TableColumn nextColumn = getNextColumn(!t.isShiftDown());
if (nextColumn != null) {
getTableView().edit(getTableRow().getIndex(),
nextColumn);
}
t.consume();
} else if (t.getCode() == KeyCode.LEFT) {
commitEdit((T)textField.getText());
getTableView().getSelectionModel().selectLeftCell();
TableColumn prevColumn = getNextColumn(false);
if (prevColumn != null) {
getTableView().edit(getTableRow().getIndex(),
prevColumn);
}
t.consume();
} else if (t.getCode() == KeyCode.UP) {
commitEdit((T)textField.getText());
getTableView().getSelectionModel().selectAboveCell();
int i=getTableView().getSelectionModel().getSelectedIndex();
if(i>=0)
getTableView().edit(i,
getTableColumn());
t.consume();
} else if (t.getCode() == KeyCode.DOWN) {
commitEdit((T)textField.getText());
getTableView().getSelectionModel().selectBelowCell();
int i=getTableView().getSelectionModel().getSelectedIndex();
if(i>=0)
getTableView().edit(i,
getTableColumn());
t.consume();
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
private TableColumn<S, ?> getNextColumn(boolean forward) {
List<TableColumn<S, ?>> columns = new ArrayList<>();
for (TableColumn<S, ?> column : getTableView().getColumns()) {
columns.addAll(getLeaves(column));
}
// There is no other column that supports editing.
if (columns.size() < 2) {
return null;
}
int currentIndex = columns.indexOf(getTableColumn());
int nextIndex = currentIndex;
if (forward) {
nextIndex++;
if (nextIndex > columns.size() - 1) {
nextIndex = 0;
}
} else {
nextIndex--;
if (nextIndex < 0) {
nextIndex = columns.size() - 1;
}
}
return columns.get(nextIndex);
}
private List<TableColumn<S, ?>> getLeaves(
TableColumn<S, ?> root) {
List<TableColumn<S, ?>> columns = new ArrayList<>();
if (root.getColumns().isEmpty()) {
// We only want the leaves that are editable.
if (root.isEditable()) {
columns.add(root);
}
return columns;
} else {
for (TableColumn<S, ?> column : root.getColumns()) {
columns.addAll(getLeaves(column));
}
return columns;
}
}
}
Inside my initialize method I have code like below
Callback<TableColumn, TableCell> cellFactory = new Callback<TableColumn, TableCell>() {
public TableCell call(TableColumn p) {
return new EditingCell();
}
};
colName.setCellValueFactory(new PropertyValueFactory<ModelBrBuilding,String>("BranchName"));
colName.setCellFactory(cellFactory);
colName.setOnEditCommit(
new EventHandler<CellEditEvent<ModelBrBuilding, String>>() {
#Override
public void handle(CellEditEvent<ModelBrBuilding, String> t) {
oldName= ((ModelBrBuilding) t.getTableView().getItems().get(
t.getTablePosition().getRow())
).getBranchName(); // catch old value before edit
((ModelBrBuilding) t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setBranchName(t.getNewValue());
newName=t.getNewValue(); // catch new value after edit
boolean edit=((ModelBrBuilding) t.getTableView().getItems().get(
t.getTablePosition().getRow())
).isEdit();
if(edit==false) {
if(oldName!= null )
{
if(!oldName.trim().equals(newName.trim()) && !newName.isEmpty())
{
((ModelBrBuilding) t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setEdit(true);
}
}
else if(!newName.isEmpty()&& newName != null)
((ModelBrBuilding) t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setEdit(true);
}
}
}
);
And here is my method for adding new row at the top of the table.
public ObservableList<ModelBrBuilding> BuildingData;// contains searched data if there is any in database
//tableBuilding is sorted
// Method for adding new row
#FXML
private void addBuilding() {
tableBuilding.setEditable(true);
tableBuilding.getSelectionModel().setCellSelectionEnabled(true);
colName.setEditable(true);
//colShortCode.setEditable(true);
//colActive.setEditable(true);
if(BuildingData==null)//When search result is empty & there is now row in the table
{
tableBuilding.requestFocus();
tableBuilding.getItems().add(0,new ModelBrBuilding());
tableBuilding.layout();
tableBuilding.edit(0, colName);
}
//when search data is not empty
else {
ModelBrBuilding building = new ModelBrBuilding();
try {
BuildingData.add(0,building);
tableBuilding.layout();
tableBuilding.edit(0, colName);
//editBuilding();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
Can anyone help me in this regards please?
Finally, I have resolved it. I have to refresh the table after adding a new row.
#FXML
private void addBuilding() {
tableBuilding.setEditable(true);
tableBuilding.getSelectionModel().setCellSelectionEnabled(true);
colName.setEditable(true);
//colShortCode.setEditable(true);
//colActive.setEditable(true);
if(BuildingData==null)//When search result is empty & there is now row in the table
{
tableBuilding.requestFocus();
tableBuilding.getItems().add(0,new ModelBrBuilding());
tableBuilding.refresh();
tableBuilding.layout();
tableBuilding.edit(0, colName);
}
//when search data is not empty
else {
ModelBrBuilding building = new ModelBrBuilding();
try {
BuildingData.add(0,building);
tableBuilding.refresh();
tableBuilding.layout();
tableBuilding.edit(0, colName);
//editBuilding();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
}

Select JavaFX Editable Combobox text on click

I have a question regarding text selection when clicking on the editable Combobox.
Currently what happens, is that the mouse cursor just goes to that place of the input and does not select the whole text field. I would like to highlight/select whole textfield on the click, but it doesn't do that.
What I want that a click on the textfield would do:
This is my AutoComplete class:
public class AutoCompleteComboBoxListener<T> implements EventHandler<KeyEvent> {
private ComboBox comboBox;
private StringBuilder sb;
private ObservableList<T> data;
private boolean moveCaretToPos = false;
private int caretPos;
private Button button;
public AutoCompleteComboBoxListener(final ComboBox comboBox, final Button button) {
this.comboBox = comboBox;
sb = new StringBuilder();
data = comboBox.getItems();
this.comboBox.setEditable(true);
this.button = button;
this.comboBox.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
System.out.println("misaja");
System.out.println(t);
comboBox.hide();
}
});
this.comboBox.setOnKeyReleased(AutoCompleteComboBoxListener.this);
}
#Override
public void handle(KeyEvent event) {
System.out.println("nonoh");
System.out.println(event.getCode());
UI.bitLogger.logging(String.valueOf(event.getCode()));
if (event.getCode() == (KeyCode.ENTER)) {
System.out.println("erki");
button.fire();
}
if (event.getCode() == KeyCode.UP) {
caretPos = -1;
moveCaret(comboBox.getEditor().getText().length());
return;
} else if (event.getCode() == KeyCode.DOWN) {
if (!comboBox.isShowing()) {
comboBox.show();
}
caretPos = -1;
moveCaret(comboBox.getEditor().getText().length());
return;
} else if (event.getCode() == KeyCode.BACK_SPACE) {
moveCaretToPos = true;
caretPos = comboBox.getEditor().getCaretPosition();
} else if (event.getCode() == KeyCode.DELETE) {
moveCaretToPos = true;
caretPos = comboBox.getEditor().getCaretPosition();
}
if (event.getCode() == KeyCode.RIGHT || event.getCode() == KeyCode.LEFT
|| event.isControlDown() || event.getCode() == KeyCode.HOME
|| event.getCode() == KeyCode.END || event.getCode() == KeyCode.TAB) {
return;
}
ObservableList list = FXCollections.observableArrayList();
for (int i = 0; i < data.size(); i++) {
if (data.get(i).toString().toLowerCase().startsWith(
AutoCompleteComboBoxListener.this.comboBox
.getEditor().getText().toLowerCase())) {
list.add(data.get(i));
}
}
String t = comboBox.getEditor().getText();
comboBox.setItems(list);
comboBox.getEditor().setText(t);
if (!moveCaretToPos) {
caretPos = -1;
}
moveCaret(t.length());
if (!list.isEmpty()) {
comboBox.show();
}
}
private void moveCaret(int textLength) {
if (caretPos == -1) {
comboBox.getEditor().positionCaret(textLength);
} else {
comboBox.getEditor().positionCaret(caretPos);
}
moveCaretToPos = false;
}
I am creating the ComboBox here:
final ComboBox comboBox = new ComboBox(options);
comboBox.setPrefWidth(320);
comboBox.setValue("");
//ComboBox comboBox = new ComboBox();
new AutoCompleteComboBoxListener<>(comboBox, goButton);
comboBox.addEventFilter(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent ke) {
if (ke.getCode() == KeyCode.ENTER) {
//System.out.println("ENTER was released");
goButton.fire();
}
}
});
comboBox.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
System.out.println("mouse click detected2! " + mouseEvent.getSource());
//comboBox.getEditor().requestFocus();
//comboBox.getEditor().requestFocus();
//comboBox.requestFocus();
//comboBox.getEditor().selectAll();
//comboBox.requestFocus();
//None of these seem to work.
}
});
What I added now is this:
comboBox.getEditor().focusedProperty().addListener(new ChangeListener<Boolean>()
{
#Override
public void changed(ObservableValue<? extends Boolean> arg0, Boolean oldPropertyValue, Boolean newPropertyValue)
{
if (newPropertyValue)
{
System.out.println("Textfield on focus");
comboBox.requestFocus();
comboBox.getEditor().selectAll();
}
else
{
System.out.println("Textfield out focus");
}
}
});
But all it does is that it selects/highlights the text for just a moment and then removes the highlight once again.
You should try to do it by adding a focus listener on the textfield as next:
comboBox.getEditor().focusedProperty().addListener(
(observable, oldValue, newValue) -> {
if (newValue) {
// Select the content of the field when the field gets the focus.
Platform.runLater(comboBox.getEditor()::selectAll);
}
}
);
This code is for Java 8, for previous versions the corresponding code is:
comboBox.getEditor().focusedProperty().addListener(
new ChangeListener<Boolean>() {
#Override
public void changed(final ObservableValue<? extends Boolean> observable,
final Boolean oldValue, final Boolean newValue) {
if (newValue) {
Platform.runLater(
new Runnable() {
#Override
public void run() {
comboBox.getEditor().selectAll();
}
}
);
}
}
}
);

JavaFx TalbleView Scroll Down/Up issue

I have a problem on JavaFx TableView with large data such as whats happened on the items on the picture.
With huge data,the TableView do crazy works when i select a row or a cell.
I repeated the Number '131004' more than once for reference only
How can i solve this problem with large data?!? i didn't find any resource for that.
EDITED
also i have the same problem when i use scroll to up/down
The class is
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
/**
*
* #author mohammad
*/
public class EditingCellNew extends TableCell<Object, Integer> {
private TextField textField;
public EditingCellNew() {
this.setAlignment(Pos.CENTER);
}
#Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
if (textField == null) {
createTextField();
}
textField.setText(getString());
//setText(null);
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
textField.selectAll();
Platform.runLater(new Runnable() {
#Override
public void run() {
textField.requestFocus();
}
});
}
}
#Override
public void cancelEdit() {
super.cancelEdit();
setText(String.valueOf(getItem()));
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
#Override
public void updateItem(Integer item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
} else {
setText(getString());
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setAlignment(Pos.CENTER);
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
commitEdit(Integer.parseInt(textField.getText()));
System.out.println("table row : " + getTableRow().getIndex());
updateTableRow(getTableRow());
updateTableColumn(getTableColumn());
updateTableView(getTableView());
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
}
});
textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
updateTableRow(getTableRow());
updateTableView(getTableView());
//bondTable.getItems().set(bondTable.getSelectionModel().getSelectedIndex(), bondTable.getSelectionModel().getSelectedItem());
System.out.println("realesed enter");
}
}
});
}
private String getString() {
return String.valueOf(getItem()) == null ? "" : String.valueOf(getItem());
}
}

Unable to bind HTMLEditor and TextField in javafx

In my GUI i am having a TABLEVIEW and a HTMLEditor.
TableView having two columns. 1st column without edit feature. 2nd column have edit option.
for HTMLEditor i have written setOnKeyPressed property. In that property, in handle method i am trying to update 2nd column data. But data is not reflecting at all in TableView Control . But when i try to print data for 2nd column it is showing HTMLEditor's data only. But the HTMLEditor's data is not reflecting in TableView 2nd Column.
Following is my code
public class BinderDocumnetController implements Initializable {
public BinderDocumnetController() {
this.details = FXCollections.observableArrayList();
}
#Override
public void initialize(URL url, ResourceBundle rb) {
tblName.setCellValueFactory(new PropertyValueFactory<CData, String>("strName"));
tblRemarks.setCellValueFactory(new PropertyValueFactory<CData, String>("strRemarks"));
tblData.setItems(details);
tblData.setEditable(true);
Callback<TableColumn<CData, String>, TableCell<CData, String>> para4cellFactory
= new Callback<TableColumn<CData, String>, TableCell<CData, String>>() {
public TableCell call(TableColumn p) {
return new EditingCell();
}
};
tblRemarks.setCellFactory(para4cellFactory);
htmlEditor.setOnKeyReleased(new EventHandler<KeyEvent>()
{
#Override
public void handle(KeyEvent t) {
textField.setText(htmlEditor.getHtmlText());
System.out.println("row no. is "+tblData.getSelectionModel().getSelectedIndex());
tblData.getItems().get(tblData.getSelectionModel().getSelectedIndex()).setStrRemarks(htmlEditor.getHtmlText());
System.out.println(" data at row no. "+tblData.getSelectionModel().getSelectedIndex()+"is");
System.out.println(" "+tblData.getItems().get(tblData.getSelectionModel().getSelectedIndex()).getStrRemarks());
}
}
);
textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
htmlEditor.setHtmlText(textField.getText());
}
});
}
public void onbtnAddClicked(){
System.out.println(" in add");
CData cdata= new CData("XYZ","done");
details.add(cdata);
}
#FXML
HTMLEditor htmlEditor;
#FXML
TextField textField;
ObservableList<CData> details;
#FXML
TableView<CData> tblData;
#FXML
TableColumn<CData,String> tblRemarks,tblName;
#FXML
Button btnAdd;
class EditingCell extends TableCell<Object, String> {
private TextField textField;
public EditingCell() {
}
#Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
createTextField();
setText(null);
setGraphic(textField);
textField.selectAll();
}
}
#Override
public void cancelEdit() {
super.cancelEdit();
setText((String) getItem());
setGraphic(null);
}
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setText(null);
setGraphic(textField);
} else {
setText(getString());
setGraphic(null);
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> arg0,
Boolean arg1, Boolean arg2) {
if (!arg2) {
commitEdit(textField.getText());
}
}
});
textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
htmlEditor.setHtmlText(textField.getText());
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
}
}
following is CData.java code
public class CData {
SimpleStringProperty strName = new SimpleStringProperty("");
SimpleStringProperty strRemarks = new SimpleStringProperty("");
public CData(String strName,String strRemarks) {
setStrName(strName);
setStrRemarks(strRemarks);
}
public String getStrName() {
return strName.get();
}
public void setStrName(String strName) {
this.strName.set(strName);
}
public String getStrRemarks() {
return strRemarks.get();
}
public void setStrRemarks(String strRemarks) {
this.strRemarks.set(strRemarks);
}
public SimpleStringProperty strName() {
return strName;
}
public SimpleStringProperty strRemarks() {
System.out.println("\nRemarks: "+strRemarks.get()+"\n\n");
return strRemarks;
}
}
public SimpleStringProperty strNameProperty() {
return strName;
}
public SimpleStringProperty strRemarksProperty() {
System.out.println("\nRemarks: "+strRemarks.get()+"\n\n");
return strRemarks;
}
Done changes to above code now its working

Categories