Kafka consumer receive null value when sending customer object - serialization

So i want to implement application which reads data from json format files. And I have created customer object for the data in json. And I want to send these object through kafka topic. So far i have successfully send String message to producer to consumer. But when i try to send object, in the consumer side, when I do .value().toString(). I got null value. The following is the code I have used:
This is producer:
public class MyProducer {
public static void main(String[] args) throws Exception {
Properties properties = new Properties();
properties.put("bootstrap.servers", "kafka.kafka-cluster-shared.non-prod-5-az-scus.prod.us.walmart.net:9092");
properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("value.serializer", "xxxxxxxxx.KafkaJsonSerializer");
properties.put("acks", "1");
properties.put("retries", "2");
properties.put("batch.size", "16384");
properties.put("linger.ms", "1");
properties.put("buffer.memory", "33554432");
KafkaProducer<String, pharmacyData> kafkaProducer = new KafkaProducer<String, pharmacyData>(
properties);
String topic = "insights";
//try {
Gson gson = new Gson();
Reader reader = Files.newBufferedReader(Paths.get("......./part.json"));
List<pharmacyData> pdata = new Gson().fromJson(reader, new TypeToken<List<pharmacyData>>() {}.getType());
//pdata.forEach(System.out::println);
reader.close();
//} catch (Exception e) {
//e.printStackTrace();
//}
for (pharmacyData data : pdata) {
kafkaProducer.send(new ProducerRecord<String, pharmacyData>(topic, data), new Callback() {
#Override
public void onCompletion(RecordMetadata recordMetadata, Exception e) {
if (e == null) {
System.out.println(recordMetadata.partition() + "--" + recordMetadata.serializedValueSize());
} else {
e.printStackTrace();
}
}
});
}
kafkaProducer.close();
}
}
This is the customer object class:
public class pharmacyData {
private String load_date;
private String store_nbr;
private String state;
private String pmp_flag;
private String zero_flag;
private String submit_ts;
public pharmacyData(String load_date, String store_nbr, String state, String pmp_flag, String zero_flag, String submit_ts) {
this.load_date = load_date;
this.store_nbr = store_nbr;
this.state = state;
this.pmp_flag = pmp_flag;
this.zero_flag = zero_flag;
this.submit_ts = submit_ts;
}
public String getLoad_date() {
return load_date;
}
public void setLoad_date(String load_date) {
this.load_date = load_date;
}
public String getStore_nbr() {
return store_nbr;
}
public void setStore_nbr(String store_nbr) {
this.store_nbr = store_nbr;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getPmp_flag() {
return pmp_flag;
}
public void setPmp_flag(String pmp_flag) {
this.pmp_flag = pmp_flag;
}
public String getZero_flag() {
return zero_flag;
}
public void setZero_flag(String zero_flag) {
this.zero_flag = zero_flag;
}
public String getSubmit_ts() {
return submit_ts;
}
public void setSubmit_ts(String submit_ts) {
this.submit_ts = submit_ts;
}
#Override
public String toString() {
return "pharmacyData{" +
"load_date='" + load_date + '\'' +
", store_nbr='" + store_nbr + '\'' +
", state='" + state + '\'' +
", pmp_flag='" + pmp_flag + '\'' +
", zero_flag='" + zero_flag + '\'' +
", submit_ts='" + submit_ts + '\'' +
'}';
}
}
this is the customer Serializer:
public class KafkaJsonSerializer implements Serializer {
private Logger logger = LogManager.getLogger(this.getClass());
#Override
public void configure(Map map, boolean b) {
}
#Override
public byte[] serialize(String s, Object o) {
byte[] retVal = null;
ObjectMapper objectMapper = new ObjectMapper();
try {
retVal = objectMapper.writeValueAsBytes(o);
} catch (Exception e) {
logger.error(e.getMessage());
}
return retVal;
}
#Override
public void close() {
}
}
This is the customer Deserializer:
public class KafkaJsonDeserializer implements Deserializer {
#Override
public void configure(Map map, boolean b) {
}
#Override
public Object deserialize(String s, byte[] bytes) {
ObjectMapper mapper = new ObjectMapper();
pharmacyData pdata = null;
try {
pdata = mapper.readValue(bytes, pharmacyData.class);
} catch (Exception e) {
e.printStackTrace();
}
return pdata;
}
#Override
public void close() {
}
}
This is consumer:
public class MyConsumer {
public static void main(String[] args) {
Properties properties = new Properties();
properties.put("bootstrap.servers", "kafka.kafka-cluster-shared.non-prod-5-az-scus.prod.us.walmart.net:9092");
properties.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
properties.put("value.deserializer", "xxxxxxxx.KafkaJsonDeserializer");
properties.put("group.id", "consumer-group-1");
properties.put("enable.auto.commit", "true");
properties.put("auto.commit.interval.ms", "1000");
properties.put("auto.offset.reset", "earliest");
properties.put("session.timeout.ms", "30000");
KafkaConsumer<String, pharmacyData> consumer = new KafkaConsumer<>(properties);
String topic = "insights";
consumer.subscribe(Collections.singletonList(topic));
while (true) {
ConsumerRecords<String, pharmacyData> consumerRecords = consumer.poll(100);
for (ConsumerRecord<String, pharmacyData> consumerRecord : consumerRecords) {
System.out.println(consumerRecord.key() + "--" + consumerRecord.toString());
//System.out.println(consumerRecord.offset() + "--" + consumerRecord.partition());
}
}
}
}
Can someone please help me with the issues? Thank you very much!

Problem solved:
The solution of this issue just add a default constructor as below:
public pharmacyData() {
}
See this page for more details.

Related

Set RecyclerView itemTextView programmatically to BOLD based on Volley JSON response?

I populate a RecyclerView from JSON data pulled from a webserver using Volley. I have two columns called user1Read and user2Read that is yes or no. I would like to know how I can modify my Adapter to set the TypeFace to bold if the message is considered "unread"? I am unsure of how to access the TextView from within my onResponse logic. Should I create a member variable in my Messages model class? Should I create it in my Adapter? Where would be the best place to put this? In my JSON onResponse, it would be great if I could just say
onResponseMethod {
if(!hasRead) {
//set TypeFace BOLD here
//But how to access TextView???
}
}
My custom Adapter:
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 androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import de.hdodenhof.circleimageview.CircleImageView;
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.ViewHolder> implements Filterable {
private ArrayList<Message> messages;
private OnItemClickListener mListener;
#Override
public Filter getFilter() {
return null;
}
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
public MessageAdapter(ArrayList<Message> messages) {
this.messages = messages;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_list_item, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Message message = messages.get(position);
holder.username.setText(message.getUsername());
holder.messageSnippet.setText(message.getMessageSnippet());
holder.singleMessageTimestamp.setText(message.getTimestamp());
Picasso.get().load(message.getAvatarUrl()).into(holder.avatarCircleImageView);
}
#Override
public int getItemCount() {
if (messages != null) {
return messages.size();
} else {
return 0;
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
public final View view;
public final TextView username;
public final TextView messageSnippet;
public final TextView singleMessageTimestamp;
public final CircleImageView avatarCircleImageView;
public ViewHolder(View view) {
super(view);
this.view = view;
username = view.findViewById(R.id.message_item_username_textview);
messageSnippet = view.findViewById(R.id.message_item_message_snippet_textview);
singleMessageTimestamp = view.findViewById(R.id.message_item_timestamp);
avatarCircleImageView = view.findViewById(R.id.message_item_circle_avatar);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mListener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
mListener.onItemClick(position);
}
}
}
});
}
}
}
My Message Model:
import android.widget.ImageView;
public class Message {
private String username;
private String messageSnippet;
private String avatarUrl;
private String timestamp;
private ImageView dot;
public Message(String username, String message, String avatar, String timestamp) {
this.username = username;
this.messageSnippet = message;
this.avatarUrl = avatar;
this.timestamp = timestamp;
}
public Message(String username, String avatar) {
this.username = username;
this.avatarUrl = avatar;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getMessageSnippet() {
return messageSnippet;
}
public void setMessageSnippet(String messageSnippet) {
this.messageSnippet = messageSnippet;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public String getAvatarUrl() {
return avatarUrl;
}
public void setAvatarUrl(String avatarUrl) {
this.avatarUrl = avatarUrl;
}
}
My main Activity (MessagesActivity).
public class MessagesActivity extends AppCompatActivity implements MessageAdapter.OnItemClickListener {
private RecyclerView messages;
private MessageAdapter adapter;
private ImageView circle_avatar;
private TextView header_username_text;
private ImageView avatar;
private TextView username_heading;
private static JSONArray profile_array;
private static final String TAG = "MessagesActivity";
private static final String getMessagesUrl = "https://myURL.com/get_messages.php";
private static String username;
private static ProgressDialog messagesProgressDialog;
private static ArrayList<Message> list = new ArrayList<>();
private static JSONObject jsonObject;
private static Timer updateTimer;
private static String hasRead;
private static RecyclerView.LayoutManager mLayoutManager;
private DrawerLayout mDrawerLayout;
private ImageButton composeImageButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messages);
configureNavigationDrawer();
configureToolbar();
if(list != null) {
list.clear();
}
avatar = findViewById(R.id.profile_avatar);
username_heading = findViewById(R.id.username_text);
updateTimer = new Timer();
TimerTask updateTimerTask = new TimerTask() {
public void run() {
refreshMessages();
}
};
updateTimer.scheduleAtFixedRate(updateTimerTask, 3000, 3000);
messagesProgressDialog = new ProgressDialog(MessagesActivity.this, R.style.Custom_Progress_Dialog);
messagesProgressDialog.setIndeterminate(true);
messagesProgressDialog.setMessage("Fetching Messages...");
messagesProgressDialog.show();
SharedPreferences sharedPreferences = this.getSharedPreferences("MyPref", MODE_PRIVATE);
username = sharedPreferences.getString("username", null);
getProfile(username);
messages = findViewById(R.id.messages);
messages.addItemDecoration(new DividerItemDecoration(this, LinearLayout.VERTICAL));
ArrayList<Message> messages = initMessages();
mLayoutManager = new LinearLayoutManager(this);
this.messages.setLayoutManager(mLayoutManager);
adapter = new MessageAdapter(messages);
this.messages.setAdapter(adapter);
adapter.setOnItemClickListener(this);
getProfile(username);
composeImageButton = findViewById(R.id.custom_toolbar_image_button);
composeImageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "Clicked compose Image Button");
Intent composeIntent = new Intent(MessagesActivity.this, ComposeActivity.class);
startActivity(composeIntent);
updateTimer.cancel();
updateTimer.purge();
}
});
}
private ArrayList<Message> initMessages() {
RequestQueue messagesQueue = Volley.newRequestQueue(this);
StringRequest messagesRequest = new StringRequest(Request.Method.POST, getMessagesUrl, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
messagesProgressDialog.dismiss();
try {
String baseUrl = "https://myURL.com";
String defaultbaseUrl = "https://myURL.com/css/images/user_default/default_avatar.png";
JSONObject responseObject = new JSONObject(response);
JSONArray responseArray = responseObject.getJSONArray("data");
for(int i = 0; i < responseArray.length(); i++) {
jsonObject = responseArray.getJSONObject(i);
hasRead = jsonObject.getString("has_read");
String avatar = jsonObject.getString("avatar");
String message = jsonObject.getString("message");
String sender = jsonObject.getString("sender");
String timestamp = jsonObject.getString("timestamp");
Log.d(TAG, "sender: "+sender+", hasRead: "+hasRead);
if(avatar.contains("../users")) {
String substring = avatar.substring(avatar.indexOf(".") + 2);
avatar = baseUrl+substring;
Log.d(TAG, "if(avatar.contains('../users'): "+avatar);
} else {
avatar = defaultbaseUrl;
}
list.add(new Message(sender, message, avatar, timestamp));
}
updateData();
} catch(Exception e) {
Log.d(TAG, "EXCEPTION: "+e.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "VolleyError: "+error.getMessage());
messagesProgressDialog.dismiss();
}
}) {
#Override
public Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("username", username);
return params;
}
};
messagesQueue.add(messagesRequest);
return list;
}
/*
Called with TimerTask
*/
private void refreshMessages() {
RequestQueue updateQueue = Volley.newRequestQueue(this);
StringRequest updateRequest = new StringRequest(Request.Method.POST, getMessagesUrl, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
list.clear();
try {
String baseUrl = "https://myURL.com";
String defaultbaseUrl = "https://myURL.com/css/images/user_default/default_avatar.png";
JSONObject updateObject = new JSONObject(response);
JSONArray updateResponseArray = updateObject.getJSONArray("data");
for (int i = 0; i < updateResponseArray.length(); i++) {
updateObject = updateResponseArray.getJSONObject(i);
hasRead = updateObject.getString("has_read");
String avatar = updateObject.getString("avatar");
String message = updateObject.getString("message");
String sender = updateObject.getString("sender");
String timestamp = updateObject.getString("timestamp");
if (avatar.contains("../users")) {
String substring = avatar.substring(avatar.indexOf(".") + 2);
avatar = baseUrl + substring;
} else {
avatar = defaultbaseUrl;
}
if(hasRead.equals("no")) {
}
list.add(new Message(sender, message, avatar, timestamp));
}
updateData();
adapter.notifyDataSetChanged();
} catch(Exception e) {
Log.d(TAG, "EXCEPTION: "+e.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "VolleyError: "+error.getMessage());
}
}) {
#Override
public Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("username", username);
return params;
}
};
updateQueue.add(updateRequest);
}
#Override
public void onBackPressed() {
super.onBackPressed();
list.clear();
updateTimer.cancel();
updateTimer.purge();
SharedPreferences prefs = MessagesActivity.this.getSharedPreferences("MyPref", MODE_PRIVATE);
prefs.edit().putBoolean("is_logged_in", false).apply();
finish();
}
#Override
protected void onResume() {
super.onResume();
}
public void updateData() {
ArrayList<Message> strs = new ArrayList<>();
for(int i = 0; i < list.size(); i++) {
strs.add(list.get(i));
MessageAdapter updateAdapter = new MessageAdapter(list);
messages = findViewById(R.id.messages);
messages.setAdapter(updateAdapter);
updateAdapter.setOnItemClickListener(this);
}
}
#Override
public void onItemClick(int position) {
Log.d(TAG, "onItemClick Called");
Intent conversationIntent = new Intent(MessagesActivity.this, ConversationActivity.class);
String recipient = ((TextView) Objects.requireNonNull(messages.findViewHolderForAdapterPosition(position)).itemView.findViewById(R.id.message_item_username_textview)).getText().toString();
conversationIntent.putExtra("recipient", recipient);
conversationIntent.putExtra("username", username);
updateTimer.cancel();
updateTimer.purge();
startActivity(conversationIntent);
list.clear();
finish();
}
public void getProfile(final String username) {
final String username_url = "https://myURL.com/get_profile.php?username=" + username;
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest postRequest = new StringRequest(Request.Method.GET, username_url,
new com.android.volley.Response.Listener<String>() {
#Override
public void onResponse(String response) {
String baseUrl = "https://myURL.com";
String defaultbaseUrl = "https://myURL.com/css/images/user_default/default_avatar.png";
try {
profile_array = new JSONArray(response);
for(int i = 0; i < profile_array.length(); i++) {
Log.d(TAG, "getProfile inside for loop");
JSONObject jsonObject = profile_array.getJSONObject(i);
String name = jsonObject.getString("name");
String avatarString = jsonObject.getString("avatar");
Log.d(TAG, "getProfile avatarString: "+avatarString);
if(avatarString.contains("../users")) {
String substring = avatarString.substring(avatarString.indexOf(".") + 2);
Log.d(TAG, "substring: "+substring);
String urlString = baseUrl +substring;
Picasso.get().load(urlString).into(circle_avatar);
Log.d(TAG, "urlString: "+urlString);
//Log.d(TAG, "CircleImageView getDrawable(): "+avatar.getDrawable());
header_username_text.setText(name);
} else {
Picasso.get().load(defaultbaseUrl).into(circle_avatar);
header_username_text.setText(name);
}
}
} catch (JSONException e) {
ToastMaker.createLongToast(getApplicationContext(), "JSONException getProfile: "+ e.getMessage());
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// error
Log.d(TAG, "VolleyError: "+error.getMessage());
//Toast.makeText(getApplicationContext(), TAG + " " + error, Toast.LENGTH_LONG).show();
}
}
) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
return params;
}
};
queue.add(postRequest);
}
public void showLogoutDialog() {
AlertDialog.Builder logoutBuilder = new AlertDialog.Builder(this, R.style.Custom_Alert_Dialog);
logoutBuilder.setIcon(R.mipmap.ic_launcher_foreground);
logoutBuilder.setTitle("Confirm Logout");
logoutBuilder.setMessage("You are about to logout.\nAre you sure?")
.setCancelable(true)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
SharedPreferences prefs = MessagesActivity.this.getSharedPreferences("MyPref", MODE_PRIVATE);
prefs.edit().putBoolean("is_logged_in", false).apply();
Intent logoutIntent = new Intent(MessagesActivity.this, LoginActivity.class);
startActivity(logoutIntent);
finish();
}
}).setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog alertDialog = logoutBuilder.create();
alertDialog.show();
}
private void configureNavigationDrawer() {
mDrawerLayout = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.navigation_view);
circle_avatar = navigationView.getHeaderView(0).findViewById(R.id.profile_circle_avatar);
header_username_text = navigationView.getHeaderView(0).findViewById(R.id.header_username_text);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.edit_profile:
//String name = username_heading.getText().toString();
//String pic = avatar.getDrawable().toString();
//String location = location_heading.getText().toString();
//String interests = interests_heading.getText().toString();
//editProfile(name, pic, location, interests);
Log.d(TAG, "Clicked Edit Profile");
break;
case R.id.messages:
Log.d(TAG, "Clicked Messages");
mDrawerLayout.closeDrawers();
break;
case R.id.privacy:
Intent privacyIntent = new Intent(MessagesActivity.this, PrivacyActivity.class);
startActivity(privacyIntent);
Log.d(TAG, "Clicked Privacy");
break;
case R.id.logout:
showLogoutDialog();
Log.d(TAG, "Clicked Logout Button");
break;
}
mDrawerLayout.closeDrawers();
return false;
}
});
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
switch(itemId) {
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START);
return true;
}
return true;
}
private void configureToolbar() {
Toolbar toolbar = findViewById(R.id.custom_toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
assert actionBar != null : Log.d(TAG, "actionBar is NULL");
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setHomeAsUpIndicator(R.drawable.ic_action_menu_24dp);
actionBar.setDisplayHomeAsUpEnabled(true);
}
#Override
protected void onRestart() {
super.onRestart();
updateTimer = new Timer();
TimerTask updateTimerTask = new TimerTask() {
public void run() {
refreshMessages();
}
};
updateTimer.scheduleAtFixedRate(updateTimerTask, 3000, 3000);
}
}
Here is the array that is being sent from the webserver:
$data[] = array('has_read' => 'no', 'avatar' => $avatar, 'sender' => $sender, 'recipient' => $recipient, 'message' => $message, 'timestamp' => $time);
$response = array('data'=>$data, 'count'=>$count);
echo json_encode($response);
If you need only one Boolean throughout your app, here is a way to access the Boolean value:
Create a separate file named ext for example and inside, make this interface:
public interface ext {
Boolean hasRead = false;
}
This variable is made when the app runs and lives for as long as the app does. so you can change it whenever you want.
If you want to have 2 separate Booleans for the two users chatting you can use a Hashmap like so:
HashMap <String, Boolean> readStatus = new HashMap<>();
Update 2
Guess what? It was a typo in another php function not mentioned in my question called getConversation(). I stopped working on the file a while back to perfect my MessagesActivity. I logged any Exceptions on the Activity, and noticed Exception in getMessages(): No value for timestamp.
I had misspelled my timestamp variable. Lol. So, I have a fully functioning messaging system now! :-) Now to work on some notification bells and whistles. Have a great weekend.
Update: This is not completely solved. It's
bold when it's initially received on the MessagesActivity screen, but it goes back to regular Typeface once they refresh (via the TimerTask). Will debug for a while and come back, unless one of you discovers it first. :)
I think I figured it out!
My table is like so:
user1, user1ID, user2, user2ID, message, timestamp, user1read, user2read
When I make my request for a message, I receive these items via the php script:
if($sender === $username) {
$data[] = array('has_read'=>$user1read, 'avatar'=>$avatar, 'sender'=>$recipient, 'message'=>'You: '.$message, 'timestamp'=>$time);
} else {
$data[] = array('has_read' => $user2read, 'avatar' => $avatar, 'sender' => $sender, 'recipient' => $recipient, 'message' => $message, 'timestamp' => $time);
}
This was my original loop to get all the messages from my JSONObject:
for (int i = 0; i < updateResponseArray.length(); i++) {
updateObject = updateResponseArray.getJSONObject(i);
String hasRead = updateObject.getString("has_read");
String avatar = updateObject.getString("avatar");
String message = updateObject.getString("message");
String sender = updateObject.getString("sender");
String timestamp = updateObject.getString("timestamp");
if (avatar.contains("../users")) {
String substring = avatar.substring(avatar.indexOf(".") + 2);
avatar = baseUrl + substring;
} else {
avatar = defaultbaseUrl;
}
list.add(new Message(sender, message, avatar, timestamp));
So, I thought, "why don't I just create another member variable for my Messages model, and call it "hasRead"? So I did just that:
public class Message {
private String username;
private String messageSnippet;
private String avatarUrl;
private String timestamp;
private String hasRead; //<--- here we go
Then I make my getters and setters (leaving out for the sake of brevity).
#J7bits suggested I access the onBindViewHolder() in my custom Adapter class. So I did that, but I included logic to check the status of the new member variable "hasRead":
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Message message = messages.get(position);
holder.username.setText(message.getUsername());
holder.messageSnippet.setText(message.getMessageSnippet());
holder.singleMessageTimestamp.setText(message.getTimestamp());
Picasso.get().load(message.getAvatarUrl()).into(holder.avatarCircleImageView);
if(message.getHasRead().equals("no")) {
holder.messageSnippet.setTypeface(null, Typeface.BOLD_ITALIC);
}
}
Then, finally, I changed my JSON onResponse method to include the has_read variable sent from php:
String hasRead = jsonObject.getString("has_read");
And I added it to my ArrayList<Message> list:
list.add(new Message(sender, message, avatar, timestamp, **hasRead**);
I entered a new message manually into the database, and set my status to "no" for user2read. And would you just look at it?!?! :D

Pusher with Service application on Android dose not bind events

I had a problem with Pusher with Service application on Android.
When I using pusher on Application or Activity then It's working.
But I move it to Service and register with application in manifress like:
<service android:name=".services.PusherServices"/>
It's not working.
When i startService Pusher connected success with authorization, but It's not bind events when I call method for register Channel.
PusherServices.java
package vn.hemlock.winkle.pancake.services;
import android.app.Activity;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import com.pusher.client.Pusher;
import com.pusher.client.PusherOptions;
import com.pusher.client.channel.PrivateChannel;
import com.pusher.client.channel.PrivateChannelEventListener;
import com.pusher.client.connection.ConnectionEventListener;
import com.pusher.client.connection.ConnectionState;
import com.pusher.client.connection.ConnectionStateChange;
import com.pusher.client.util.HttpAuthorizer;
import net.windjs.android.utils.Encrypt;
import net.windjs.android.utils.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import vn.hemlock.winkle.pancake.abstracts.ChatEvents;
import vn.hemlock.winkle.pancake.contracts.ServicesURI;
import vn.hemlock.winkle.pancake.ui.Conversation;
import vn.hemlock.winkle.pancake.ui.Message;
import vn.hemlock.winkle.pancake.ui.Page;
/**
* Created by me866chuan on 5/4/15.
*/
public class PusherServices extends Service {
private String LOG_TAG = "Pusher Services";
private boolean pusherOn = false;
public final String PUSHER_KEY = "...";
private String userToken = "";
private String userID = "";
private final IBinder mBinder = new LocalBinder();
public boolean isPusherOn() {
return pusherOn;
}
public void setPusherOn(boolean pusherOn) {
this.pusherOn = pusherOn;
}
public String getUserToken() {
return userToken;
}
public void setUserToken(String userToken) {
this.userToken = userToken;
}
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
#Override
public IBinder onBind(Intent intent) {
setUserID(intent.getStringExtra("userId"));
setUserToken(intent.getStringExtra("userToken"));
startPusher();
startService(intent);
return mBinder;
}
#Override
public boolean onUnbind(Intent intent) {
Log.e(LOG_TAG, "OFF");
stopService(intent);
return true;
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
pusher.disconnect();
}
private Pusher pusher;
public void startPusher() {
HashMap<String, String> hash = new HashMap<>();
Log.e(LOG_TAG, "Token: "+getUserToken());
hash.put("authorization", getUserToken());
HttpAuthorizer authorizer = new HttpAuthorizer(ServicesURI.PUSHER_AUTHORIZER);
authorizer.setHeaders(hash);
PusherOptions options = new PusherOptions().setAuthorizer(authorizer);
pusher = new Pusher(PUSHER_KEY, options);
pusher.connect(new ConnectionEventListener() {
#Override
public void onConnectionStateChange(ConnectionStateChange change) {
Log.e(LOG_TAG, "State changed to " + change.getCurrentState() +
" from " + change.getPreviousState());
if(change.getCurrentState().toString().toUpperCase().equals("CONNECTED") || change.getCurrentState().toString().toUpperCase().equals("CONNECTING")){
setPusherOn(true);
}
else setPusherOn(false);
}
#Override
public void onError(String message, String code, Exception e) {
Log.e(LOG_TAG, "There was a problem connecting: " + message);
}
}, ConnectionState.ALL);
}
PrivateChannel userChannel;
public void userListenChanel(final Activity activity) {
if (pusher == null) return;
userChannel = pusher.subscribePrivate("private-" + Encrypt.stringMD5(getUserID()));
userChannel.bind("fetch_accounts", new PrivateChannelEventListener() {
#Override
public void onEvent(String channel, String event, final String data) {
Log.e(LOG_TAG, "Received event with data: " + data);
if (activity != null) activity.runOnUiThread(new Runnable() {
#Override
public void run() {
try {
ChatEvents.getInstance().onNewPage(new Page((new JSONObject(data)).getJSONObject("page")));
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
#Override
public void onAuthenticationFailure(String s, Exception e) {
Log.e(LOG_TAG, "USER FETCH FAIL: " + s);
}
#Override
public void onSubscriptionSucceeded(String s) {
Log.e(LOG_TAG, "USER FETCH SUCCESS: " + s);
}
});
}
PrivateChannel pageChannel;
private String idPageChannelListen;
public void pageListenChanel(final Activity activity, String pageId) {
if (pusher == null) return;
idPageChannelListen = pageId;
Log.e(LOG_TAG, "Channel page: "+"private-" + Encrypt.stringMD5(pageId));
pageChannel = pusher.subscribePrivate("private-" + Encrypt.stringMD5(pageId));
pageChannel.bind("realtime_updates", new PrivateChannelEventListener() {
#Override
public void onEvent(String channel, String event, final String data) {
Log.e(LOG_TAG, "Real time update with data: " + data);
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(data);
} catch (JSONException e) {
e.printStackTrace();
}
final JSONObject finalJsonObject = jsonObject;
if(activity != null) activity.runOnUiThread(new Runnable() {
#Override
public void run() {
if (finalJsonObject == null) return;
try {
if (finalJsonObject.has("message")) ChatEvents.getInstance().onNewMessage(new Message(finalJsonObject.getJSONObject("message")));
else if (finalJsonObject.has("conversation")) ChatEvents.getInstance().onNewConversation(new Conversation(finalJsonObject.getJSONObject("conversation")));
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
#Override
public void onAuthenticationFailure(String s, Exception e) {
Log.e(LOG_TAG, "Real time update failed: " + s);
}
#Override
public void onSubscriptionSucceeded(String s) {
Log.e(LOG_TAG, "Real time update successed: " + s);
}
});
pageChannel.bind("fetch_conversations", new PrivateChannelEventListener() {
#Override
public void onEvent(String channel, String event, final String data) {
Log.e(LOG_TAG, "Received event with data: " + data);
if(activity != null) activity.runOnUiThread(new Runnable() {
#Override
public void run() {
try {
ChatEvents.getInstance().onNewConversation(new Conversation((new JSONObject(data)).getJSONObject("conversation")));
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
#Override
public void onAuthenticationFailure(String s, Exception e) {
}
#Override
public void onSubscriptionSucceeded(String s) {
}
});
pageChannel.bind("fetch_comments", new PrivateChannelEventListener() {
#Override
public void onEvent(String channel, String event, String data) {
Log.e(LOG_TAG, "Received event with data: " + data);
}
#Override
public void onAuthenticationFailure(String s, Exception e) {
}
#Override
public void onSubscriptionSucceeded(String s) {
}
});
}
public void removeLisnterPage(String pageId) {
if (pusher != null) pusher.unsubscribe("private-" + Encrypt.stringMD5(pageId));
idPageChannelListen = "";
}
public void reconnectPusher() {
if (pusher != null) {
pusher.disconnect();
pusher.connect();
}
}
public void disconnectPusher() {
if (pusher != null) pusher.disconnect();
}
public String getIdPageChannelListen() {
return idPageChannelListen;
}
public class LocalBinder extends Binder {
public PusherServices getService() {
// Return this instance of LocalService so clients can call public methods
return PusherServices.this;
}
}
}

orika property expression mapping

Given
classA {
long fahr;
....
and
classB {
long cels;
....
how can I map the following in Orika?
A.fahr <-> (B.cels*9)/5
Do I need customised Mapper or Filter ?
I suggest to use field level converter if both are of different data types but since they are of same data type we have to use a custom converter for entire class.
This is sample converter that suitable for this use case.
import ma.glasnost.orika.BoundMapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.converter.ConverterFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
public class EntryClass {
public static void main(String[] args) {
EntryClass ec = new EntryClass();
BoundMapperFacade<A, B> facade = getMapperFactory().getMapperFacade(A.class, B.class);
A fahr = new A(455);
B cels = facade.map(fahr);
System.out.println(cels);
A revFahr = facade.mapReverse(cels);
System.out.println(revFahr);
}
private static MapperFactory getMapperFactory() {
MapperFactory factory = new DefaultMapperFactory.Builder()
.build();
ConverterFactory cfactory = factory.getConverterFactory();
cfactory.registerConverter(new FahrCelsConverter());
factory.classMap(A.class, B.class)
.field("fahr", "cels")
.byDefault()
.register();
return factory;
}
}
public class A {
long fahr;
public A(long fahr) {
this.fahr = fahr;
}
public long getFahr() {
return fahr;
}
public void setFahr(long fahr) {
this.fahr = fahr;
}
#Override
public String toString() {
return "A [fahr=" + fahr + "]";
}
}
public class B {
long cels;
public B(long cels) {
this.cels = cels;
}
public long getCels() {
return cels;
}
public void setCels(long cels) {
this.cels = cels;
}
#Override
public String toString() {
return "B [cels=" + cels + "]";
}
}
public class FahrCelsConverter extends BidirectionalConverter<A, B>
{
#Override
public B convertTo(A source, Type<B> destinationType, MappingContext mappingContext) {
if(source != null)
{
return new B((source.fahr - 32) * 5 / 9);
}
return null;
}
#Override
public A convertFrom(B source, Type<A> destinationType, MappingContext mappingContext) {
if(source != null)
{
return new A((source.cels / 5) * 9 + 32);
}
return null;
}
}
It's more suited to use a converter (by id).

Deserialize JSON with Gson - Expected BEGIN_OBJECT but was String - Reddit's JSON

I'm trying to deserialize JSON from Reddit that you can obtain by appending .json to the url. An example would be:
http://www.reddit.com/r/pics/comments/1wvx52/.json?sort=top
However, I am getting the error message:
Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 9765
At line 1 column 9765 in the json there is the following code: "replies": "", whereas normally this would contain an object like this: replies: {
kind: "Listing",
data: {}
},
Does this mean that the json is a String when there is no data, but an object otherwise? How can I deserialize with gson properly if this is the case? I've included my classes below. I still need to figure out how to handle the json starting off with an array of basically two different objects (the first listing in the json is describing the link, while the second listing is describing the comments), but I'll cross that bridge when I get there. Thanks in advance if anyone can shed some light on this issue.
Main Class
public static void main(String[] args)
{
ArrayList<CommentsResults> commentsResults = new ArrayList<CommentsResults>();
String commentsURL = "http://www.reddit.com/r/pics/comments/1wvx52/.json?sort=top";
URL url = null;
try
{
url = new URL(commentsURL);
} catch (MalformedURLException ex)
{
System.out.println(ex.getMessage());
}
try
{
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
String jsonText = readAll(bufferedReader);
Gson gson = new GsonBuilder().create();
commentsResults = gson.fromJson(jsonText, new TypeToken<ArrayList<CommentsResults>>(){}.getType());
} catch (IOException ex)
{
System.out.println(ex.getMessage());
}
}
private static String readAll(Reader reader) throws IOException
{
StringBuilder stringBuilder = new StringBuilder();
int cp;
while ((cp = reader.read()) != -1)
{
stringBuilder.append((char) cp);
}
return stringBuilder.toString();
}
CommentsResults Class
public class CommentsResults {
private String kind;
private CommentsData data;
public CommentsResults()
{
}
public CommentsResults(String kind, CommentsData data)
{
this.kind = kind;
this.data = data;
}
public String getKind()
{
return kind;
}
public CommentsData getData()
{
return data;
}
public void setKind(String kind)
{
this.kind = kind;
}
public void setData(CommentsData data)
{
this.data = data;
}
}
CommentsData Class
private String modhash;
private List <CommentsChild> children;
public CommentsData()
{
}
public CommentsData(String modhash, List<CommentsChild> children)
{
this.modhash = modhash;
this.children = children;
}
public String getModhash()
{
return modhash;
}
public List<CommentsChild> getChildren()
{
return children;
}
public void setModhash(String modhash)
{
this.modhash = modhash;
}
public void setChildren(List<CommentsChild> children)
{
this.children = children;
}
CommentsChild Class
private String kind;
private Comment data;
public CommentsChild()
{
}
public CommentsChild(String kind, Comment comment)
{
this.kind = kind;
this.data = comment;
}
public String getKind()
{
return kind;
}
public Comment getComment()
{
return data;
}
public void setKind(String kind)
{
this.kind = kind;
}
public void setComment(Comment comment)
{
this.data = comment;
}
Comment Class
public class Comment {
private CommentsResults replies;
private String id;
private int gilded;
private String author;
private String parent_id;
private String body;
private int downs;
private String link_id;
private boolean score_hidden;
private int created_utc;
private String distinguished;
public Comment()
{
}
public Comment(CommentsResults replies, String id, int gilded, String author, String parent_id, String body, int downs, String link_id, boolean score_hidden, int created_utc, String distinguished)
{
this.replies = replies;
this.id = id;
this.gilded = gilded;
this.author = author;
this.parent_id = parent_id;
this.body = body;
this.downs = downs;
this.link_id = link_id;
this.score_hidden = score_hidden;
this.created_utc = created_utc;
this.distinguished = distinguished;
}
public CommentsResults getReplies()
{
return replies;
}
public String getId()
{
return id;
}
public int getGilded()
{
return gilded;
}
public String getAuthor()
{
return author;
}
public String getParent_id()
{
return parent_id;
}
public String getBody()
{
return body;
}
public int getDowns()
{
return downs;
}
public String getLink_id()
{
return link_id;
}
public boolean isScore_hidden()
{
return score_hidden;
}
public int getCreated_utc()
{
return created_utc;
}
public String getDistinguished()
{
return distinguished;
}
public void setReplies(CommentsResults replies)
{
this.replies = replies;
}
public void setId(String id)
{
this.id = id;
}
public void setGilded(int gilded)
{
this.gilded = gilded;
}
public void setAuthor(String author)
{
this.author = author;
}
public void setParent_id(String parent_id)
{
this.parent_id = parent_id;
}
public void setBody(String body)
{
this.body = body;
}
public void setDowns(int downs)
{
this.downs = downs;
}
public void setLink_id(String link_id)
{
this.link_id = link_id;
}
public void setScore_hidden(boolean score_hidden)
{
this.score_hidden = score_hidden;
}
public void setCreated_utc(int created_utc)
{
this.created_utc = created_utc;
}
public void setDistinguished(String distinguished)
{
this.distinguished = distinguished;
}
}
So in the off chance this helps somebody (which seems dubious at this point) I decided to parse the Json manually using recursion. Here's how I did it:
public static void getCommentsOnLink()
{
String commentsURL= "http://www.reddit.com/r/pics/comments/1wvx52/.json?sort=top";
URL url = null;
try
{
url = new URL(commentsURL);
} catch (MalformedURLException ex)
{
System.out.println(ex.getMessage());
}
String JsonText = readCommentJsonFromURL(url);
RedditCommentResults redditCommentResults = getCommentResults(JsonText);
}
private static String readCommentJsonFromURL(URL url)
{
String JSONText = null;
try
{
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
JSONText = readAll(bufferedReader);
} catch (IOException ex)
{
System.out.println(ex.getMessage());
}
return JSONText;
}
private static String readAll(Reader reader) throws IOException
{
StringBuilder stringBuilder = new StringBuilder();
int cp;
while ((cp = reader.read()) != -1)
{
stringBuilder.append((char) cp);
}
return stringBuilder.toString();
}
private static RedditCommentResults getCommentResults(String JsonText)
{
JsonParser parser = new JsonParser();
JsonArray completeJson = (JsonArray) parser.parse(JsonText);
//get link and comment object from the array containing an object for each
JsonObject linkParentJson = (JsonObject) completeJson.get(0);
JsonObject commentParentJson = (JsonObject) completeJson.get(1);
//use automatic deserializer for redditLink
JsonObject linkListingDataJson = linkParentJson.getAsJsonObject("data");
JsonObject linkChildrenJson = linkListingDataJson.getAsJsonArray("children").get(0).getAsJsonObject();
JsonObject linkDataJson = linkChildrenJson.getAsJsonObject("data");
Link commentLink = gson.fromJson(linkDataJson, Link.class);
RedditLink redditCommentLink = new RedditLink(commentLink);
//parse comments manually
JsonObject commentDataJson = commentParentJson.getAsJsonObject("data");
JsonArray commentChildrenJson = commentDataJson.getAsJsonArray("children");
//get all of the comments from the JsonArray
ArrayList<RedditComment> redditComments = getNestedComments(commentChildrenJson);
RedditCommentResults redditCommentResults = new RedditCommentResults(redditComments, redditCommentLink);
return redditCommentResults;
}
private static ArrayList<RedditComment> getNestedComments(JsonArray commentWrapperJsonArray)
{
ArrayList<RedditComment> redditComments = new ArrayList();
for (JsonElement commentWrapperJson : commentWrapperJsonArray)
{
//cast Element to Object so we can search for the primitive "kind". Finally we get it as a String
String kind = commentWrapperJson.getAsJsonObject().getAsJsonPrimitive("kind").getAsString();
//if the comment is of type t1 meaning it is a comment and not a "more" (a "more" is a comment which
//hasn't been loaded yet because it does not have a great deal of upvotes relative to other comments)
if (kind.equals("t1"))
{
JsonObject commentJson = commentWrapperJson.getAsJsonObject().getAsJsonObject("data");
Comment comment = gson.fromJson(commentJson, Comment.class);
RedditComment redditComment = new RedditComment(comment);
JsonElement repliesJson = commentJson.get("replies");
//if the reply is not equal to an empty String (i.e. if there is at least one reply)
if (!repliesJson.isJsonPrimitive())
{
JsonObject dataJson = repliesJson.getAsJsonObject().getAsJsonObject("data");
JsonArray childrenJson = dataJson.getAsJsonArray("children");
ArrayList<RedditComment> nestedComments = getNestedComments(childrenJson);
redditComment.setReplies(nestedComments);
}
redditComments.add(redditComment);
}
}
return redditComments;
}
You have to remove the private CommentsResults replies; from Comment Class and compose replies in CommentsChild class. According to Json fomate you model is
CommentResult -
CommentsData --
List <CommentsChild> children---
CommentsResults replies
recursion/ repeation of comment result
public class CommentsChild {
private String kind;
private Comment data;
//
private CommentsResults replies;
}

Phone number tabbing in Text field using Jface

I am stuck in one of the issue. Suppose i have a phone number field 010-9999-9999, this number should split in 3 text field. I tried to do this but i get only prefix number i.e 010 in all three text field. I am using jface databinding.
I created Model as
class A{
String phoneNo;
}
Jface Databinding:
IObservableValue ssn1TextTextObserveWidget = SWTObservables.observeText(text_ph11, SWT.Modify);
IObservableValue ssn2TextTextObserveWidget = SWTObservables.observeText(text_ph2, SWT.Modify);
IObservableValue ssn2TextTextObserveWidget1 = SWTObservables.observeText(text_ph3, SWT.Modify);
IObservableValue simpleTableViewerSSN1ObserveDetailValue = BeansObservables.observeDetailValue(simpleTableViewerSelectionObserveSelection_employee, "phoneNo", String.class);
IObservableValue simpleTableViewerSSN2ObserveDetailValue = BeansObservables.observeDetailValue(simpleTableViewerSelectionObserveSelection_employee, "phoneNo", String.class);
IObservableValue simpleTableViewerSSN2ObserveDetailValue = BeansObservables.observeDetailValue(simpleTableViewerSelectionObserveSelection_employee, "phoneNo", String.class);
Databinding
bindingContext.bindValue(simpleTableViewerSSN1ObserveDetailValue, ssn1TextTextObserveWidget, null, null);
bindingContext.bindValue(simpleTableViewerSSN2ObserveDetailValue, ssn2TextTextObserveWidget, null, null);
bindingContext.bindValue(simpleTableViewerSSN2ObserveDetailValue, ssn2TextTextObserveWidget1, null, null);
When i try to do this value only prefix get populated in all three fields i.e 010-010-010. Please help me out to resolve this issue.
If you want your phone number to be divided into three different widgets you will probably need to save the phone number in three different attributes, each assigned a different part of the phone number.
There might be some way to bind a 'part' of a string value to a widget, maybe through getter methods, but for that wait and let someone more knowledgeable in this area give an answer for you.
Here is sample code that can be modified to work with your case. IConverter is used with UpdateValueStrategy to modify the value that will be set/get model to/from target text feild.
//GUI class
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new GridLayout(3, false));
Label lbl = new Label(shell, SWT.NONE);
lbl.setText("Name");
final Text firstName = new Text(shell, SWT.BORDER);
final Text lastName = new Text(shell, SWT.BORDER);
final Name name = new Name();
SWTObservables.getRealm(display).exec(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Realm realm = SWTObservables.getRealm(display);
DataBindingContext cxt = new DataBindingContext(realm);
ISWTObservableValue firstNameObservable = SWTObservables.observeText(firstName, new int[] { SWT.Modify });
ISWTObservableValue lastNameObservable = SWTObservables.observeText(lastName, new int[] { SWT.Modify });
final IObservableValue nameObservable = BeansObservables.observeValue(realm, name, "name");
UpdateValueStrategy firstNameTxtToName = new UpdateValueStrategy();
firstNameTxtToName.setConverter(new IConverter() {
#Override
public Object getToType() {
// TODO Auto-generated method stub
return String.class;
}
#Override
public Object getFromType() {
// TODO Auto-generated method stub
return String.class;
}
#Override
public Object convert(Object fromObject) {
String val = fromObject.toString();
Object beanVal = nameObservable.getValue();
if (beanVal != null) {
String beanString = beanVal.toString();
int i = beanString.indexOf(',');
if (i != -1) {
return val + beanString.substring(i);
}
}
return val;
}
});
UpdateValueStrategy nameToFirstName = new UpdateValueStrategy();
nameToFirstName.setConverter(new IConverter() {
#Override
public Object getToType() {
// TODO Auto-generated method stub
return String.class;
}
#Override
public Object getFromType() {
// TODO Auto-generated method stub
return String.class;
}
#Override
public Object convert(Object fromObject) {
if (fromObject != null) {
Object objVal = nameObservable.getValue();
if (objVal != null) {
String val = objVal.toString();
int i = val.indexOf(',');
if (i != -1) {
return val.substring(0, i);
} else {
return val;
}
}
}
return "";
}
});
UpdateValueStrategy lastNameTxtToName = new UpdateValueStrategy();
lastNameTxtToName.setConverter(new IConverter() {
#Override
public Object getToType() {
// TODO Auto-generated method stub
return String.class;
}
#Override
public Object getFromType() {
// TODO Auto-generated method stub
return String.class;
}
#Override
public Object convert(Object fromObject) {
String val = fromObject.toString();
Object beanVal = nameObservable.getValue();
if (beanVal != null) {
String beanString = beanVal.toString();
int i = beanString.indexOf(',');
String fName = beanString;
if (i != -1) {
fName = beanString.substring(0, i + 1);
} else {
fName = fName + ",";
}
val = fName + val;
}
return val;
}
});
UpdateValueStrategy nameToLastName = new UpdateValueStrategy();
nameToLastName.setConverter(new IConverter() {
#Override
public Object getToType() {
// TODO Auto-generated method stub
return String.class;
}
#Override
public Object getFromType() {
// TODO Auto-generated method stub
return String.class;
}
#Override
public Object convert(Object fromObject) {
if (fromObject != null) {
String val = fromObject.toString();
int i = val.indexOf(',');
if (i != -1) {
return val.substring(i + 1);
}
}
return "";
}
});
cxt.bindValue(firstNameObservable, nameObservable, firstNameTxtToName, nameToFirstName);
cxt.bindValue(lastNameObservable, nameObservable, lastNameTxtToName, nameToLastName);
}
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
//POJO
public class Name {
private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
changeSupport.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
changeSupport.removePropertyChangeListener(propertyName, listener);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
changeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
changeSupport.removePropertyChangeListener(listener);
}
public void firePropertyChangeEvent(PropertyChangeEvent evt) {
changeSupport.firePropertyChange(evt);
}
String name;
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
System.out.println(name);
}
}