I created a Panel in which Im trying to get live Ajax behaviour to some radio options.
The problem is that I can not set the current active option, in the setter "setSelectedLang", the parameter there is always null, even when I click on different radio options. How can that be fixed?
I am running Wicket version 7.5.0.
package xx.yy.admin
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.RadioChoice;
import org.apache.wicket.markup.html.panel.GenericPanel;
import org.apache.wicket.model.PropertyModel;
import xx.yy.admin.Survey;
import xx.yy.admin.AjaxListener;
import java.util.Arrays;
import java.util.List;
public class LanguageSelectionPanel extends GenericPanel<Void> {
private static final String SVENSKA = "Sve";
private static final String ENGELSKA = "Eng";
private AjaxListener listener;
private Form<Void> form;
private List<String> languages = Arrays.asList(SVENSKA, ENGELSKA);
private Survey surveyModel;
private String selectedLang = "Sve";
private RadioChoice languageRadioChoice;
public SurveyLanguageSelectionPanel(String id, Survey survey, AjaxListener listener) {
super(id);
this.surveyModel = survey;
this.listener = listener;
initialize();
}
protected void initialize() {
super.onInitialize();
form = new Form<Void>("langform") {
#Override
protected void onSubmit() {
info("Init : ");
}
};
add(form);
languageRadioChoice = getLanguageSelection();
form.add(languageRadioChoice);
}
private RadioChoice getLanguageSelection() {
RadioChoice<String> langRadioChoice = new RadioChoice<>("languages",
new PropertyModel<>(this, "selectedLang"), languages);
// Add Ajax Behaviour...
langRadioChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") {
protected void onUpdate(AjaxRequestTarget target) {
listener.onUpdate(target);
}
});
return langRadioChoice;
}
public void setSelectedLang(String selectedLang) {
this.selectedLang = selectedLang;
}
public String getSelectedLang() {
return selectedLang;
}
}
The html code:
<body>
<wicket:panel>
<form style="" class="" wicket:id="langform">
<wicket:enclosure child="languages">
<span wicket:id="languages"></span>
</wicket:enclosure>
<br/>
<hr/>
</form>
</wicket:panel>
</body>
</html>
You have to use "AjaxFormChoiceComponentUpdatingBehavior" as described here:
onchange get current value with radioChoice
i.e.
langRadioChoice.add(new AjaxFormChoiceComponentUpdatingBehavior() {
protected void onUpdate(AjaxRequestTarget target) {
listener.onUpdate(target);
}
});
Related
Problem:After the ActionEvent is triggered (selecting an account), the comboBox is null. When I run the program, I can see that the ComboBox is populated. I think I'm doing something wrong with the FXML loader. I read through the following document: https://openjfx.io/javadoc/12/javafx.fxml/javafx/fxml/doc-files/introduction_to_fxml.html#controllers
While thrilling (actually learned a lot), the document did not give me an answer to my problem. Please advise.... Referring me to another source for further education would be appreciated. If you need more information to answer the question, let me know.
Caused by: java.lang.NullPointerException: Cannot invoke "javafx.scene.control.ComboBox.setItems(javafx.collections.ObservableList)" because "this.accountComboBox" is null at application.budget/application.budget.Controller.initialize(Controller.java:67)
Line 67 is: accountComboBox.setItems(accountlist);
package application.budget;
import datamodel.Account;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import java.io.IOException;
import java.text.NumberFormat;
public class Controller {
public Button detacctinfo;
private Stage stage;
private Scene scene;
private Parent root;
#FXML
private Button createnewacct, Submit;
#FXML
private AnchorPane mainPanel;
#FXML
private ComboBox<Account> accountComboBox;
#FXML
Label acctbalField = new Label();
private NumberFormat fmt;
public void initialize () {
ObservableList<Account> accountlist = FXCollections.observableArrayList();
accountlist.add(new Account("Bank of America", 10010101.32));
accountlist.add(new Account("Prosperity Bank", 10010101.32));
//ComboBox<Account> selectacct = new ComboBox<>();
// Use a StringConverter to configure our ComboBox to display only the film's title
/* accountComboBox.setConverter(new StringConverter<Account>() {
#Override
public String toString(Account account) {
return account.getAccountName();
}
#Override
public Account fromString(String string) {
return accountComboBox.getItems().stream().filter(ap ->
ap.getAccountName().equals(string)).findFirst().orElse(null);
}
});*/
// Finally, set our ComboBox's items to our sample list
accountComboBox.setItems(accountlist);
System.out.println(accountlist);
}
public void OnItemSelected(ActionEvent e ) throws IOException {
root = FXMLLoader.load(getClass().getResource("AccountHome.fxml"));
Stage window = (Stage) Submit.getScene().getWindow();
window.setScene(new Scene(root));
}
}
package datamodel;
public class Account {
private String accountName;
private Double accountBalance;
public Account(String accountName, Double accountBalance) {
this.accountName = accountName;
this.accountBalance = accountBalance;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public Double getAccountBalance() {
return accountBalance;
}
public void setAccountBalance(Double accountBalance) {
this.accountBalance = accountBalance;
}
#Override //Esto dice que cuando un variable se usa, va a dar el valor de abajo
public String toString() {
return accountName;
}
public String getBalance() {
return String.valueOf(accountBalance);
}
}
Caused by: java.lang.NullPointerException: Cannot invoke "javafx.scene.control.ComboBox.setItems(javafx.collections.ObservableList)" because "this.accountComboBox" is null
at application.budget/application.budget.Controller.initialize(Controller.java:67)
Line 67 is: accountComboBox.setItems(accountlist);
After some research, it seems like each FXML document needs it's own controller. Been doing this for about 2 weeks. Excuse the lack of education on my part.
I have a problem i can't solve and I have spent a lot of time. I have a table and I have a column with hyperlinks. I have some filters added to the table and when I activate one of those filters, the hyperlink column doesn't refresh correctly. The code I implemented is showing above. This is an example you can copy&paste, run & reproduce the bug:
The Table class:
package borrar;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.Hyperlink;
public class Example {
private static TableViewer tViewer = null;
private static Table tblTrades = null;
private static Text txtTicker;
public static TickerFilter2 tickerFilter = new TickerFilter2();
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
Composite parent = new Composite(shell, SWT.NONE);
parent.setLayout(new FillLayout());
parent.setLayout(new GridLayout(1, true));
Label lblTicker = new Label(parent, SWT.NONE);
lblTicker.setText("Search: ");
txtTicker = new Text(parent, SWT.NONE);
txtTicker.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
txtTicker.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent ke) {
tickerFilter.setSearchText(txtTicker.getText());
tViewer.refresh();
}
});
tViewer = new TableViewer(parent, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION | SWT.CENTER);
String[] titles = { "Ticker", "Hyperlinks" };
createColumns(titles);
tblTrades = tViewer.getTable();
tViewer.setContentProvider(new ArrayContentProvider());
List<DataTable> dt = Arrays.asList(new DataTable("AAA", "ImagePath"), new DataTable("ABBBBBB", "ImagePath"),
new DataTable("BBBBBBB", "ImagePath"));
tViewer.setInput(dt);
tblTrades.setHeaderVisible(true);
tViewer.addFilter(tickerFilter);
shell.open();
shell.pack();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
private static void createColumns(String[] titles) {
TableViewerColumn col = createTableViewerColumn(titles[0], 70);
col.setLabelProvider(new ColumnLabelProvider() {
#Override
public String getText(Object element) {
DataTable op = (DataTable) element;
if (op.getTicker() != null) {
return op.getTicker();
} else {
return "";
}
}
});
col = createTableViewerColumn(titles[1], 80);
col.setLabelProvider(new ColumnLabelProvider() {
Map<Object, Hyperlink> hyperlinks = new HashMap<Object, Hyperlink>();
#Override
public void update(ViewerCell cell) {
TableItem item = (TableItem) cell.getItem();
final Hyperlink hyperlink;
if (hyperlinks.containsKey(cell.getElement()) && !hyperlinks.get(cell.getElement()).isDisposed()) {
hyperlink = hyperlinks.get(cell.getElement());
} else {
hyperlink = new Hyperlink((Composite) (cell.getViewerRow().getControl()), SWT.NONE);
if (cell.getElement() instanceof DataTable) {
DataTable trade = (DataTable) cell.getElement();
if (trade.getPath() != null && !trade.getPath().equals("")) {
hyperlink.setText(trade.getPath() + "-" + trade.getTicker());
hyperlink.setHref(trade.getPath());
}
}
hyperlink.addHyperlinkListener(new HyperlinkAdapter() {
public void linkActivated(HyperlinkEvent e) {
org.eclipse.swt.program.Program.launch(hyperlink.getHref().toString());
}
});
hyperlinks.put(cell.getElement(), hyperlink);
}
TableEditor editor = new TableEditor(item.getParent());
editor.grabHorizontal = true;
editor.grabVertical = true;
editor.setEditor(hyperlink, item, cell.getColumnIndex());
editor.layout();
}
});
}
private static TableViewerColumn createTableViewerColumn(String title, int bound) {
final TableViewerColumn viewerColumn = new TableViewerColumn(tViewer, SWT.CENTER);
final TableColumn column = viewerColumn.getColumn();
column.setText(title);
column.setWidth(bound);
column.setResizable(true);
column.setMoveable(true);
return viewerColumn;
}
public void refreshTable() {
tViewer.refresh();
}
}
My filter class:
package borrar;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
public class TickerFilter2 extends ViewerFilter {
private String searchString;
public void setSearchText(String s) {
// ensure that the value can be used for matching
this.searchString = ".*" + s + ".*";
}
#Override
public boolean select(Viewer viewer, Object parentElement, Object element) {
if (searchString == null || searchString.length() == 0) {
return true;
}
DataTable trade = (DataTable) element;
if (trade.getTicker().matches(searchString)) {
return true;
}
return false;
}
}
The data table object:
package borrar;
public class DataTable {
String ticker;
String path;
public DataTable(String ticker, String path) {
super();
this.ticker = ticker;
this.path = path;
}
public String getTicker() {
return ticker;
}
public void setTicker(String ticker) {
this.ticker = ticker;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
If you put in the search field a "z" or "l" for example, you can see that the hyperlink column does not filter.
The filter class filters data correctly but the hyperlinks column doesn't filter fine.
Here you have an image with the bad result:
The TableViewer doesn't really know about the TableEditor code so it doesn't deal with them when filtering.
You could perhaps use the EditingSupport code. The following code defines a cell editor which does an action as soon as you click on the column cell.
For the column definition replace your code with something like:
col.setLabelProvider(new ColumnLabelProvider() {
#Override
public String getText(final Object element) {
// Whatever you want for the cell text here
final DataTable op = (DataTable) element;
return op.getPath();
}
});
col.setEditingSupport(new HyperlinkEditingSupport(tViewer));
The editing support class:
public class HyperlinkEditingSupport extends EditingSupport
{
private final HyperlinkCellEditor _editor;
public HyperlinkEditingSupport(final TableViewer viewer)
{
super(viewer);
_editor = new HyperlinkCellEditor(viewer.getTable());
}
#Override
protected CellEditor getCellEditor(final Object element)
{
return _editor;
}
#Override
protected boolean canEdit(final Object element)
{
return true;
}
#Override
protected Object getValue(final Object element)
{
// Return the value you want launched
return ((DataTable)element).getPath();
}
#Override
protected void setValue(final Object element, final Object value)
{
// no action
}
}
And the CellEditor. This is a bit odd because we are just going to launch as soon as the editor is invoked so we don't really need a separate editor:
public class HyperlinkCellEditor extends CellEditor
{
public HyperlinkCellEditor(final Composite parent)
{
super(parent);
}
#Override
protected Control createControl(final Composite parent)
{
return new Composite(parent, SWT.None);
}
#Override
protected Object doGetValue()
{
return new Object[0];
}
#Override
protected void doSetFocus()
{
// no action
}
#Override
protected void doSetValue(final Object value)
{
final String path = (String)value;
// TODO Open the link
}
}
I have modified #greg-449 solution to show a link appearance in the cell only modifying the LabelProvider:
col.setLabelProvider(new StyledCellLabelProvider() {
#Override
public void update(ViewerCell cell) {
DataTable op = (DataTable) cell.getItem().getData();
StyledString ss = new StyledString();
StyleRange sr = new StyleRange(0, 80, Display.getCurrent().getSystemColor(SWT.COLOR_BLUE), null);
sr.underline = true;
ss.append(op.getPath(), StyledString.DECORATIONS_STYLER);
cell.setText("Open Image");
StyleRange[] range = { sr };
cell.setStyleRanges(range);
}
});
col.setEditingSupport(new HyperlinkEditingSupport(tViewer));
I am trying to get started with mapbox android and can't get any of the example projects to work.
My problem is with the imports
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import com.mapbox.mapboxandroiddemo.R;
I get I "cannot resolve symbol annotation", "cannot resolve symbol v7" and "cannot resolve symbol mapboxandroiddemo".
I feel like this is some android problem that I am just not understanding correctly so if anyone has some insight that would be amazing. I have tried taking out some code and using the recommended bug fixes but all that has done is break my project.
Here is the entire MainActivity.java file
package com.example.mapboxtut;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatActivity;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.FeatureCollection;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxandroiddemo.R;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
import com.mapbox.mapboxsdk.utils.BitmapUtils;
import static com.mapbox.mapboxsdk.style.expressions.Expression.get;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAllowOverlap;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconIgnorePlacement;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textAllowOverlap;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textField;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textIgnorePlacement;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textOffset;
/**
* Use the {#link MapView#addOnStyleImageMissingListener(MapView.OnStyleImageMissingListener)}
* to handle the situation where a SymbolLayer tries using a missing image as an icon. If an icon-image
* cannot be found in a map style, a custom image can be provided to the map via
* the listener.
*/
public class MissingIconActivity extends AppCompatActivity {
private static final String ICON_SOURCE_ID = "ICON_SOURCE_ID";
private static final String ICON_LAYER_ID = "ICON_LAYER_ID";
private static final String PROFILE_NAME = "PROFILE_NAME";
private static final String CARLOS = "Carlos";
private static final String ANTONY = "Antony";
private static final String MARIA = "Maria";
private static final String LUCIANA = "Luciana";
private MapView mapView;
private MapboxMap mapboxMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Mapbox access token is configured here. This needs to be called either in your application
// object or in the same activity which contains the mapview.
Mapbox.getInstance(this, getString(R.string.access_token));
// This contains the MapView in XML and needs to be called after the access token is configured.
setContentView(R.layout.activity_styles_missing_icon);
mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(#NonNull final MapboxMap mapboxMap) {
// Add Features which represent the location of each profile photo SymbolLayer icon
Feature carlosFeature = Feature.fromGeometry(Point.fromLngLat(-7.9760742,
41.2778064));
carlosFeature.addStringProperty(PROFILE_NAME, CARLOS);
Feature antonyFeature = Feature.fromGeometry(Point.fromLngLat(-8.0639648,
37.5445773));
antonyFeature.addStringProperty(PROFILE_NAME, ANTONY);
Feature mariaFeature = Feature.fromGeometry(Point.fromLngLat(-9.1845703,
38.9764924));
mariaFeature.addStringProperty(PROFILE_NAME, MARIA);
Feature lucianaFeature = Feature.fromGeometry(Point.fromLngLat(-7.5146484,
40.2459915));
lucianaFeature.addStringProperty(PROFILE_NAME, LUCIANA);
// Use a URL to build and add a Style object to the map. Then add a source to the Style.
mapboxMap.setStyle(
new Style.Builder().fromUrl(Style.LIGHT)
.withSource(new GeoJsonSource(ICON_SOURCE_ID,
FeatureCollection.fromFeatures(new Feature[] {
carlosFeature,
antonyFeature,
mariaFeature,
lucianaFeature}))),
new Style.OnStyleLoaded() {
#Override
public void onStyleLoaded(#NonNull Style style) {
MissingIconActivity.this.mapboxMap = mapboxMap;
// Add a SymbolLayer to the style. iconImage is set to a value that will
// be used later in the addOnStyleImageMissingListener below
style.addLayer(new SymbolLayer(ICON_LAYER_ID, ICON_SOURCE_ID).withProperties(
iconImage(get(PROFILE_NAME)),
iconIgnorePlacement(true),
iconAllowOverlap(true),
textField(get(PROFILE_NAME)),
textIgnorePlacement(true),
textAllowOverlap(true),
textOffset(new Float[] {0f, 2f})
));
}
});
}
});
// Use the listener to match the id with the appropriate person. The correct profile photo is
// given to the map during "runtime".
mapView.addOnStyleImageMissingListener(new MapView.OnStyleImageMissingListener() {
#Override
public void onStyleImageMissing(#NonNull String id) {
switch (id) {
case CARLOS:
addImage(id, R.drawable.carlos);
break;
case ANTONY:
addImage(id, R.drawable.antony);
break;
case MARIA:
addImage(id, R.drawable.maria);
break;
case LUCIANA:
addImage(id, R.drawable.luciana);
break;
default:
addImage(id, R.drawable.carlos);
break;
}
}
});
}
private void addImage(String id, int drawableImage) {
Style style = mapboxMap.getStyle();
if (style != null) {
style.addImageAsync(id, BitmapUtils.getBitmapFromDrawable(
getResources().getDrawable(drawableImage)));
}
}
// Add the mapView lifecycle to the activity's lifecycle methods
#Override
public void onResume() {
super.onResume();
mapView.onResume();
}
#Override
protected void onStart() {
super.onStart();
mapView.onStart();
}
#Override
protected void onStop() {
super.onStop();
mapView.onStop();
}
#Override
public void onPause() {
super.onPause();
mapView.onPause();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
#Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
}
when i filter recyclerview it shows Not found .My Searchview not working.when i run the code its result in Not Found i think there is problem in onQueryTextChange
myfilter function also did not work
#Override
public boolean onQueryTextSubmit(String query) {
Toast.makeText(SecondActivity1.this, "Name is : " + query, Toast.LENGTH_SHORT).show();
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
final List<DatabaseModel> filteredModelList = filter(dbList, newText);
if (filteredModelList.size() > 0) {
// Toast.makeText(SecondActivity1.this, "Found", Toast.LENGTH_SHORT).show();
recyclerAdapter.setFilter(filteredModelList);
return true;
} else {
Toast.makeText(SecondActivity1.this, "Not Found", Toast.LENGTH_SHORT).show();
return false;
}
private List filter(List models, String query) {
query = query.toLowerCase();
recyclerAdapter.notifyDataSetChanged();
final List<DatabaseModel> filteredModelList = new ArrayList<>();
// mRecyclerView.setLayoutManager(new LinearLayoutManager(SecondActivity1.this));
// mRecyclerView.setAdapter(RecyclerAdapter);
for (DatabaseModel model : models) {
final String text = model.getName().toLowerCase();
if (text.contains(query)) {
filteredModelList.add(model);
}
}
return filteredModelList;
//
}
here is filter method which recieve parameter(dblist,newtext) filter method recieves these method when i use toast its show that it takes newText But didnot filter this.i checked many sites but this is same in many sites points.when i enter name toast shows name which i enter but it did not filter
RecyclerAdapter.java
package com.example.prabhu.databasedemo;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/**
* Created by user_adnig on 11/14/15.
*/
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
List<DatabaseModel> dbList;
static Context context;
RecyclerAdapter(Context context, List<DatabaseModel> dbList ){
this.dbList = new ArrayList<>();
this.context = context;
this.dbList = (ArrayList<DatabaseModel>) dbList;
}
#Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.item_row, null);
// create ViewHolder
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerAdapter.ViewHolder holder, int position) {
holder.name.setText(dbList.get(position).getName());
holder.email.setText(dbList.get(position).getEmail());
}
#Override
public int getItemCount() {
return dbList.size();
}
public void setFilter(List<DatabaseModel> countryModels) {
// Toast.makeText(RecyclerAdapter.this,"Method is called", Toast.LENGTH_SHORT).show();
dbList = new ArrayList<>();
dbList.addAll(countryModels);
notifyDataSetChanged();
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView name,email;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
name = (TextView) itemLayoutView
.findViewById(R.id.rvname);
email = (TextView)itemLayoutView.findViewById(R.id.rvemail);
itemLayoutView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Intent intent = new Intent(context,DetailsActivity.class);
Bundle extras = new Bundle();
extras.putInt("position",getAdapterPosition());
intent.putExtras(extras);
/*
int i=getAdapterPosition();
intent.putExtra("position", getAdapterPosition());*/
context.startActivity(intent);
Toast.makeText(RecyclerAdapter.context, "you have clicked Row " + getAdapterPosition(), Toast.LENGTH_LONG).show();
}
}
}
this is my recyclerAdapterCode.i also used Recycleradapter.setFilter(filterModeList) method but it did not work for me.i think in my set filter method error which i did not solve yet.
. But when I clear the search widget I don't get the full list instead I get the empty RecyclerView.
I'm using javafx to do some table stuff. I want to validate my textfields in the myTextRow Class. In the "setText2" method I check the input if it is not bigger than 6 symbols, but it has no effects at all.
import java.util.ArrayList;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TextArea;
import javafx.util.Callback;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class Supermain extends Application {
#Override
public void start(Stage primaryStage) {
ArrayList myindizes=new ArrayList();
final TableView<myTextRow> table = new TableView<>();
table.setEditable(true);
table.setStyle("-fx-text-wrap: true;");
//Table columns
TableColumn<myTextRow, String> clmID = new TableColumn<>("ID");
clmID.setMinWidth(160);
clmID.setCellValueFactory(new PropertyValueFactory<>("ID"));
TableColumn<myTextRow, String> clmtext = new TableColumn<>("Text");
clmtext.setMinWidth(160);
clmtext.setCellValueFactory(new PropertyValueFactory<>("text"));
clmtext.setCellFactory(new TextFieldCellFactory());
TableColumn<myTextRow, String> clmtext2 = new TableColumn<>("Text2");
clmtext2.setMinWidth(160);
clmtext2.setCellValueFactory(new PropertyValueFactory<>("text2"));
clmtext2.setCellFactory(new TextFieldCellFactory());
//Add data
final ObservableList<myTextRow> data = FXCollections.observableArrayList(
new myTextRow(5, "Lorem","bla"),
new myTextRow(2, "Ipsum","bla")
);
table.getColumns().addAll(clmID, clmtext,clmtext2);
table.setItems(data);
HBox hBox = new HBox();
hBox.setSpacing(5.0);
hBox.setPadding(new Insets(5, 5, 5, 5));
Button btn = new Button();
btn.setText("Get Data");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
for (myTextRow data1 : data) {
System.out.println("data:" + data1.getText2());
}
}
});
hBox.getChildren().add(btn);
BorderPane pane = new BorderPane();
pane.setTop(hBox);
pane.setCenter(table);
primaryStage.setScene(new Scene(pane, 640, 480));
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
public static class TextFieldCellFactory
implements Callback<TableColumn<myTextRow, String>, TableCell<myTextRow, String>> {
#Override
public TableCell<myTextRow, String> call(TableColumn<myTextRow, String> param) {
TextFieldCell textFieldCell = new TextFieldCell();
return textFieldCell;
}
public static class TextFieldCell extends TableCell<myTextRow, String> {
private TextArea textField;
private StringProperty boundToCurrently = null;
public TextFieldCell() {
textField = new TextArea();
textField.setWrapText(true);
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
this.setGraphic(textField);
}
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
// Show the Text Field
this.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
// myindizes.add(getIndex());
// Retrieve the actual String Property that should be bound to the TextField
// If the TextField is currently bound to a different StringProperty
// Unbind the old property and rebind to the new one
ObservableValue<String> ov = getTableColumn().getCellObservableValue(getIndex());
SimpleStringProperty sp = (SimpleStringProperty) ov;
if (this.boundToCurrently == null) {
this.boundToCurrently = sp;
this.textField.textProperty().bindBidirectional(sp);
} else if (this.boundToCurrently != sp) {
this.textField.textProperty().unbindBidirectional(this.boundToCurrently);
this.boundToCurrently = sp;
this.textField.textProperty().bindBidirectional(this.boundToCurrently);
}
double height = real_lines_height(textField.getText(), this.getWidth(), 30, 22);
textField.setPrefHeight(height);
textField.setMaxHeight(height);
textField.setMaxHeight(Double.MAX_VALUE);
// if height bigger than the biggest height in the row
//-> change all heights of the row(textfields ()typeof textarea) to this height
// else leave the height as it is
//System.out.println("item=" + item + " ObservableValue<String>=" + ov.getValue());
//this.textField.setText(item); // No longer need this!!!
} else {
this.setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
}
}
public class myTextRow {
private final SimpleIntegerProperty ID;
private final SimpleStringProperty text;
private final SimpleStringProperty text2;
public myTextRow(int ID, String text,String text2) {
this.ID = new SimpleIntegerProperty(ID);
this.text = new SimpleStringProperty(text);
this.text2 = new SimpleStringProperty(text2);
}
public void setID(int id) {
this.ID.set(id);
}
public void setText(String text) {
this.text.set(text);
}
public void setText2(String text) {
if(text2check(text)){
this.text2.set(text);}
else
{System.out.println("wrong value!!!");}
}
public int getID() {
return ID.get();
}
public String getText() {
return text.get();
}
public StringProperty textProperty() {
return text;
}
public String getText2() {
return text2.get();
}
public StringProperty text2Property() {
return text2;
}
public IntegerProperty IDProperty() {
return ID;
}
public boolean text2check(String t)
{
if(t.length()>6)return false;
return true;
}
}
private static double real_lines_height(String s, double width, double heightCorrector, double widthCorrector) {
HBox h = new HBox();
Label l = new Label("Text");
h.getChildren().add(l);
Scene sc = new Scene(h);
l.applyCss();
double line_height = l.prefHeight(-1);
int new_lines = s.replaceAll("[^\r\n|\r|\n]", "").length();
// System.out.println("new lines= "+new_lines);
String[] lines = s.split("\r\n|\r|\n");
// System.out.println("line count func= "+ lines.length);
int count = 0;
//double rest=0;
for (int i = 0; i < lines.length; i++) {
double text_width = get_text_width(lines[i]);
double plus_lines = Math.ceil(text_width / (width - widthCorrector));
if (plus_lines > 1) {
count += plus_lines;
//rest+= (text_width / (width-widthCorrector)) - plus_lines;
} else {
count += 1;
}
}
//count+=(int) Math.ceil(rest);
count += new_lines - lines.length;
return count * line_height + heightCorrector;
}
private static double get_text_width(String s) {
HBox h = new HBox();
Label l = new Label(s);
l.setWrapText(false);
h.getChildren().add(l);
Scene sc = new Scene(h);
l.applyCss();
// System.out.println("dubbyloop.FXMLDocumentController.get_text_width(): "+l.prefWidth(-1));
return l.prefWidth(-1);
}
}
A rule of the JavaFX Properties pattern is that for a property x, invoking xProperty().setValue(value) should always be identical to invoking setX(value). Your validation makes this not true. The binding your cell implementation uses invokes the setValue method on the property, which is why it bypasses your validation check.
(Side note: in all the code I am going to change the names so that they adhere to proper naming conventions.)
The default way to implement a property in this pattern is:
public class MyTextRow {
private final StringProperty text = new SimpleStringProperty();
public StringProperty textProperty() {
return text ;
}
public final void setText(String text) {
textProperty().set(text);
}
public final String getText() {
return textProperty().get();
}
}
By having the set/get methods delegate to the appropriate property methods, you are guaranteed these rules are enforced, even if the textProperty() methods is overridden in a subclass. Making the set and get methods final ensures that the rule is not broken by a subclass overriding those methods.
One approach might be to override the set and setValue methods in the property, as follows:
public class MyTextRow {
private final StringProperty text2 = new StringPropertyBase() {
#Override
public String getName() {
return "text2";
}
#Override
public Object getBean() {
return MyTextRow.this ;
}
#Override
public void setValue(String value) {
if (text2Check(value)) {
super.setValue(value);
}
}
#Override
public void set(String value) {
if (text2Check(value)) {
super.set(value);
}
}
}
public StringProperty text2Property() {
return text2 ;
}
public final void setText2(String text2) {
text2Property().set(text2);
}
public final String getText2() {
return text2Property().get();
}
// ...
}
however, I think this will break the bidirectional binding that you have with the text property in the TextArea (basically, there is no way to communicate back to the text area when a change is vetoed, so the text area will not know to revert to the previous value). One fix would be to implement your cell using listeners on the properties instead of bindings. You could use a TextFormatter on the text area that simply updates the property and vetoes the text change if the change doesn't occur.
Here is a complete SSCCE using this approach:
import java.util.function.Function;
import java.util.function.UnaryOperator;
import javafx.application.Application;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.property.StringPropertyBase;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextFormatter;
import javafx.scene.control.TextFormatter.Change;
import javafx.stage.Stage;
public class VetoStringChange extends Application {
#Override
public void start(Stage primaryStage) {
TableView<Item> table = new TableView<>();
table.setEditable(true);
table.getColumns().add(column("Item", Item::nameProperty));
table.getColumns().add(column("Description", Item::descriptionProperty));
for (int i = 1; i <= 20 ; i++) {
table.getItems().add(new Item("Item "+i, ""));
}
primaryStage.setScene(new Scene(table, 600, 600));
primaryStage.show();
}
public static <S> TableColumn<S,String> column(String title, Function<S,Property<String>> property) {
TableColumn<S,String> col = new TableColumn<>(title);
col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
col.setCellFactory(tc -> new TextAreaCell<S>(property));
col.setPrefWidth(200);
return col ;
}
public static class TextAreaCell<S> extends TableCell<S, String> {
private TextArea textArea ;
public TextAreaCell(Function<S, Property<String>> propertyAccessor) {
textArea = new TextArea();
textArea.setWrapText(true);
textArea.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
textArea.setMaxHeight(Double.MAX_VALUE);
UnaryOperator<Change> filter = c -> {
String proposedText = c.getControlNewText() ;
Property<String> prop = propertyAccessor.apply(getTableView().getItems().get(getIndex()));
prop.setValue(proposedText);
if (prop.getValue().equals(proposedText)) {
return c ;
} else {
return null ;
}
};
textArea.setTextFormatter(new TextFormatter<String>(filter));
this.setGraphic(textArea);
}
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
if (! textArea.getText().equals(item)) {
textArea.setText(item);
}
// Show the Text Field
this.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
} else {
this.setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
}
public static class Item {
private final StringProperty name = new StringPropertyBase() {
#Override
public Object getBean() {
return Item.this;
}
#Override
public String getName() {
return "name" ;
}
#Override
public void set(String value) {
if (checkValue(value)) {
super.set(value);
}
}
#Override
public void setValue(String value) {
if (checkValue(value)) {
super.setValue(value);
}
}
};
private final StringProperty description = new SimpleStringProperty();
public Item(String name, String description) {
setName(name);
setDescription(description);
}
private boolean checkValue(String value) {
return value.length() <= 6 ;
}
public final StringProperty nameProperty() {
return this.name;
}
public final String getName() {
return this.nameProperty().get();
}
public final void setName(final String name) {
this.nameProperty().set(name);
}
public final StringProperty descriptionProperty() {
return this.description;
}
public final String getDescription() {
return this.descriptionProperty().get();
}
public final void setDescription(final String description) {
this.descriptionProperty().set(description);
}
}
public static void main(String[] args) {
launch(args);
}
}
Another approach is to allow a "commit and revert" type strategy on your property:
public class MyTextRow {
private final StringProperty text2 = new SimpleStringProperty();
public MyTextRow() {
text2.addListener((obs, oldText, newText) -> {
if (! checkText2(newText)) {
// sanity check:
if (checkText2(oldText)) {
text2.set(oldText);
}
}
});
}
public StringProperty text2Property() {
return text ;
}
public final void setText2(String text2) {
text2Property().set(text2);
}
public final String getText2() {
return text2Property().get();
}
}
In general I dislike validation by listening for an invalid value and reverting like this, because other listeners to the property will see all the changes, including changes to and from invalid values. However, this might be the best option in this case.
Finally, you could consider vetoing invalid changes as in the first option, and also setting a TextFormatter on the control in the cell that simply doesn't allow text entry that results in an invalid string. This isn't always possible from a usability perspective (e.g. if empty strings are invalid, you almost always want to allow the user to temporarily delete all the text), and it means keeping two validation checks in sync in your code, which is a pain.