'Named Singleton' with Google Guice - dependency-injection

i try to implement '#Named' injection but i do not want to predefine the #Named instances (i have an example at the end, which is actually working... but not the way i want - as i predefine the names)
its easier to provide an code example than explaining what i mean.
public class NamedSingletonExample {
private static Map<String, DoubleProperty> dMap = new HashMap<String, DoubleProperty>();
public static DoubleProperty getNamedDoubleProperty(String name) {
DoubleProperty d = dMap.get(name);
if (d == null) {
d = new SimpleDoubleProperty();
dMap.put(name, d);
}
return d;
}
#Test
public void testNamedSingleton() {
System.out.println("test()");
DoubleProperty d0 = getNamedDoubleProperty("d0");
DoubleProperty d1 = getNamedDoubleProperty("d1");
DoubleProperty d0_2 = getNamedDoubleProperty("d0");
d0.set(1);
d1.set(2);
d0_2.set(4);
System.out.println("expected: false & actual -> " + (d0.get() == d1.get()));
System.out.println("expected: true & actual -> " + (d0.get() == d0_2.get()));
System.out.println("expected: true & actual -> " + (d0 == d0_2));
}
}
and this is the way i expect it to work using guice
public class NamedSingletonConsumer {
#Inject
public NamedSingletonConsumer(//
#Named("d0") DoubleProperty d0, //
#Named("d1") DoubleProperty d1, //
#Named("d0_2") DoubleProperty d0_2//
) {
// ...
}
}
i read loads of in other questions here on StackOverflow and used google (including guice doc) but was not able to find an example for this.
now the "working" example:
public class AllInOneExample {
public AllInOneExample() {
Injector injector = Guice.createInjector(new AllInOneExample.DoublePropertyModule());
DoublePropertyConsumer consumer = injector.getInstance(DoublePropertyConsumer.class);
consumer.test();
}
public static void main(String[] args) {
new AllInOneExample();
}
static class DoublePropertyConsumer {
DoubleProperty d0;
DoubleProperty d1;
DoubleProperty d0_2;
#Inject
public DoublePropertyConsumer(//
#Named("d0") DoubleProperty d0, //
#Named("d1") DoubleProperty d1, //
#Named("d0_2") DoubleProperty d0_2//
) {
this.d0 = d0;
this.d1 = d1;
this.d0_2 = d0_2;
}
public void test() {
System.out.println("test()");
d0.set(1);
d1.set(2);
d0_2.set(4);
System.out.println("expected: false & actual -> " + (d0.get() == d1.get()));
System.out.println("expected: true & actual -> " + (d0.get() == d0_2.get()));
System.out.println("expected: true & actual -> " + (d0 == d0_2));
}
}
static class DoublePropertyFactory {
private Map<String, DoubleProperty> dMap = new HashMap<String, DoubleProperty>();
public DoubleProperty buildProperty(String name) {
DoubleProperty d = dMap.get(name);
if (d == null) {
d = new SimpleDoubleProperty();
dMap.put(name, d);
}
return d;
}
}
static class DoublePropertyModule extends AbstractModule {
#Override
protected void configure() {
DoublePropertyFactory doublePropertyFactory = new DoublePropertyFactory();
requestInjection(doublePropertyFactory);
// bind(DoubleProperty.class).annotatedWith(Named.class).toInstance(doublePropertyFactory .buildProperty(???)));
bind(DoubleProperty.class).annotatedWith(Names.named("d0"))
.toInstance(doublePropertyFactory.buildProperty("d0"));
bind(DoubleProperty.class).annotatedWith(Names.named("d1"))
.toInstance(doublePropertyFactory.buildProperty("d1"));
bind(DoubleProperty.class).annotatedWith(Names.named("d0_2"))
.toInstance(doublePropertyFactory.buildProperty("d0"));
}
}
}

Related

Vaadin Combobox and LazyInitializationException

My question maybe simple simple but I don't understand why Vaadin combobox tries to get a colletion of nested entities set in a combobox if I do not call these items of collection.
See this:
#Entity
public class Estado extends AbstractEntity {
private String nome;
private String sigla;
#OneToMany(mappedBy = "estado")
private List<Municipio> municipios;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getSigla() {
return sigla;
}
public void setSigla(String sigla) {
this.sigla = sigla;
}
public List<Municipio> getMunicipios() {
return municipios;
}
public void setMunicipios(List<Municipio> municipios) {
this.municipios = municipios;
}
private void initCbEstados() {
if (cbEstados.isEmpty()) {
List<Estado> estados = estadoService.findAllEager();
cbEstados.setItems(estados);
}
cbEstados.addValueChangeListener(e -> updateCbMunicipios());
cbEstados.setClearButtonVisible(true);
cbEstados.setItemLabelGenerator(Estado::getNome);
cbEstados.setWidth("50%");
}
private void updateViewToEdit(){
if (isEditMode) {
Estado estado = entity.getEndereco().getEstado();
***//this throws LazyInitializationException***
cbEstados.setValue(estado);
updateCbMunicipios();
}
I do not call at any time estado.getMunicipios. But apparently the behavior of the combobox tries to infer in the municipios released the exception.
Is this expected behavior?
I don't think it should be?
Sory, fisrt post on stack overflow and i was not familiar with the platform and ended not posting the entire code. The error occurred in
cbEstados.addValueChangeListener(e -> updateCbMunicipios());
that during the debug was not visible because it was occurring within the vaadin classes. The problem was solved by searching for the municpios in updateCbMunicpios(); So when FormBase calls beforeEnter(BeforeEnterEvent event) the readBean() set values on cbEstados that fires ValuechangeListener and load the LazeInicializaTionExceptions because Entity comes from the Request Scoope and not Fully filed to set the Value of Municipio in cbMunicipios. And cbMunicipios would be empty firing anhoter error from Vaadin.
public class FornecedorForm extends CadastroFormBaseGenerics<Fornecedor, FornecedorService> {
private static final long serialVersionUID = -5599427454458715210L;
EstadoService estadoService;
#PropertyId("ativo")
private Checkbox ckAtivo;
#PropertyId("razaoSocial")
private TextField txtRazaoSocial;
#PropertyId("nomeFantasia")
private TextField txtNomeFantasia;
#PropertyId("cnpj")
private TextField txtCnpj;
#PropertyId("contato")
private TextField txtContato;
#PropertyId("telefoneContato")
private TextField txtTelContato;
#PropertyId("telefone")
private TextField txtTelefone;
#PropertyId("observacao")
TextArea txtObservacao;
private ComboBox<Estado> cbEstados;
private ComboBox<Municipio> cbMunicipios;
private TextField txtCep;
private TextField txtLogradouro;
private TextField txtNumero;
private TextField txtComplemento;
#PropertyId("emailContato")
EmailField txtEmailContato;
private FormLayout layout;
HorizontalLayout layoutEstado;
public FornecedorForm(#Autowired EstadoService estadoService) {
super(Fornecedor.class, "Fornecedor");
this.estadoService = estadoService;
updateViewToEdit();
}
protected void configureAdditionalBinds() {
getBinder().bind(cbEstados, "endereco.estado");
getBinder().bind(cbMunicipios, "endereco.municipio");
getBinder().bind(txtCep, "endereco.cep");
getBinder().bind(txtLogradouro, "endereco.logradouro");
getBinder().bind(txtNumero, "endereco.numero");
getBinder().bind(txtComplemento, "endereco.complemento");
}
private void initCbEstados() {
cbEstados = new ComboBox<Estado>("Estado");
List<Estado> estados = estadoService.findAllEager();
cbEstados.setItems(estados);
cbEstados.addValueChangeListener(e -> updateCbMunicipios());
cbEstados.setClearButtonVisible(true);
cbEstados.setItemLabelGenerator(Estado::getNome);
cbEstados.setWidth("50%");
}
private void initCbMunicpios() {
cbMunicipios = new ComboBox<Municipio>("Município");
cbMunicipios.setItemLabelGenerator(Municipio::getNome);
cbMunicipios.setWidth("50%");
cbMunicipios.setReadOnly(true);
}
private void updateCbMunicipios() {
if (cbEstados.getValue() != null) {
cbMunicipios.clear();
cbMunicipios.setReadOnly(false);
Estado estado = estadoService.findMunicipios(cbEstados.getValue());
cbMunicipios.setItems(estado.getMunicipios());
} else {
cbMunicipios.clear();
cbMunicipios.setReadOnly(true);
}
}
#Override
protected void initViewComponents() {
layoutEstado = new HorizontalLayout();
layout = new FormLayout();
layoutEstado.setSizeFull();
initCbEstados();
initCbMunicpios();
ckAtivo = new Checkbox("Ativo ?", true);
txtRazaoSocial = new TextField("Razão Social");
txtNomeFantasia = new TextField("Nome Fantasia");
txtCnpj = new TextField("CNPJ");
txtCnpj.setWidth("25%");
// txtCnpj.setErrorMessage("CNPJ Incorreto.");
// txtCnpj.setPattern("^[0-9]{2}?[-s.]?[0-9]{3}[-s.]?[0-9]{3}[-s/]?[0-9]{4}[-s-]?[0-9]{2}$");
txtTelefone = new TextField("Telefone");
txtContato = new TextField("Nome Contato");
txtTelContato = new TextField("Telefone Contato");
txtEmailContato = new EmailField("Email Contato");
txtEmailContato.setClearButtonVisible(true);
txtEmailContato.setErrorMessage("Formato do E-mail incorreto");
txtEmailContato.setRequiredIndicatorVisible(false);
txtLogradouro = new TextField("Logradouro");
txtNumero = new TextField("Número");
txtNumero.setWidth("50px");
txtCep = new TextField("CEP");
txtCep.setPattern("^[0-9]{5}?[-s-]?[0-9]{3}$");
txtCep.setPlaceholder("00000-000");
txtCep.setRequired(true);
txtCep.setErrorMessage("Informe o CEP");
txtCep.setWidth("75px");
txtComplemento = new TextField("Complemento");
txtObservacao = new TextArea("Observações");
layout.add(ckAtivo, 2);
layout.add(txtCnpj, 2);
layout.add(txtRazaoSocial, txtNomeFantasia);
layout.add(layoutEstado, 2);
layout.add(txtLogradouro, txtNumero);
layout.add(txtComplemento, txtCep, txtTelefone);
HorizontalLayout layoutContato = new HorizontalLayout(txtContato, txtTelContato, txtEmailContato);
layoutContato.setSizeFull();
txtContato.setWidth("40%");
txtEmailContato.setWidth("40%");
txtTelContato.setWidth("20%");
layout.add(layoutContato, 2);
layout.add(txtObservacao, 2);
super.formLayout.add(layout);
layoutEstado.add(cbEstados, cbMunicipios);
configureAdditionalBinds();
}
protected void updateViewToEdit() {
if (isEditMode) {
Estado estado = entity.getEndereco().getEstado();
estado = estadoService.findMunicipios(estado);
cbEstados.setValue(estado);
}
}
#Override
protected void getNewEntityToPersist() {
entity = new Fornecedor();
entity.setEndereco(new Endereco());
ckAtivo.setValue(true);
}
}
public abstract class CadastroFormBaseGenerics<T, SERVICE extends ServiceInterface<T>> extends FormLayout
implements BeforeEnterObserver {
private static final long serialVersionUID = 7069232922824142288L;
protected T entity;
#Autowired
private SERVICE service;
private final Class<T> beanClass;
private Binder<T> binder;
private String nomeDoBean;
protected boolean isEditMode;
private Button btnSave = new Button("Salvar");
private Button btnDelete = new Button("Excluir");
private Button btnCancel = new Button("Cancelar");
protected VerticalLayout formLayout = new VerticalLayout();;
private HorizontalLayout buttonsLayout = new HorizontalLayout();
public CadastroFormBaseGenerics(Class<T> beanClass, String nomeDoBean) {
this.beanClass = beanClass;
this.nomeDoBean = nomeDoBean;
}
protected abstract void initViewComponents();
#PostConstruct
private void inicialize() {
checkEditMode();
initBinder();
initViewComponents();
addComponentAsFirst(formLayout);
configureFormLayout();
getEntityToEdit();
updateViewToEdit();
}
protected abstract void updateViewToEdit();
protected void initBinder() {
binder = new BeanValidationBinder<T>(beanClass);
}
protected void setPlaceHolders(String beanName) {
String primeiraLetra = "" + beanName.charAt(0);
primeiraLetra = primeiraLetra.toUpperCase();
char letraMaiuscula = primeiraLetra.charAt(0);
char[] cArray = beanName.toCharArray();
cArray[0] = letraMaiuscula;
beanName = new String(cArray);
for (int i = 0; i < formLayout.getComponentCount(); i++) {
Component c = formLayout.getComponentAt(i);
if (c.getClass().getName().equals("com.vaadin.flow.component.textfield.TextField")) {
TextField aux = (TextField) c;
aux.setPlaceholder(aux.getLabel() + " " + beanName + "...");
aux.setClearButtonVisible(true);
}
}
}
protected void configureFormLayout() {
formLayout.setSizeFull();
// formLayout.setMargin(true);
formLayout.setSpacing(true);
formLayout.setPadding(true);
formLayout.setAlignItems(Alignment.AUTO);
formLayout.setMargin(true);
// add(formLayout, 2);
configureButtonsLayout();
}
void configureButtonsLayout() {
btnDelete.setVisible(false);
btnSave.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
btnDelete.addThemeVariants(ButtonVariant.LUMO_ERROR);
buttonsLayout = new HorizontalLayout();
buttonsLayout.add(btnSave, btnDelete, btnCancel);
buttonsLayout.setMargin(true);
buttonsLayout.setPadding(true);
buttonsLayout.setSizeFull();
configureButtonEvents();
add(buttonsLayout, 2);
}
private void configureButtonEvents() {
btnSave.addClickListener(saveEvent -> save());
btnDelete.addClickListener(deleteEvent -> delete());
btnCancel.addClickListener(cancelEvent -> clearForm());
}
private void save() {
String msg = nomeDoBean + " Alterada(o) com sucesso.";
if (!isEditMode) {
msg = nomeDoBean + " Cadastrada(o) com sucesso.";
getNewEntityToPersist();
// getNewEntity();
}
try {
getBinder().writeBean(entity);
service.save(entity);
clearForm();
showSucess(msg);
} catch (DoisCsCrudException e) {
showWarnig(nomeDoBean + " já cadastrado. Verique.");
logException(e, "Metodo save()");
} catch (ValidationException e) {
showWarnig("Verique os campos obrigatórios.");
}
}
/**
* {#summary} Você deve implementar o {#code} entity = New POJO este método é
* chamado toda vez que {#code} save() para criar um novo BEAN a ser persistido.
*/
protected abstract void getNewEntityToPersist();
private void delete() {
try {
service.delete(entity);
clearForm();
showSucess(nomeDoBean + " removida(o) com sucesso.");
} catch (DoisCsCrudException e) {
showWarnig(nomeDoBean + " não pode ser removida(o), pois existem registros que dependem dele. %/n "
+ "Inative-o para que não seja mais exibido.");
}
}
#SuppressWarnings("unchecked")
private void getEntityToEdit() throws ClassCastException {
if (isEditMode) {
btnDelete.setVisible(true);
this.entity = (T) VaadinServletRequest.getCurrent().getAttribute("entityToEdit");
}
}
private boolean checkEditMode() {
if (VaadinServletRequest.getCurrent().getAttribute("entityToEdit") != null) {
isEditMode = true;
} else {
isEditMode = false;
}
return isEditMode;
}
/**
* Sempre deve ser chamado após um click no botão salvar, cancelar ou excluir
*/
protected void clearForm() {
// Desabilita o botão para excluir um Bean Cadastrado
btnDelete.setVisible(false);
// Seta editmode para falso, garantido que a proxima interação
// seja com um bean novo
isEditMode = false;
clearBinder();
}
protected void clearBinder() {
binder.readBean(null);
}
protected void showSucess(String message) {
createNotification(message, NotificationVariant.LUMO_SUCCESS, 3000);
}
protected void showError(String message) {
createNotification(message, NotificationVariant.LUMO_ERROR, 5000);
}
protected void showWarnig(String message) {
createNotification(message, NotificationVariant.LUMO_CONTRAST, 10000);
}
private void createNotification(String message, NotificationVariant variant, int duration) {
Notification n = new Notification(message);
n.setDuration(7000);
n.addThemeVariants(variant);
n.setPosition(Position.TOP_CENTER);
n.open();
}
protected void logException(Exception e, String logDesc) {
System.out.println("################ " + logDesc.toUpperCase() + " $$ " + getClass().getSimpleName()
+ " ################");
e.printStackTrace();
}
public Binder<T> getBinder() {
return binder;
}
#Override
public void beforeEnter(BeforeEnterEvent event) {
binder.bindInstanceFields(this);
if (entity != null) {
getBinder().readBean(entity);
}
}
}

Return IEnumerable of a property of the Key in a Map

Suppose I have the following classes:
public class X
{
public string a;
public string b;
}
public class Y
{
public string c;
}
and I have a Map:
var myMap = Map<X, Y>();
How do I return a list of a (IEnumerable<string>) from this?
I am trying to write:
myMap.Keys.Select(_ => _.a);
But this won't work. What am I missing?
The code you've written actually works fine as long as you are using System.Linq. However, if you want to create a non-empty map, your key class (X) has to derive from Record<T> as well, like this:
using System;
using System.Linq;
using LanguageExt;
using static LanguageExt.Prelude;
public class X : Record<X>
{
public string a;
public string b;
public static X Create(string a, string b)
=> new X() { a = a, b = b };
}
public class Y
{
public string c;
public static Y Create(string c)
=> new Y() { c = c };
}
class Program
{
static void Main(string[] args)
{
var myMap =
Map(
(X.Create("a1", "b1"), Y.Create("c1")),
(X.Create("a2", "b2"), Y.Create("c2")));
foreach (var str in myMap.Keys.Select(_ => _.a))
{
Console.WriteLine(str);
}
}
}
Output is:
a1
a2

Vaadin Validate date, not empty

Im trying to write validation in Vaadin but I don't understand how to check if date field is empty
I wrote something like this
#Override
public void setConfiguration(EditorConfiguration editorConfiguration) {
boolean required = ((DateFieldConfiguration) editorConfiguration).isRequired();
if (required == true) {
setRequiredIndicatorVisible(true);
addValueChangeListener(event -> validate(event.getSource().getDefaultValidator(), event.getValue()));
}
}
private void validate(Validator<LocalDate> defaultValidator, LocalDate localDate) {
binder.forField(this).withValidator(validator).asRequired("Mandatory").bind(s -> getValue(),
(b, v) -> setValue(v));
}
I have achived a validation with a text field:
String Validator code
public class VaadinStringEditor extends TextField implements HasValueComponent<String> {
/**
*
*/
private static final long serialVersionUID = 6271513226609012483L;
private Binder<String> binder;
#PostConstruct
public void init() {
setWidth("100%");
binder = new Binder<>();
}
#Override
public void initDefaults() {
setValue("");
binder.validate();
}
#Override
public void setConfiguration(EditorConfiguration editorConfiguration) {
Validator<String> validator = ((TextFieldConfiguration) editorConfiguration).getValidator();
if (validator != null) {
binder.forField(this).withValidator(validator).asRequired("Mandatory").bind(s -> getValue(),
(b, v) -> setValue(v));
}
and I valid it here:
question.setEditorConfiguration(new TextFieldConfiguration(textRequiredValidator()));
Validator:
private Validator<String> textRequiredValidator() {
return Validator.from(v -> v != null && StringUtils.trimAllWhitespace((String) v).length() != 0,
, "Not empty");
}
You should use com.vaadin.ui.DateField for LocalDate values. Have a look at the following example.
Example bean:
public class MyBean {
private LocalDate created;
public LocalDate getCreated() {
return created;
}
public void setCreated(LocalDate created) {
this.created = created;
}
}
Editor
DateField dateField = new DateField("Date selector");
binder.forField(dateField)
.bind(MyBean::getCreated, MyBean::setCreated);
If for some reason you would like to have com.vaadin.ui.TextField for editing date, then you need to set converter like this:
Binder<MyBean> binder = new Binder<>();
TextField textDateField = new TextField("Date here:");
binder.forField(textDateField)
.withNullRepresentation("")
.withConverter(new StringToLocalDateConverter())
.bind(MyBean::getCreated, MyBean::setCreated);
Converter implementation:
public class StringToLocalDateConverter implements Converter<String, LocalDate> {
#Override
public Result<LocalDate> convertToModel(String userInput, ValueContext valueContext) {
try {
return Result.ok(LocalDate.parse(userInput));
} catch (RuntimeException e) {
return Result.error("Invalid value");
}
}
#Override
public String convertToPresentation(LocalDate value, ValueContext valueContext) {
return Objects.toString(value, "");
}
}
Note that this converter does not utilise ValueContext object that contains information that should be taken into account in more complex cases. For example, user locale should be handled.

Recursive method not incrementing string analysis counter in TableView GUI (JavaFX)

EDIT Recursion is required for the counter increment.
I have a GUI that adds entered fields to a ListView, but also adds the name of the object to a TableView beside it and displays four substring counts. They are Plant objects, and it's supposed to display in the ListView (which it does), and then display the name with each occurrence of a certain substring:
See here:
I don't understand what I'm missing, because in my addButtonClick method, I call my recursive method. The logic seems correct to me in the method, so I must be missing something in my Integer properties, or a constructor.
Here is the method in the Controller for the add button click. There is a combo box where a user can choose Flower, Fungus, Weed, or Herb. And when the user clicks a respective plant type, respective radio buttons appear that are related to certain traits. All of that works. I will show the Flower section of code:
/*
Adds respective plant type and resets controls
*/
public void handleAddButtonClick(ActionEvent event) {
if (idInput != null && nameInput != null & colorInput != null) {
if (plantType.getValue().equals("Flower")) {
Flower flower = new Flower(ID, idNum, name, color, smell, thorns, edible, poisonous, flavor, medicine, seasonal);
flower.setID(idInput.getText());
flower.setName(nameInput.getText());
flower.setColor(colorInput.getText());
flower.setSmell(scentedRadio.isSelected());
flower.setThorns(thornyRadio.isSelected());
observablePlantList.add(flower);
//this is where the table information gets added.
//it adds it, just displays 0's.
flower.setPlantName(nameInput.getText());
Plant.substringCounter(name, "e"); //tried flower instead
Plant.substringCounter(name, "ar");//of Plant. still nothing.
Plant.substringCounter(name, "er");
Plant.substringCounter(name, "o");
observableAnalysisList.add(flower);
//just doing some debug printing. this prints 0
System.out.println(Plant.substringCounter(name, "e"));
//more debugging. this prints fine because of toString() method
System.out.println(flower);
Here is the relevant code in the main class and the Flower class:
//Plant Table properties ("e", "o", "ar", "er")
public StringProperty plantName = new SimpleStringProperty(this, "plantName", "");
public String getPlantName() {return plantName.get(); }
public StringProperty plantNameProperty() {return plantName; }
public void setPlantName(String plantName) {this.plantName.set(plantName); }
public IntegerProperty countLetterE = new SimpleIntegerProperty(this, "countLetterE", 0);
public int getLetterE() {return countLetterE.get();}
public IntegerProperty eProperty() {return countLetterE; }
public void setCountLetterE(int countLetterE) {this.countLetterE.set(countLetterE);}
public IntegerProperty countLetterO = new SimpleIntegerProperty(this, "countLetterO", 0);
public int getLetterO() {return countLetterO.get(); }
public IntegerProperty oProperty() {return countLetterO; }
public void setCountLetterO(int countLetterO) {this.countLetterO.set(countLetterO);}
public IntegerProperty countLetterER = new SimpleIntegerProperty(this, "countLetterER", 0);
public int getLetterER() {return countLetterER.get(); }
public IntegerProperty erProperty() {return countLetterER; }
public void setCountLetterER(int countLetterER) {this.countLetterER.set(countLetterER);}
public IntegerProperty countLetterAR = new SimpleIntegerProperty(this, "countLetterAR", 0);
public int getLetterAR() {return countLetterAR.get(); }
public IntegerProperty arProperty() {return countLetterAR; }
public void setCountLetterAR(int countLetterAR) {this.countLetterAR.set(countLetterAR);}
Recursive method:
public static int substringCounter(String plantName, String letters) {
plantName = plantName.toLowerCase();
if(plantName.isEmpty()) {
return 0;
}
if(plantName.indexOf(letters) == -1) {
return 0;
}
return 1 + substringCounter(plantName.substring(plantName.indexOf(letters) + 1), letters);
}
//toString method for Plant class to display in ListView. Works fine.
public String toString() {
return "ID: " + this.ID + "-" + this.idNum + ", Name: " + this.name + ", Color: " + this.color;
}
}
Flower class
public class Flower extends Plant {
public Flower(String ID, int idNum, String name, String color, boolean smell, boolean thorns, boolean edible, boolean poisonous, boolean flavor, boolean medicine, boolean seasonal) {
super(ID, idNum, name, color, smell, thorns, edible, poisonous, flavor, medicine, seasonal);
}
public void setSmell(boolean smell) {
this.smell = smell;
}
public void setThorns(boolean thorns) {
this.thorns = thorns;
}
//toString method for the ListView only. All works fine here
public String toString() {
return super.toString() + ", Scent? " + this.smell + ", Thorns? " + this.thorns;
}
}
I sincerely hope I either 1) gave you enough information, or 2) didn't give you too much information. Thank you all for any help offered.
You are invoking a static method on a string and return a number which effectively results in absolutely nothing when you call it like that:
Plant.substringCounter(name, "e");
You need to modify a property if you want some "action" or at least process the result that's being returned by substringCounter.
Besides, I have no idea why you use recursion. This does the same:
String text = "dandelion";
String search = "d";
int count = 0;
int pos = 0;
if (!search.isEmpty()) {
while ((pos = text.indexOf(search, pos)) != -1) {
count++;
pos++;
}
}
System.out.println(count);
Basically something like this:
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
HBox box = new HBox();
box.setSpacing(10);
TextField sourceTextField = new TextField( "Dandelion");
Label result = new Label();
TextField searchTextField = new TextField();
// add listener for counting the number of substrings
searchTextField.textProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
String sourceText = sourceTextField.getText().toLowerCase();
String searchText = newValue.toLowerCase();
int count = 0;
int pos = 0;
if( !searchText.isEmpty()) {
while( (pos = sourceText.indexOf( searchText, pos)) != -1) {
count++;
pos++;
}
}
result.setText( String.valueOf(count));
}
});
box.getChildren().addAll( new Label( "Search:"), searchTextField, new Label( "Text:"), sourceTextField, new Label( "Count:"), result);
Scene scene = new Scene(box, 600, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Or using your recursive method (you also need to check letters for empty string by the way):
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
HBox box = new HBox();
box.setSpacing(10);
TextField sourceTextField = new TextField( "Dandelion");
Label result = new Label();
TextField searchTextField = new TextField();
searchTextField.textProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
String sourceText = sourceTextField.getText().toLowerCase();
String searchText = newValue.toLowerCase();
result.setText( String.valueOf( substringCounter( sourceText, searchText)));
}
});
box.getChildren().addAll( new Label( "Search:"), searchTextField, new Label( "Text:"), sourceTextField, new Label( "Count:"), result);
Scene scene = new Scene(box, 600, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
public static int substringCounter(String plantName, String letters) {
plantName = plantName.toLowerCase();
if(letters.isEmpty()) {
return 0;
}
if(plantName.isEmpty()) {
return 0;
}
if(plantName.indexOf(letters) == -1) {
return 0;
}
return 1 + substringCounter(plantName.substring(plantName.indexOf(letters) + 1), letters);
}
public static void main(String[] args) {
launch(args);
}
}
Instead of setting the label like I did in the example you of course have to change your integer properties.

Keywordfilter field in blackberry

I used a keywordfilter for a list which is populated from db .Its working good .Imagine the list contains a phrase 'A big bat' and there are other words starting with 'b' like books etc .But when I give 'b' in the search field the phrase 'A big bat' appears first and then only words starting with 'b'.Please help me to fix it
please see my code
public final class KeywordFilter
{
private KeywordFilterField _keywordFilterField;
private WordList _wordList;
private Vector _words;
public KeywordFilter()
{
_words = getDataFromDatabase();
if(_words != null)
{
_wordList = new WordList(_words);
_keywordFilterField = new KeywordFilterField();
_keywordFilterField.setSourceList(_wordList, _wordList);
CustomKeywordField customSearchField = new CustomKeywordField();
_keywordFilterField.setKeywordField(customSearchField);
KeywordFilterScreen screen = new KeywordFilterScreen(this);
screen.setTitle(_keywordFilterField.getKeywordField());
screen.add(_keywordFilterField);
UiApplication ui = UiApplication.getUiApplication();
ui.pushScreen(screen);
}
else
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Error reading data file.");
System.exit(0);
}
});
}
}
KeywordFilterField getKeywordFilterField()
{
return _keywordFilterField;
}
private Vector getDataFromDatabase()
{
Vector words = new Vector();
Database d;
for(;;)
{
try
{
URI myURI=URI.create("file:///SDCard/Databases/MyTestDatabase.db");
d=DatabaseFactory.open(myURI);
Statement st=d.createStatement("select (select distinct group_concat(eng) fromEnglish),group_concat(mal) from English e ,Malayalam m where e.Ecode=m.Mcode group by eng");
st.prepare();
net.rim.device.api.database.Cursor c=st.getCursor();
Row r;
while(c.next())
{
r=c.getRow();
String w=r.getString(0);
String meaning=r.getString(1);
words.addElement(new Word(w,meaning));
}
st.close();
d.close();
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
e.printStackTrace();
}
return words;
}
}
void addElementToList(Word w)
{
_wordList.addElement(w);
_keywordFilterField.updateList();
}
final static class CustomKeywordField extends BasicEditField
{
CustomKeywordField()
{
super(USE_ALL_WIDTH|NON_FOCUSABLE|NO_LEARNING|NO_NEWLINE);
setLabel("Search: ");
}
protected boolean keyChar(char ch, int status, int time)
{
switch(ch)
{
case Characters.ESCAPE:
if(super.getTextLength() > 0)
{
setText("");
return true;
}
}
return super.keyChar(ch, status, time);
}
protected void paint(Graphics graphics)
{
super.paint(graphics);
getFocusRect(new XYRect());
drawFocus(graphics, true);
}
}
}
class KeywordFilterScreen extends MainScreen
{
private KeywordFilter _app;
private KeywordFilterField _keywordFilterField;
public KeywordFilterScreen(KeywordFilter app)
{
_app = app;
_keywordFilterField = _app.getKeywordFilterField();
}
protected boolean keyChar(char key, int status, int time)
{
if (key == Characters.ENTER)
{
displayInfoScreen();
// Word w = (Word)_keywordFilterField.getSelectedElement();
// Status.show(w.getMeaning());
return true;
}
return super.keyChar(key, status, time);
}
public boolean invokeAction(int action)
{
switch(action)
{
case ACTION_INVOKE:
displayInfoScreen();
return true;
}
return super.invokeAction(action);
}
private void displayInfoScreen()
{
Word w = (Word)_keywordFilterField.getSelectedElement();
if(w != null)
{
InfoScreen infoScreen = new InfoScreen(w);
UiApplication ui=UiApplication.getUiApplication();
ui.pushScreen(infoScreen);
}
}
public boolean onSavePrompt()
{
return true;
}
private final static class InfoScreen extends MainScreen
{
InfoScreen(Word w)
{
setTitle(w.toString());
BasicEditField popField = new BasicEditField(" ",w.getMeaning(),300,Field.NON_FOCUSABLE);
FontManager.getInstance().load("DC124.TTF", "MyFont", FontManager.APPLICATION_FONT) ;
{
try {
FontFamily typeface = FontFamily.forName("MyFont");
Font myFont = typeface.getFont(Font.PLAIN, 25);
popField.setFont(myFont);
add(popField);
} catch (ClassNotFoundException ex) {
ex.printStackTrace();}
}
}
}
}
This query is useful for you:
SELECT Name FROM Employee where Name like '%d%' order by Name;
Here Name is my column-name;
Try this;
I think you are using query like following
select colomname from tablename where colomname GLOB '%b%';
here you get all names which are contain letter 'b' (case sensitive)
if you want all words which are strted with letter 'b' use should writr query like
select colomname from tablename where colomname GLOB 'b%' order by colomname ;
here i am using "GLOB" it gives case sensitive to the out put records if you dont need case sensitive then you can use "LIKE" key word
thanks

Resources