Is there a way to configure a DatePicker to accept a custom format in addition to the currently supported formats?
For example - instead of the user typing "04/06/2016" into the field, they could enter "04062016" or "04.06.2016"?
Currently I can see that the acceptable separators are a "/" and a "-".
Thanks!
You can define as many patterns as you want, and in your Converter check if the entered date fits any of them.
private final List<String> patterns = Arrays.asList(
"MM/dd/yyyy", "MMddyyyy", "MM.dd.yyyy");
#Override
public void start(Stage stage) {
DatePicker datePicker = new DatePicker();
datePicker.setConverter(new StringConverter<LocalDate>() {
#Override
public String toString(LocalDate date) {
if (date != null) {
for (String pattern : patterns) {
try {
return DateTimeFormatter.ofPattern(pattern).format(date);
} catch (DateTimeException dte) { }
}
System.out.println("Format Error");
}
return "";
}
#Override
public LocalDate fromString(String string) {
if (string != null && !string.isEmpty()) {
for (String pattern : patterns) {
try {
return LocalDate.parse(string, DateTimeFormatter.ofPattern(pattern));
} catch (DateTimeParseException dtpe) { }
}
System.out.println("Parse Error");
}
return null;
}
});
}
There's an even more clear example in the docs here now.
Related
What i am trying to do is display the response from a POST message on to the HTML loaded in my webview. However, the my webview appears blank. I can see the response message by in LogCat by printing it out. However, again my webview appears blank. Example.html is the page loading in my webview. My implementation is below:
private void startSchedule()
{
for(int i=0;i<temPojoData.size();i++)
{
tempPojo tem =temPojoData.get(i);
/////////////////////// Daily and AllDays functionality start here //////////////////
if(tem.getDaysweekmonth().equals("Daily") )
{
if(tem.getDaysbases().equals("AllDays")) {
if (findDateBTwoDates(tem.getStartDate(), tem.getEndDate())) {
Log.i("Daily Date", "Today Available");
layoutID += tem.getLayout();
}
}else if(tem.getDaysbases().equals("Whole Day")){
}else if(tem.getDaysbases().equals("Morning"))
{ scheduleStartTimes.add(tem.getStartTime());
}else if(tem.getDaysbases().equals("After Noon"))
{ scheduleStartTimes.add(tem.getStartTime());
}else if(tem.getDaysbases().equals("Evening"))
{ scheduleStartTimes.add(tem.getStartTime());
}else if(tem.getDaysbases().equals("Night"))
{ scheduleStartTimes.add(tem.getStartTime());
}else if(tem.getDaysbases().equals("Choose Time"))
{ scheduleStartTimes.add(tem.getStartTime());
}
}
/////////////////////// Weekly and AllDays functionality start here //////////////////
else if(tem.getDaysweekmonth().equals("weekly") && tem.getDaysbases().equals("AllDays"))
{
if(tem.getDaysbases().equals("AllDays")) {
}
}
/////////////////////// Monthly and AllDays functionality start here //////////////////
else if(tem.getDaysweekmonth().equals("montly") && tem.getDaysbases().equals("AllDays"))
{
if(tem.getDaysbases().equals("AllDays")) {
}
}
}
}
private void findTimeBTwoTimes(String sTime,String eTime)
{
try {
String string1 = "20:11:13";
Date time1 = new SimpleDateFormat("HH:mm:ss").parse(string1);
Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(time1);
String string2 = "14:49:00";
Date time2 = new SimpleDateFormat("HH:mm:ss").parse(string2);
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(time2);
calendar2.add(Calendar.DATE, 1);
String someRandomTime = "01:00:00";
Date d = new SimpleDateFormat("HH:mm:ss").parse(someRandomTime);
Calendar calendar3 = Calendar.getInstance();
calendar3.setTime(d);
calendar3.add(Calendar.DATE, 1);
Date x = calendar3.getTime();
if (x.after(calendar1.getTime()) && x.before(calendar2.getTime())) {
//checkes whether the current time is between 14:49:00 and 20:11:13.
System.out.println(true);
}
} catch (ParseException e) {
e.printStackTrace();
}
}
private boolean findDateBTwoDates(String sDate,String eDate)
{
try {
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
String s = sDate.replace(" AM","");
String e = eDate.replace(" AM","");
String oeStartDateStr =sDate.replace("PM","");
String oeEndDateStr =eDate.replace("PM","");
Log.i("Start End Date ",sDate+"------------"+eDate);
Calendar cal = Calendar.getInstance();
Integer year = cal.get(Calendar.YEAR);
Date startDate = sdf.parse(oeStartDateStr);
Date endDate = sdf.parse(oeEndDateStr);
Date d = new Date();
String currDt = sdf.format(d);
if ((d.after(startDate) && (d.before(endDate))) || (currDt.equals(sdf.format(startDate)) || currDt.equals(sdf.format(endDate)))) {
System.out.println("Date is between 1st april to 14th nov...");
return true;
}
/*else {
System.out.println("Date is not between 1st april to 14th nov...");
}*/
}catch (Exception e){}
return false;
}
I will explain this in a sudo code so that you can come up with a solution.
The first point to your answer is that -> No, you cannot do it in a straightforward manner. The reason behind this is that MongoDB does not have/support joins. Like in SQL where you can join two tables and query them for conditional results; the same is not doable in MongoDB.
But do not lose hope. You cannot do a join on the DB side but you can certainly come up with a solution on the driver/application side. What I would suggest you to do is as follows. (I am using the JAVA driver and Morphia so my solutions' arrangement may look specific to them)
Have a DAO interface for both collections seperately
public interface MyDAO1 extends DAO<MyClass1, ObjectId>
{
public MyClass1 getByName(String name);
}
public interface MyDAO2 extends DAO<MyClass2, ObjectId>
{
public MyClass2 getByResult(int result);
}
First make implementation classes for both the above interfaces. That's pretty simple so I am skipping it to move on to the real part. Have an implementation of the interface
public class MyDAOImpl extends BasicDAO<MyClass, ObjectId> implements MyDAO1, MyDAO2
{
public MyClass1 getByName (String name)
{
MyClass1 output= query collection1 with with the Name;
return output;
}
public MyClass2 getByResult (int result)
{
MyClass2 output= query collection2 with with the result;
return output;
}
public void getByNameResult (String name, int result)
{
MyClass1 output1 = getByName (name);
MyClass2 output2 = getByResult (result);
print them in however format you want OR create a string;
}
}
please note:
MyClass1 is the #Entity class for the employee collection
MyClass2 is the #Entity class for the result collection
I've implemented a custom autocomplete text field in a cn1 app, but I've noticed it only loads the suggestions list once, after that any change in the text doesn't trigger a change in the list, and the getSuggestionModel() is never called again. How can I achieve this (in my mind, basic) functionality?
This is my autocomplete class:
public class ForumNamesAutocomplete extends AutoCompleteTextField {
List<String>suggestions = new LinkedList<String>();
List<Map<String,Object>> fData;
StateMachine mac;
int currentIndex;
String prevText;
public static final String KEY_FORUM_NAME = "name";
public static final String KEY_FORUM_ID = "id";
public static final String KEY_FORUM_DESC = "desc";
public ForumNamesAutocomplete(StateMachine sm){
super();
mac = sm;
if(sm.forumData != null){
fData = mac.forumData;
}
}
#Override
protected boolean filter(String text) {
if(text.equals(prevText)){
return false;
}
setSuggestionList(text);
fireDataChanged(DataChangedListener.CHANGED, text.length());
prevText = text;
return true;
}
#Override
public void fireDataChanged(int type, int index) {
super.fireDataChanged(type, index);
}
public void setSuggestionList(String s){
if(suggestions == null){
suggestions = new LinkedList<String>();
}else{
suggestions.clear();
}
LinkedList<String> descList = new LinkedList<String>();
for(int i = 0;i<fData.size();i++){
boolean used = false;
Map<String,Object> forumMap = fData.get(i);
if(((String)forumMap.get(KEY_FORUM_NAME)).indexOf(s) != -1){
suggestions.add((String)forumMap.get(KEY_FORUM_NAME));
used = true;
}
if(!used && ((String)forumMap.get(KEY_FORUM_DESC)).indexOf(s) != -1){
descList.add((String)forumMap.get(KEY_FORUM_NAME));
}
}
suggestions.addAll(descList);
}
#Override
protected ListModel<String> getSuggestionModel() {
return new DefaultListModel<String>(suggestions);
}
}
This used to be simpler and seems to be a bit problematic now as explained in this issues.
Technically what you need to do is return one model and then mutate said model/fire modified events so everything will refresh. This is non-trivial and might not work correctly for all use cases so ideally we should have a simpler API to do this as we move forward.
After additional debugging, I saw that the getSuggestionModel() method was being called only during initialization, and whatever the suggestion list (in suggestion object) was at that point, it remained so. Instead I needed to manipulate the underlying ListModel object:
public class ForumNamesAutocomplete extends AutoCompleteTextField {
ListModel<String>myModel = new ListModel<String>();
...
#Override
protected boolean filter(String text) {
if(text.length() > 1){
return false;
}
setSuggestionList(text);
return true;
}
private void setSuggestionList(String s){
if(myModel == null){
myModel = new ListModel<String>();
}else{
while(myModel.getSize() > 0)
myModel.removeItem(0);
}
for(int i = 0;i<fData.size();i++){
boolean used = false;
Map<String,Object> forumMap = fData.get(i);
if(((String)forumMap.get(KEY_FORUM_NAME)).indexOf(s) != -1){
myModel.addItem((String)forumMap.get(KEY_FORUM_NAME));
used = true;
}
if(!used && ((String)forumMap.get(KEY_FORUM_DESC)).indexOf(s) != -1){
myModel.addItem((String)forumMap.get(KEY_FORUM_NAME));
}
}
}
...
}
Hi everyone !!
I'm working with JavaFX and the JDK 8.
I got a TableView filled by a database with the use of a JavaFX POJO Class "Inputs". I've implemented TexField cells, ComboBoxes cells and Checkbox cells succesfully.
But I am not able to make it working with DatePicker Control: the event on the "setOnEditComit" is never invoked...
Hre is my code:
Declarations for TableColumn:
#FXML
private TableColumn<Inputs,LocalDate> colDate = new TableColumn<Inputs,LocalDate>();
[...]
colDate.setCellValueFactory(
new PropertyValueFactory<Inputs,LocalDate>("localdate"));
Callback<TableColumn<Inputs, LocalDate>, TableCell<Inputs, LocalDate>> dateCellFactory =
new Callback<TableColumn<Inputs, LocalDate>, TableCell<Inputs, LocalDate>>() {
public TableCell call(TableColumn p) {
return new EditingDatePickerCell();
}
};
[...]
colDate.setOnEditCommit(
new EventHandler<CellEditEvent<Inputs, LocalDate>>() {
#Override
public void handle(CellEditEvent<Inputs, LocalDate> event) {
System.out.println("EVENT!!!!");
((Inputs) event.getTableView().getItems().get(
event.getTablePosition().getRow())
).setDatePicker(event.getNewValue());
}
}
);
With these JavaFX POJO Objects declarations:
public ObjectProperty<LocalDate> localdate;
[...]
this.localdate = new SimpleObjectProperty<LocalDate>(localdate);
[...]
public LocalDate getDatePicker() {
return localdate.getValue();
}
[...]
public void setDatePicker(LocalDate value) {
System.out.println("EVENT!!!!");
localdate.setValue(value);
}
[...]
public ObjectProperty<LocalDate> localdateProperty() {
return localdate;
}
EditingDatePickerCell class:
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import com.desktop.newapp.utils.Inputs;
public class EditingDatePickerCell <Inputs, LocalDate> extends TableCell<Inputs, LocalDate> {
#Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
createDatePicker();
setText(null);
setGraphic(datePicker);
datePicker.requestFocus();
}
}
#Override
public void cancelEdit() {
super.cancelEdit();
datePicker.setValue((java.time.LocalDate) getItem());
setGraphic(null);
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
private DatePicker datePicker;
public EditingDatePickerCell() {
if (datePicker == null) {
createDatePicker();
}
setGraphic(datePicker);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
Platform.runLater(new Runnable() {
#Override
public void run() {
datePicker.requestFocus();
}
});
}
#Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (datePicker != null && item != null) {
datePicker.setValue((java.time.LocalDate) getLocalDate());
commitEdit(getLocalDate());
}
setGraphic(datePicker);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
}
private void createDatePicker() {
datePicker = new DatePicker();
datePicker.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
setGraphic(datePicker);
datePicker.addEventFilter(KeyEvent.KEY_PRESSED,new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
commitEdit(getLocalDate());
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
} else if (t.getCode() == KeyCode.TAB) {
commitEdit(getLocalDate());;
}
}
});
setAlignment(Pos.CENTER);
}
private LocalDate getLocalDate() {
return getItem();
///return datePicker.getValue() != null ? datePicker.getValue() : getItem();
}
}
I've been Googling a lot and I didn't find any correct implementation of the Java8 DatePicker Editing capabilities in a JavaFX TableView. Any help would be very appreciate !!
Without Stackoverflow I'll never could done the quarter of the whole job so long life to Stackoverflow !!
Regards.
You need to put the table in editing mode (for the current row) when the user interacts with the picker. That can be achieved with an onShowingHandler like this (example is also with a color picker):
this.colorPicker.setOnShowing(event -> {
final TableView<T> tableView = getTableView();
tableView.getSelectionModel().select(getTableRow().getIndex());
tableView.edit(tableView.getSelectionModel().getSelectedIndex(), column);
});
then watch the valueProperty of the picker like this:
this.colorPicker.valueProperty().addListener((observable, oldValue, newValue) -> {
if(isEditing()) {
commitEdit(newValue);
}
});
For more explanation have a look at my blog post: Custom editor components in JavaFX TableCells.
Full Class:
public class ColorTableCell<T> extends TableCell<T, Color> {
private final ColorPicker colorPicker;
public ColorTableCell(TableColumn<T, Color> column) {
this.colorPicker = new ColorPicker();
this.colorPicker.editableProperty().bind(column.editableProperty());
this.colorPicker.disableProperty().bind(column.editableProperty().not());
this.colorPicker.setOnShowing(event -> {
final TableView<T> tableView = getTableView();
tableView.getSelectionModel().select(getTableRow().getIndex());
tableView.edit(tableView.getSelectionModel().getSelectedIndex(), column);
});
this.colorPicker.valueProperty().addListener((observable, oldValue, newValue) -> {
if(isEditing()) {
commitEdit(newValue);
}
});
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
#Override
protected void updateItem(Color item, boolean empty) {
super.updateItem(item, empty);
setText(null);
if(empty) {
setGraphic(null);
} else {
this.colorPicker.setValue(item);
this.setGraphic(this.colorPicker);
}
}
}
I was having the same issues but i ended up solving it with this post. JavaFX8 – Render a DatePicker Cell in a TableView.
The outcome is illustrated in the image below.
Your Model object is a bit strange. The setDatePicker and getDatePicker methods should be called setLocaldate and getLocaldate, to be consistent with the localdateProperty() method and (possibly importantly) the parameter passed to the PropertyValueFactory.
I don't think that would cause the problem you observe, though, and I can't see what else is wrong.
This example works for me.
Have a look and see if you can see what I did that's different...
here is a datapicker cell edit when pressing tab key and go to the next cell
datePicker.setOnKeyPressed /EventHandler doesnot work with tab
datePicker.EventFilter get called twice
to work arround this you need to add a listner to tableview cell and get date text as string and cast it to localdate
addEventFilter to TableCell deduction object is a sample
=> addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler() {...}
public class DatePickerCell extends TableCell<Deduction, LocalDate> {
private DatePicker datePicker;
private TableColumn column;
// private TableCell cell;
public DatePickerCell(TableColumn column) { //
super();
this.column = column;
this.datePicker = new DatePicker(getDate());
}
#Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
createDatePicker();
setText(null);
setGraphic(datePicker);
Platform.runLater(new Runnable() {
#Override
public void run() {
datePicker.requestFocus();
}
});
//Platform.runLater(datePicker::requestFocus);
}
}
#Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
// SimpleDateFormat smp = new SimpleDateFormat("dd/MM/yyyy");
/* if (null == this.datePicker) {
System.out.println("datePicker is NULL");
}*/ //TO be reviewed
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (datePicker != null) {
datePicker.setValue(getItem());
}
setText(null);
setGraphic(datePicker);
} else {
setText(getItem().toString());
setGraphic(null);
}
}
}
private LocalDate getDate() {
return getItem() == null ? LocalDate.now() : getItem();
}
private void createDatePicker() {
this.datePicker = new DatePicker(getDate());
datePicker.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
this.datePicker.editableProperty().bind(column.editableProperty());
this.datePicker.disableProperty().bind(column.editableProperty().not());
this.datePicker.setOnShowing(event -> {
final TableView tableView = getTableView();
tableView.getSelectionModel().select(getTableRow().getIndex());
tableView.edit(tableView.getSelectionModel().getSelectedIndex(), column);
});
datePicker.setOnAction((e) -> {
commitEdit(datePicker.getValue());
TableColumn nextColumn = getNextColumn(true);
if (nextColumn != null) {
getTableView().edit(getTableRow().getIndex(),
nextColumn);
}
});
datePicker.focusedProperty().addListener(
new ChangeListener<Boolean>() {
#Override
public void changed(
ObservableValue<? extends Boolean> arg0,
Boolean arg1, Boolean arg2) {
if (!arg2) {
commitEdit(datePicker.getValue());
}
}
});
datePicker.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
// System.out.println("setOnKeyPressed datapicker get value ...." + t.getCode());
/* if (t.getCode() == KeyCode.ENTER) {
commitEdit(datePicker.getValue());
System.out.println("Enter datapicker get value " + datePicker.getValue());
} else */if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
} else if (t.getCode() == KeyCode.ENTER){
commitEdit(datePicker.getValue());
// System.out.println("Tab datapicker get value " + datePicker.getValue());
TableColumn nextColumn = getNextColumn(!t.isShiftDown());
// System.out.println("nextColumn datapicker get value " + nextColumn.getId());
if (nextColumn != null) {
getTableView().edit(getTableRow().getIndex(),
nextColumn);
}
}
}
});
addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if (event.getCode() == KeyCode.TAB) {
commitEdit(LocalDate.parse(datePicker.getEditor().getText(), DateTimeFormatter.ofPattern("dd/MM/yyyy")));
TableColumn nextColumn = getNextColumn(true);
if (nextColumn != null) {
getTableView().edit(getTableRow().getIndex(),
nextColumn);
}
}
}
});
//
// // setAlignment(Pos.CENTER);
}
#Override
public void cancelEdit() {
super.cancelEdit();
setText(getItem().toString());
setGraphic(null);
}
public DatePicker getDatePicker() {
return datePicker;
}
public void setDatePicker(DatePicker datePicker) {
this.datePicker = datePicker;
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
private TableColumn<Deduction, ?> getNextColumn(boolean forward) {
List<TableColumn<Deduction, ?>> columns = new ArrayList<>();
for (TableColumn<Deduction, ?> 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<Deduction, ?>> getLeaves(
TableColumn<Deduction, ?> root) {
List<TableColumn<Deduction, ?>> 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<Deduction, ?> column : root.getColumns()) {
columns.addAll(getLeaves(column));
}
return columns;
}
}
}
in your class with the tableview
Callback cellFactoryDate
= new Callback<TableColumn, TableCell>() {
public TableCell call(TableColumn p) {
return new DatePickerCell(p);//DatePickerTest(p) //DatePickerTest2 //EditingCellDate
}
};
dateColumn.setCellValueFactory(new PropertyValueFactory<>("date"));
// dateColumn.setCellFactory(cellFactoryTest);//cellFactoryDate
dateColumn.setCellFactory(cellFactoryDate);
dateColumn.setOnEditCommit(
new EventHandler<TableColumn.CellEditEvent<Deduction, LocalDate>>() {
#Override
public void handle(TableColumn.CellEditEvent<Deduction, LocalDate> t) {
((Deduction) t.getTableView().getItems().get(
t.getTablePosition().getRow())).setDate(t.getNewValue());
}
}
);
Here is a solution acceptable for all custom controls; this example use a ColorPicker control:
So finnaly I deal it like that: on the events of the controls I get back the POJO objects in use by the "((Inputs)getTableView().getItems().get(getTableRow().getIndex()" and I update similary like is it done in the OnEditCommit method...
So for me it's look like this (update the color):
((Inputs) getTableView().getItems().get(
getTableRow().getIndex())
).setColor(cp.getValue());
Here is example with ColorPickerCell
:
public class ColorPickerTableCell<Inputs> extends TableCell<Inputs, Color>{
private ColorPicker cp;
public ColorPickerTableCell(){
cp = new ColorPicker();
cp.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
commitEdit(cp.getValue());
updateItem(cp.getValue(), isEmpty());
((Inputs) getTableView().getItems().get(
getTableRow().getIndex())
).setColor(cp.getValue());
}
});
setGraphic(cp);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
setEditable(true);
}
#Override
protected void updateItem(Color item, boolean empty) {
super.updateItem(item, empty);
cp.setVisible(!empty);
this.setItem(item);
cp.setValue(item);
}
}
With this simple JavaFX's POJO:
public ObjectProperty<Color> color = new SimpleObjectProperty<Color>();
this.color = new SimpleObjectProperty(color);
public ObjectProperty<Color> colorProperty() {
return color;
}
public void setColor(Color color2) {
color.set(color2);
}
I do not know if it's a good way to achive that but it worked for me... Note that the JavaFX's POJO is only accessible within an "ActionEvent" request (combobox, datepicker, colorpicker, etc..)
Regards,
I have one [JavaFX] ComboBox that is populated with countries.
My object:
public static class CountryObj {
private String TCountryDescr;
private String TCountryCode;
private CountryObj(String CountryDescr,String CountryCode) {
this.TCountryDescr = CountryDescr;
this.TCountryCode = CountryCode;
}
public String getTCountryCode() {
return TCountryCode;
}
public void setTCountryCode(String fComp) {
TCountryCode= fComp;
}
public String getTCountryDescr() {
return TCountryDescr;
}
public void setCountryDescr(String fdescr) {
TCountryDescr = fdescr;
}
#Override
public String toString() {
return TCountryDescr;
}
}
Then I have my ObservableList:
private final ObservableList<CountryObj> CountrycomboList =
FXCollections.observableArrayList(
new CountryObj("United States", "US"),
new CountryObj("United Kingdom", "UK"),
new CountryObj("France", "FR"),
new CountryObj("Germany", "DE"));
Then my ComboBox which displays the name of the country and the code of the country is for my own use:
private ComboBox<CountryObj> cCountry1 = new ComboBox<>();
cbCountry1.setItems(CountrycomboList);
cbCountry1.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<CountryObj>() {
#Override
public void changed(ObservableValue<? extends CountryObj> arg0, CountryObj arg1, CountryObj arg2) {
if (arg2 != null) {
System.out.println("Selected Country: " + arg2.getTCountryCode());
}
}
});
How can I auto-select a country, for example Germany, if I only have the code of the country, which is "DE"?
comboBox.getSelectionModel().select(indexOfItem);
or
comboBox.setValue("item1");
Couple of months old question but here is more elegant solution for such type of problems.
Modify the CountryObj class and override the hashCode and equals functions as below:
public class CountryObj {
private String TCountryDescr;
private String TCountryCode;
public CountryObj(String CountryDescr,String CountryCode) {
this.TCountryDescr = CountryDescr;
this.TCountryCode = CountryCode;
}
public String getTCountryCode() {
return TCountryCode;
}
public void setTCountryCode(String fComp) {
TCountryCode= fComp;
}
public String getTCountryDescr() {
return TCountryDescr;
}
public void setCountryDescr(String fdescr) {
TCountryDescr = fdescr;
}
#Override
public String toString() {
return TCountryDescr;
}
#Override
public int hashCode() {
int hash = 0;
hash += (TCountryCode != null ? TCountryCode.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
String otherTCountryCode = "";
if (object instanceof Country) {
otherTCountryCode = ((Country)object).TCountryCode;
} else if(object instanceof String){
otherTCountryCode = (String)object;
} else {
return false;
}
if ((this.TCountryCode == null && otherTCountryCode != null) || (this.TCountryCode != null && !this.TCountryCode.equals(otherTCountryCode))) {
return false;
}
return true;
}
}
Now in you code if you will execute the following statement, it will automatically select "Germany" for you.
cmbCountry.getSelectionModel().select("DE")
You can also pass an object of CountryObj to select method above.
I think the simplest solution is to write an autoSelect function that finds the matching CountryObj in your ObservableList. Once you find the correct CountryObj, tell the combobox to set that as its value. It should looks something like this...
private void autoSelectCountry(String countryCode)
{
for (CountryObj countryObj : countryComboList)
{
if (countryObj.getTCountryCode().equals(countryCode))
{
cbCountry1.setValue(countryObj);
}
}
}
EDIT:
This can be further refactored to reusable method for all ComboBox'es that take different type parameter:
public static <T> void autoSelectComboBoxValue(ComboBox<T> comboBox, String value, Func<T, String> f) {
for (T t : comboBox.getItems()) {
if (f.compare(t, value)) {
comboBox.setValue(t);
}
}
}
where Func is an interface:
public interface Func<T, V> {
boolean compare(T t, V v);
}
How to apply this method:
autoSelectComboBoxValue(comboBox, "Germany", (cmbProp, val) -> cmbProp.getNameOfCountry().equals(val));
If both comboBox are from the same Array, assembly column one and two, then they have the same sequence. Then you can use the index.
a = comboBox1.getSelectionModel().getSelectedIndex();
comboBox2.getSelectionModel().select(a);
"United States" is on index position 1 "US" also on index position 1 then:
comboBox2.getSelectionModel().select(1); // is "US"
The solution of Brendan and Branislav Lazic is perfect, but we still can improve the call to the autoSelectComboBoxValue method :
public static <T, V> void autoSelectComboBoxValue(ComboBox<T> comboBox, V value, Func<T, V> f) {...}
:)
i know how to implement it,using field assist and search pattern, but the mechanism each time triggers a new search. I am not sure, how the mechanism is implemented in Open Type for example ( i think with indexes). How to use this cache to make in time classpath search
This almost my entire solution. Each time a call createProposalData
private TreeSet<String> data;
private SearchParticipant[] participants = new SearchParticipant[] { SearchEngine
.getDefaultSearchParticipant() };
private SearchPattern pattern;
private IJavaProject prj;
private JavaSearchScope scope;
private SearchEngine searchEngine = new SearchEngine();
private SearchRequestor requestor = new SearchRequestor() {
#Override
public void acceptSearchMatch(SearchMatch match) throws CoreException {
String text = getText(match.getElement());
if (text != null) {
data.add(text);
}
}
public String getText(Object element) {
...
}
};
public ProposalEngine(IJavaProject prj) {
super();
this.prj = prj;
scope = new JavaSearchScope();
try {
scope.add(prj);
} catch (JavaModelException e) {
//
}
}
public Collection<String> createProposalData(final String patternText) {
data = new TreeSet<String>();
try {
pattern = getPatternForSeach(patternText);
searchEngine.search(pattern, participants, scope, requestor, null);
} catch (Exception e) {
// skip
}
return data;
}
protected SearchPattern getPatternForSeach(String patternText) {
return SearchPattern.createPattern(patternText,
IJavaSearchConstants.CLASS_AND_INTERFACE,
IJavaSearchConstants.DECLARATIONS,
SearchPattern.R_CAMELCASE_MATCH);
}
I believe that you are doing exactly what the Open Type dialog is doing. Indexing to speed up search happens underneath JDT API.