Linked to question: JavaFX 2: Save edit in TableCell
There seems to be allot of plumbing required for to establish an editable tableview - namely trapping all the events for each textField (gained/lost focus, tabbing away from the textField, commiting edits from the textField to the underlying data model), and overriding several methods in the the TableCell.
The default behavior to establish editing - doubleclicking in a cell - doesn't seem familiar to me or users of a standard table control. I just want to click into the cell and start typing, for the most part.
Are there any fully implemented examples out there? Please add yours, or comments for designing such a creature.
Instead of responding to several events at the TableCell and TableColumn level to initiate editing of a cell, and successfully update the cell's underlying data - instead we provide a custom cell factory and override theupdateItem() method in the cell and 'bind' the textProperty of the textField directly to the property inside our data model for the TableView (in this case a StringProperty). I have added other aesthetics to make the textField inside the cell seem seamless and respond to hover and focused states.
All the magic happens in updateItem() method. You have to keep track of the textField and what it is bound to - the TableView API 'recycles' TableCells to reduce memory consumption:
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if(!empty) {
// Show the Text Field
this.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
// 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);
}
}
System.out.println("item=" + item + " ObservableValue<String>=" + ov.getValue());
//this.textField.setText(item); // No longer need this!!!
}
else {
this.setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
Here is a full example of a table with 4 columns, all bound to the underlying textField. As soon as you type in the textField, the underlying data model in the Observable list is updated:
package tablevieweditingwithbinding;
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Callback;
/**
*
* #author jKaufmann
*/
public class TableViewEditingWithBinding extends Application {
public static class TableData {
private SimpleStringProperty firstName, lastName, phone, email;
private ObjectProperty<SimpleStringProperty> firstNameObject;
public TableData(String firstName, String lastName, String phone, String email) {
this.firstName = new SimpleStringProperty(firstName);
this.firstNameObject = new SimpleObjectProperty(firstNameObject);
this.lastName = new SimpleStringProperty(lastName);
this.phone = new SimpleStringProperty(phone);
this.email = new SimpleStringProperty(email);
}
public String getEmail() {
return email.get();
}
public void setEmail(String email) {
this.email.set(email);
}
public SimpleStringProperty emailProperty() { return email; }
public String getFirstName() {
return firstName.get();
}
public SimpleStringProperty getFirstNameObject() {
return firstNameObject.get();
}
public void setFirstNameObject(SimpleStringProperty firstNameObject) {
this.firstNameObject.set(firstNameObject);
}
public ObjectProperty<SimpleStringProperty> firstNameObjectProperty() { return firstNameObject; }
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public SimpleStringProperty firstNameProperty() {
return firstName;
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public SimpleStringProperty lastNameProperty() { return lastName; }
public String getPhone() {
return phone.get();
}
public void setPhone(String phone) {
this.phone.set(phone);
}
public SimpleStringProperty phoneProperty() { return phone; }
}
public static class TextFieldCellFactory
implements Callback<TableColumn<TableData,String>,TableCell<TableData,String>> {
#Override
public TableCell<TableData, String> call(TableColumn<TableData, String> param) {
TextFieldCell textFieldCell = new TextFieldCell();
return textFieldCell;
}
public static class TextFieldCell extends TableCell<TableData,String> {
private TextField textField;
private StringProperty boundToCurrently = null;
public TextFieldCell() {
String strCss;
// Padding in Text field cell is not wanted - we want the Textfield itself to "be"
// The cell. Though, this is aesthetic only. to each his own. comment out
// to revert back.
strCss = "-fx-padding: 0;";
this.setStyle(strCss);
textField = new TextField();
//
// Default style pulled from caspian.css. Used to play around with the inset background colors
// ---trying to produce a text box without borders
strCss = "" +
//"-fx-background-color: -fx-shadow-highlight-color, -fx-text-box-border, -fx-control-inner-background;" +
"-fx-background-color: -fx-control-inner-background;" +
//"-fx-background-insets: 0, 1, 2;" +
"-fx-background-insets: 0;" +
//"-fx-background-radius: 3, 2, 2;" +
"-fx-background-radius: 0;" +
"-fx-padding: 3 5 3 5;" + /*Play with this value to center the text depending on cell height??*/
//"-fx-padding: 0 0 0 0;" +
"-fx-prompt-text-fill: derive(-fx-control-inner-background,-30%);" +
"-fx-cursor: text;" +
"";
// Focused and hover states should be set in the CSS. This is just a test
// to see what happens when we set the style in code
textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
TextField tf = (TextField)getGraphic();
String strStyleGotFocus = "-fx-background-color: purple, -fx-text-box-border, -fx-control-inner-background;" +
"-fx-background-insets: -0.4, 1, 2;" +
"-fx-background-radius: 3.4, 2, 2;";
String strStyleLostFocus = //"-fx-background-color: -fx-shadow-highlight-color, -fx-text-box-border, -fx-control-inner-background;" +
"-fx-background-color: -fx-control-inner-background;" +
//"-fx-background-insets: 0, 1, 2;" +
"-fx-background-insets: 0;" +
//"-fx-background-radius: 3, 2, 2;" +
"-fx-background-radius: 0;" +
"-fx-padding: 3 5 3 5;" + /**/
//"-fx-padding: 0 0 0 0;" +
"-fx-prompt-text-fill: derive(-fx-control-inner-background,-30%);" +
"-fx-cursor: text;" +
"";
if(newValue.booleanValue())
tf.setStyle(strStyleGotFocus);
else
tf.setStyle(strStyleLostFocus);
}
});
textField.hoverProperty().addListener(new ChangeListener<Boolean>() {
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
TextField tf = (TextField)getGraphic();
String strStyleGotHover = "-fx-background-color: derive(purple,90%), -fx-text-box-border, derive(-fx-control-inner-background, 10%);" +
"-fx-background-insets: 1, 2.8, 3.8;" +
"-fx-background-radius: 3.4, 2, 2;";
String strStyleLostHover = //"-fx-background-color: -fx-shadow-highlight-color, -fx-text-box-border, -fx-control-inner-background;" +
"-fx-background-color: -fx-control-inner-background;" +
//"-fx-background-insets: 0, 1, 2;" +
"-fx-background-insets: 0;" +
//"-fx-background-radius: 3, 2, 2;" +
"-fx-background-radius: 0;" +
"-fx-padding: 3 5 3 5;" + /**/
//"-fx-padding: 0 0 0 0;" +
"-fx-prompt-text-fill: derive(-fx-control-inner-background,-30%);" +
"-fx-cursor: text;" +
"";
String strStyleHasFocus = "-fx-background-color: purple, -fx-text-box-border, -fx-control-inner-background;" +
"-fx-background-insets: -0.4, 1, 2;" +
"-fx-background-radius: 3.4, 2, 2;";
if(newValue.booleanValue()) {
tf.setStyle(strStyleGotHover);
}
else {
if(!tf.focusedProperty().get()) {
tf.setStyle(strStyleLostHover);
}
else {
tf.setStyle(strStyleHasFocus);
}
}
}
});
textField.setStyle(strCss);
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);
// 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);
}
}
System.out.println("item=" + item + " ObservableValue<String>=" + ov.getValue());
//this.textField.setText(item); // No longer need this!!!
}
else {
this.setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
}
}
public static void printNodeKidsRecursively(Node n, String tabs) {
String toTab = tabs == null ? "" : tabs;
String msg1 = toTab + n.getClass().getName();
String msg2 = ":" + n.toString();
// Spit out and text data from Text classes
if(javafx.scene.text.Text.class.isAssignableFrom(n.getClass())) {
javafx.scene.text.Text t = (javafx.scene.text.Text)n;
msg2 += " \"" +t.getText() + "\"";
}
// if this Node does not extend from Parent, then it can't have kids.
if(!Parent.class.isAssignableFrom(n.getClass())) {
System.out.println(msg1+msg2);
return;
}
Parent p = (Parent)n;
System.out.println(toTab + n.getClass().getName() +
"(KIDS=" +
Integer.toString(p.getChildrenUnmodifiable().size()) + ")" +
msg2);
ObservableList<Node> kids = p.getChildrenUnmodifiable();
toTab +=" ";
for(Node n2 : kids) {
printNodeKidsRecursively(n2, toTab);
}
}
private final TableView<TableData> table = new TableView<TableData>();
final ObservableList<TableData> ol =
FXCollections.observableArrayList(
new TableData("Wilma","Flintstone","555-123-4567","WFlintstone#gmail.com"),
new TableData("Fred","Flintstone","555-123-4567","FFlintstone#gmail.com"),
new TableData("Barney","Flintstone","555-123-4567","Barney#gmail.com"),
new TableData("Bugs","Bunny","555-123-4567","BugsB#gmail.com"),
new TableData("Yo","Sam","555-123-4567","ysam#gmail.com"),
new TableData("Tom","","555-123-4567","tom#gmail.com"),
new TableData("Jerry","","555-123-4567","Jerry#gmail.com"),
new TableData("Peter","Pan","555-123-4567","Ppan#gmail.com"),
new TableData("Daffy","Duck","555-123-4567","dduck#gmail.com"),
new TableData("Tazmanian","Devil","555-123-4567","tdevil#gmail.com"),
new TableData("Mickey","Mouse","555-123-4567","mmouse#gmail.com"),
new TableData("Mighty","Mouse","555-123-4567","mimouse#gmail.com")
);
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage Stage) {
Stage.setTitle("Editable Table");
BorderPane borderPane = new BorderPane();
Scene scene = new Scene(borderPane, 800, 600);
// top of border pane
Button b1 = new Button("Print Scene Graph for table Node");
Button b2 = new Button("Change value in table list");
HBox hbox = new HBox(10);
hbox.setStyle("-fx-background-color: #336699");
hbox.setAlignment(Pos.BOTTOM_CENTER);
HBox.setMargin(b2, new Insets(10,0,10,0));
HBox.setMargin(b1, new Insets(10,0,10,0));
hbox.getChildren().addAll(b1,b2);
borderPane.setTop(hbox);
BorderPane.setAlignment(hbox, Pos.CENTER);
// Button Events
b1.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
printNodeKidsRecursively(table,"");
}
});
b2.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
String curFirstName = ol.get(0).getFirstName();
if(curFirstName.contentEquals("Jason"))
ol.get(0).setFirstName("Paul");
else
ol.get(0).setFirstName("Jason");
}
});
table.setItems(ol);
borderPane.setCenter(table);
BorderPane.setAlignment(table, Pos.CENTER);
BorderPane.setMargin(table, new Insets(25));
// Add columns
TableColumn<TableData,String> c1 = new TableColumn<TableData,String>("FirstName");
c1.setCellValueFactory(new PropertyValueFactory<TableData,String>("firstName"));
c1.setCellFactory(new TextFieldCellFactory());
TableColumn<TableData,String> c2 = new TableColumn<TableData,String>("LastName");
c2.setCellValueFactory(new PropertyValueFactory<TableData,String>("lastName"));
c2.setCellFactory(new TextFieldCellFactory());
TableColumn<TableData,String> c3 = new TableColumn<TableData,String>("Phone");
c3.setCellValueFactory(new PropertyValueFactory<TableData,String>("phone"));
c3.setCellFactory(new TextFieldCellFactory());
TableColumn<TableData,String> c4 = new TableColumn<TableData,String>("Email");
c4.setCellValueFactory(new PropertyValueFactory<TableData,String>("email"));
c4.setCellFactory(new TextFieldCellFactory());
table.getColumns().addAll(c1,c2,c3,c4);
Stage.setScene(scene);
Stage.show();
}
}
Related
I've got an object that looks like this
import lombok.Data;
import org.neo4j.ogm.annotation.GraphId;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Relationship;
import java.util.HashSet;
import java.util.Set;
#Data
#NodeEntity
public class GPlayer {
#GraphId
private Long id;
#Relationship(type = "comrade", direction = Relationship.UNDIRECTED)
private Set<GPlayer> comrades;
// #Indexed(unique = true) doesn't work in v4
private String name;
/**
* Adds new comrade.
*
* #param comrade comrade
*/
public void acquainted(GPlayer comrade) {
if (null == comrades) {
comrades = new HashSet<>();
} else {
if (comrades.contains(comrade)) {
return;
}
}
comrades.add(comrade);
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
GPlayer gPlayer = (GPlayer) o;
if (!id.equals(gPlayer.id)) return false;
return name.equals(gPlayer.name);
}
#Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + id.hashCode();
result = 31 * result + name.hashCode();
return result;
}
#Override
public String toString() {
return "GPlayer{" +
"id=" + id +
", comrades=" + comrades +
", name='" + name + '\'' +
'}';
}
}
I want to store it in Neo4j with unique name. So when I insert GPlayer - if the object with such name doesn't exist I don't want to insert it.
I have repository that looks like this
public interface GraphPlayerRepository extends GraphRepository<GPlayer> {
List<GPlayer> findAll();
GPlayer findByName(String name);
}
To insert I do like this
private Long createPlayer(String playerName, String comrade, GraphPlayerRepository gRepo) {
GPlayer gPlayer = gRepo.findByName(playerName);
if (null == gPlayer) {
gPlayer = new GPlayer();
gPlayer.setName(playerName);
if (null != comrade) {
gPlayer.acquainted(gRepo.findByName(comrade));
}
gRepo.save(gPlayer);
LOGGER.info("Created new GRAPH player: {}", gPlayer);
} else {
gPlayer.acquainted(gRepo.findByName(comrade));
gRepo.save(gPlayer);
LOGGER.info("Updated player: {}", gPlayer);
}
return gPlayer.getId();
}
But it looks rather verbose. Is there a way to make it simpler?
You could use the name as the id of the entity
#Index(unique=true, primary=true)
private String name;
Then no need to declare the findByName method, just use Neo4jRepository
public interface GraphPlayerRepository extends Neo4jRepository<GPlayer, String> {
...
}
and use repository.findOne(name) to get players from the name.
That said, the implementation of hashCode and Equals is incorrect : it is strongly advised not to use the Long id in these. See here.
Otherwise, not related to SDN, but improvements could include :
use lombok to generate hashcode and equals
initialize the hashSet at the field level
You could also migrate to SDN 5 and make use of Optional return types to avoid the if/else nullity check blocks.
I am moving my android application from asmack-android library to Smack 4.1.4. I have some PacketExtensions in the asmack version of Smack, which uses PacketExtension and PacketExtensionProvider classes to handle. Since the PacketExtension is deprecated in Smack 4.1.4, I am confused among the classes and interfaces ExtensionElement, DataPacketExtension, ExtensionElementProvider , DefaultExtensionElement. Could any one of you give me an example of creating an extension which can be added with stanza and parse back...https://www.igniterealtime.org/builds/smack/docs/latest/javadoc/org/jivesoftware /smack/packet/DefaultExtensionElement.htmlhttps://www.igniterealtime.org/builds/smack/docs/latest/javadoc/org/jivesoftware /smack/provider/ExtensionElementProvider.html
Message message = new Message();
message.setStanzaId("923442621149");
message.setType(Type.chat);
message.setBody("shanraisshan");
Log.e("message --->", message.toXML().toString());
This will produce the following stanza
<message id='923442621149' type='chat'><body>shanraisshan</body></message>
1. CUSTOM EXTENSION STANZA TYPE-1
In order to generate below custom extension stanza
<message id='923442621149' type='chat'><body>shanraisshan</body>
<reply xmlns='shayan:reply' rText='this is custom attribute'/>
</message>
where reply is a custom extension, which contains
Element (reply)
Namespace (shayan:reply)
the list of default xmpp namespaces are available at Official XMPP website
Do following steps
1. Add ReplyExtension.java in your project
ReplyExtension.java
package com.xmpp.extensions;
import org.jivesoftware.smack.packet.DefaultExtensionElement;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.provider.EmbeddedExtensionProvider;
import org.jivesoftware.smack.util.XmlStringBuilder;
import java.util.List;
import java.util.Map;
/**
* Shayan Rais (http://shanraisshan.com)
* created on 9/7/2016
*/
public class ReplyExtension implements ExtensionElement {
public static final String NAMESPACE = "shayan:reply";
public static final String ELEMENT = "reply";
String rText = null;
static final String ATTRIBUTE_REPLY_TEXT = "rText";
#Override
public String getElementName() {
return ELEMENT;
}
#Override
public String getNamespace() {
return NAMESPACE;
}
#Override
public XmlStringBuilder toXML() {
XmlStringBuilder xml = new XmlStringBuilder(this);
xml.attribute(ATTRIBUTE_REPLY_TEXT, getReplyText());
xml.closeEmptyElement();
return xml;
}
//__________________________________________________________________________________________________
public void setReplyText(String _rText) {
rText = _rText;
}
public String getReplyText() {
return rText;
}
//__________________________________________________________________________________________________
public static class Provider extends EmbeddedExtensionProvider<ReplyExtension> {
#Override
protected ReplyExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends ExtensionElement> content) {
ReplyExtension repExt = new ReplyExtension();
repExt.setReplyText(attributeMap.get(ATTRIBUTE_REPLY_TEXT));
return repExt;
}
}
}
2. Register ReplyExtension in your Provider Manager
ProviderManager.addExtensionProvider(ReplyExtension.ELEMENT, ReplyExtension.NAMESPACE, new ReplyExtension.Provider());
FOR SENDING MESSAGES
You can generate the custom extension stanza TYPE-1 by using following code
Message message = new Message();
message.setStanzaId("923442621149");
message.setType(Type.chat);
message.setBody("shanraisshan");
//adding custom reply extension
ReplyExtension repExt = new ReplyExtension();
repExt.setReplyText("this is custom attribute");
message.addExtension(repExt);
Log.e("message --->", message.toXML().toString());
DURING RECEIVING MESSAGES
Now during receiving custom extension stanzas, you need to cast the extension to get attribute values.
//check for message with reply extension
ExtensionElement packetExtension = message.getExtension(ReplyExtension.NAMESPACE);
ReplyExtension repExt = (ReplyExtension)packetExtension;
if(repExt!=null) {
Log.e("--->", " --- LOG REPLY EXTENSION ---");
Log.e("--->", repExt.toXML() + "");
Log.e("--->", repExt.getReplyText() + ""); //this is custom attribute
}
_______________________________________________________
2. CUSTOM EXTENSION STANZA TYPE-2
In order to generate below custom extension stanza
<message id='923442621149' type='chat'><body>shanraisshan</body>
<reply xmlns='shayan:reply'><rText>this is custom attribute</rText></reply>
</message>
FOR SENDING MESSAGES
You can generate the custom extension stanza TYPE-2 by using following code
Message message = new Message();
message.setStanzaId("923442621149");
message.setType(Type.chat);
message.setBody("shanraisshan");
//adding custom reply extension
DefaultExtensionElement repExt = new DefaultExtensionElement("reply", "shayan:reply");
repExt.setValue("rText", "this is custom attribute");
message.addExtension(repExt);
Log.e("message --->", message.toXML().toString());
DURING RECEIVING MESSAGES
DefaultExtensionElement repExt = (DefaultExtensionElement) message.getExtension("shayan:reply");
if(repExt!=null) {
Log.e("--->", " --- LOG REPLY EXTENSION ---");
Log.e(getClass().getSimpleName(), repExt.getValue("rText"));
}
Finally figured it out.... Here is the solution for it...
import org.jivesoftware.smack.packet.DefaultExtensionElement;
public class IM_FileSharing_Extension extends DefaultExtensionElement implements
IM_Commons_Extension_FileSharing {
private String fileUrl;
private String fileType;
private String base64preview;
private String fileId;
private String fileSize;
public IM_FileSharing_Extension(String fileUrl, String fileType,
String base64preview, String fileId, String fileSize) {
super(FILE_TAG, XMLNS);
this.fileUrl = fileUrl;
this.fileType = fileType;
this.base64preview = base64preview;
this.fileId = fileId;
this.fileSize = fileSize;
}
#Override
public String toXML() {
StringBuilder sb = new StringBuilder("<" + FILE_TAG + " xmlns=\""
+ XMLNS + "\" ");
sb.append(FILE_URL + "=\"" + fileUrl + "\" ");
sb.append(FILE_ID + "=\"" + fileId + "\" ");
sb.append(FILE_TYPE + "=\"" + fileType + "\" ");
sb.append(FILE_SIZE + "=\"" + fileSize + "\">");
sb.append("<" + FILE_PREVIEW_TAG + ">" + base64preview + "</"
+ FILE_PREVIEW_TAG + ">");
sb.append("</" + FILE_TAG + ">");
return sb.toString();
}
public String getFileUrl() {
return fileUrl;
}
public void setFileUrl(String fileUrl) {
this.fileUrl = fileUrl;
}
public String getBase64preview() {
return base64preview;
}
public void setBase64preview(String base64preview) {
this.base64preview = base64preview;
}
public String getFileId() {
return fileId;
}
public void setFileId(String fileId) {
this.fileId = fileId;
}
public String getFileType() {
return fileType;
}
public void setFileType(String fileType) {
this.fileType = fileType;
}
public String getFileSize() {
return fileSize;
}
public void setFileSize(String fileSize) {
this.fileSize = fileSize;
}
}
Provider for the above extension is as follows...
import java.io.IOException;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.provider.ExtensionElementProvider;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.util.Log;
public class IM_FileSharingExtension_Provider extends
ExtensionElementProvider<IM_FileSharing_Extension> implements
IM_Commons_Extension_FileSharing {
static final String TAG = "file_extension";
#Override
public IM_FileSharing_Extension parse(XmlPullParser parser, int initialDepth)
throws XmlPullParserException, IOException, SmackException {
IM_FileSharing_Extension fileExtension = null;
boolean stop = false;
String n = null;
int evtType;
String fileUrl = null;
String fileType = null;
String fileId = null;
String fileSize = null;
while (!stop) {
evtType = parser.getEventType();
n = parser.getName();
Log.d(TAG, "n:" + n + " evt:" + evtType);
switch (evtType) {
case XmlPullParser.START_TAG:
if (FILE_TAG.equals(n)) {
fileUrl = parser.getAttributeValue("", FILE_URL);
fileType = parser.getAttributeValue("", FILE_TYPE);
fileId = parser.getAttributeValue("", FILE_ID);
fileSize = parser.getAttributeValue("", FILE_SIZE);
evtType = parser.next();
}
if (FILE_PREVIEW_TAG.equals(parser.getName())) {
String basePreview = parser.nextText();
fileExtension = new IM_FileSharing_Extension(fileUrl,
fileType, basePreview, fileId, fileSize);
}
evtType = parser.next();
break;
case XmlPullParser.END_TAG:
if (parser.getName().equals(FILE_TAG)) {
return fileExtension;
}
evtType = parser.next();
}
}
return null;
}
}
And should be added in Provider manager as following....
ProviderManager.addExtensionProvider(
IM_Commons_Extension_FileSharing.FILE_TAG,
IM_Commons_Extension_FileSharing.XMLNS,
new IM_FileSharingExtension_Provider());
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
NoClassDefFoundError importing a library project
My blackberry application suddenly stopped working. My simulator or/and my application does not load up, I get the " Uncaught Exception: java.lang.NoClassDefFoundError ". I have not made any changes to my code since I last tested it. What has gone wrong?
package mypackage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.rmi.RemoteException;
import java.util.Hashtable;
import java.util.Vector;
import javacard.framework.UserException;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.location.Location;
import javax.microedition.location.LocationProvider;
import org.kobjects.base64.Base64;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransport;
import org.xmlpull.v1.XmlPullParserException;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.component.pane.TitleView;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.image.Image;
public class LoginTest extends UiApplication
{
public static void main(String[] args)
{
//Create a new instance of the app
//and start the app on the event thread.
LoginTest app = new LoginTest();
app.enterEventDispatcher();
}
public LoginTest()
{
//Display a new screen.
pushScreen(new LoginTestScreen());
}
}
//Create a new screen that extends MainScreen and provides
//behaviour similar to that of other apps.
final class LoginTestScreen extends MainScreen
{
//declare variables for later use
private InfoScreen _infoScreen;
private ObjectChoiceField choiceField;
private int select;
BasicEditField username;
PasswordEditField passwd;
CheckboxField checkBox1;
ButtonField loginBtn;
public LoginTestScreen()
{
//Invoke the MainScreen constructor.
super();
//Add a screen title.
setTitle("Track24ELMS");
LabelField login = new LabelField("ELMS Login", LabelField.FIELD_HCENTER);
login.setFont(Font.getDefault().derive(Font.BOLD, 30));
login.setMargin(10, 0, 20, 0); //To leave some space from top and bottom
HorizontalFieldManager user = new HorizontalFieldManager();
user.setMargin(0, 0, 10, 0);
HorizontalFieldManager pass = new HorizontalFieldManager();
pass.setMargin(0, 0, 20, 0);
HorizontalFieldManager checkbox = new HorizontalFieldManager();
checkbox.setMargin(0, 0, 30, 0);
HorizontalFieldManager btns = new HorizontalFieldManager(HorizontalFieldManager.FIELD_HCENTER);
LabelField usernameTxt = new LabelField("Username :");
LabelField passwordTxt = new LabelField("Password :");
username = new BasicEditField();
passwd = new PasswordEditField();
loginBtn = new ButtonField("Login", ButtonField.CONSUME_CLICK);
loginBtn.setChangeListener(new LoginButtonListener());
checkBox1 = new CheckboxField("Remember me",false);
user.add(usernameTxt);
user.add(username);
pass.add(passwordTxt);
pass.add(passwd);
btns.add(loginBtn);
add(login);
add(user);
add(pass);
add(checkBox1);
add(btns);
}
private class LoginButtonListener implements FieldChangeListener {
public void fieldChanged(Field field, int context) {
//Open a new screen
String uname = username.getText();
String pwd = passwd.getText();
String sep = "</>";
//If there is no input
if (uname.length() == 0 || pwd.length()==0)
Dialog.alert("One of the textfield is empty!");
else
{
String URL = "http://xxx.xxx.com/xxx/xxx.asmx";
String METHOD_NAME = "ValidateCredentials";
String NAMESPACE = "http://tempuri.org/";
String SOAP_ACTION = NAMESPACE+METHOD_NAME;
//final String URL = "http://prerel.track24elms.com/Android/T24AndroidLogin.asmx/ValidateCredentials";
SoapObject resultRequestSOAP = null;
HttpConnection httpConn = null;
HttpTransport httpt;
System.out.println("The username" + uname + "password" + pwd );
SoapPrimitive response = null;
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//String usernamecode = Base64.encode(uname.getBytes());
//String pwdEncodeString = Base64.encode(pwd.getBytes());
request.addProperty("username", uname);
request.addProperty("password", pwd);
System.out.println("The request is=======" + request.toString());
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
//envelope.bodyOut = request;
envelope.dotNet = true;
//envelope.encodingStyle = SoapSerializationEnvelope.XSD;
envelope.setOutputSoapObject(request);
System.out.println("The envelope has the value++++"+ envelope.toString());
/* URL+ Here you can add paramter so that you can run on device,simulator etc. this will work only for wifi */
httpt = new HttpTransport(URL+ ";deviceside=true;ConnectionUID=S TCP");
//httpt.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
httpt.debug = true;
try
{
System.out.println("SOAP_ACTION == " + SOAP_ACTION);
httpt.call(SOAP_ACTION, envelope);
response = (SoapPrimitive) envelope.getResponse();
String result = response.toString();
System.out.println("response == " + result);
resultRequestSOAP = (SoapObject) envelope.bodyIn;
System.out.println("result == " + resultRequestSOAP);
String[] listResult = split(result, sep);
}
catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("The exception is IO==" + e.getMessage());
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
System.out.println("The exception xml parser example==="
+ e.getMessage());
}
System.out.println( resultRequestSOAP);
//UiApplication.getUiApplication().pushScreen(new InfoScreen()); //Open a new Screen
}
}
};
private String[] split(String original, String separator) {
Vector nodes = new Vector();
int index = original.indexOf(separator);
while (index >= 0) {
nodes.addElement(original.substring(0, index));
original = original.substring(index + separator.length());
index = original.indexOf(separator);
}
nodes.addElement(original);
String[] result = new String[nodes.size()];
if (nodes.size() > 0) {
for (int loop = 0; loop < nodes.size(); loop++) {
result[loop] = (String) nodes.elementAt(loop);
System.out.println(result[loop]);
}
}
return result;
}
//To display a dialog box when a BlackBerry device user
//closes the app, override the onClose() method.
public boolean onClose()
{
Dialog.alert("Goodbye!");
System.exit(0);
return true;
}
//Create a menu item for BlackBerry device users to click to see more
//information about the city they select.
private MenuItem _viewItem = new MenuItem("More Info", 110, 10)
{
public void run()
{
//Store the index of the city the BlackBerry device user selects
select = choiceField.getSelectedIndex();
//Display a new screen with information about the
//city the BlackBerry device user selects
_infoScreen = new InfoScreen();
UiApplication.getUiApplication().pushScreen(_infoScreen);
}
};
//Create a menu item for BlackBerry device users to click to close
//the app.
private MenuItem _closeItem = new MenuItem("Close", 200000, 10)
{
public void run()
{
onClose();
}
};
//Create an inner class for a new screen that displays
//information about the city a BlackBerry device user selects.
private class InfoScreen extends MainScreen
{
String latitude, logitude, altitude;
public InfoScreen()
{
super();
setTitle("Itinerary");
LabelField login = new LabelField("Employee Itinerary", LabelField.FIELD_HCENTER);
HorizontalFieldManager userDetails = new HorizontalFieldManager();
userDetails.setMargin(0, 0, 10, 0);
HorizontalFieldManager statusBox = new HorizontalFieldManager();
statusBox.setMargin(0, 0, 20, 0);
HorizontalFieldManager locationDetails = new HorizontalFieldManager();
locationDetails.setMargin(0, 0, 30, 0);
HorizontalFieldManager imgBtn = new HorizontalFieldManager();
imgBtn.setMargin(0, 0, 40, 0);
//BitmapField userImg = new BitmapField(Bitmap.getBitmapResource("img1.jpg"));
LabelField userFetched = new LabelField("Sarah Farukh");
LabelField lastStatus = new LabelField("I am OK");
EditField statusMsg = new EditField("Status Message", "Update status here");
EditField lat = new EditField("Latitude", "latitude");
EditField longi = new EditField("Longitude", "logitude");
EditField alti = new EditField("Attitude", "altitude");
//BitmapField btnOK = new BitmapField(Bitmap.getBitmapResource("ok.png"),Field.FIELD_BOTTOM);
//BitmapField btnNO = new BitmapField(Bitmap.getBitmapResource("no.png"),Field.FIELD_BOTTOM);
//BitmapField btnHN = new BitmapField(Bitmap.getBitmapResource("hn.png"),Field.FIELD_BOTTOM);
//userDetails.add(userImg);
userDetails.add(userFetched);
userDetails.add(lastStatus);
statusBox.add(userFetched);
locationDetails.add(lat);
locationDetails.add(longi);
locationDetails.add(alti);
//imgBtn.add(btnOK);
//imgBtn.add(btnNO);
//imgBtn.add(btnHN);
add(login);
add(userDetails);
add(statusBox);
add(locationDetails);
add(imgBtn);
}
}
}
It is possible that you are accessing a class in a separate library. You have set up your project so that the class is found at build time.
If that library was not deployed to the device for some reason (forgot to? error when deploying?), then your class will not be found at runtime.
Either make sure to deploy this library properly onto the device (by uploading the correct compiled COD file).
Or include the library into your project by setting up your build path correctly.
(my answer based on this one: NoClassDefFoundError importing a library project)
Please anyone help me get selected listitems from a listfieldcheckbox, and add them into an arraylist. If possible, give any useful links also. Here's my code so far (I am new to blackberry application development). Please help.
package mypackage;
import java.util.Vector;
import net.rim.device.api.system.Characters;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.ListField;
import net.rim.device.api.ui.component.ListFieldCallback;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
import net.rim.device.api.util.IntVector;
/**
* A class extending the MainScreen class, which provides default standard
* behavior for BlackBerry GUI applications.
*/
public final class MyScreen extends MainScreen implements ListFieldCallback
{
private Vector _listData = new Vector();
private Vector _checkedData = new Vector();
private ListField listField;
private static final String[] _elements = {"First element", "Second element","Third element"
};
//private static final String[] _elements1 = {"hai","welcome","where r u"
//};
private MenuItem _getDataMenu,selectall,Delete;
Vector result = new Vector();
protected void makeMenu(Menu menu, int instance)
{
menu.add(_getDataMenu);
menu.add(selectall);
menu.add(Delete);
//Create the default menu.
super.makeMenu(menu, instance);
}
private class ChecklistData
{
private String _stringVal;
private boolean _checked;
ChecklistData(String stringVal, boolean checked)
{
_stringVal = stringVal;
_checked = checked;
}
//Get/set methods.
private String getStringVal()
{
return _stringVal;
}
private boolean isChecked()
{
return _checked;
}
//Toggle the checked status.
private void toggleChecked()
{
_checked = !_checked;
}
}
public Vector getCheckedItems() {
return _checkedData;
}
/**
* Creates a new MyScreen object
*/
public MyScreen()
{
// Set the displayed title of the screen
setTitle("MyTitle");
VerticalFieldManager main = new VerticalFieldManager(VerticalFieldManager.USE_ALL_HEIGHT|
VerticalFieldManager.USE_ALL_WIDTH|VerticalFieldManager.VERTICAL_SCROLL);
this.add(main);
HorizontalFieldManager hfm = new HorizontalFieldManager();
main.add(hfm);
listField = new ListField(){
//Allow the space bar to toggle the status of the selected row.
protected boolean keyChar(char key, int status, int time)
{
boolean retVal = false;
//If the spacebar was pressed...
if (key == Characters.SPACE)
{
//Get the index of the selected row.
int index = getSelectedIndex();
//Get the ChecklistData for this row.
ChecklistData data = (ChecklistData)_listData.elementAt(index);
//Toggle its status.
data.toggleChecked();
//Update the Vector with the new ChecklistData.
_listData.setElementAt(data, index);
//Invalidate the modified row of the ListField.
invalidate(index);
//Consume this keyChar (key pressed).
retVal = true;
}
return retVal;
}
};
listField.setCallback(this);
reloadList();
int elementLength = _elements.length;
for(int count = 0; count < elementLength; ++count)
{
_listData.addElement(new ChecklistData(_elements[count], false));
//_listData.addElement(new ChecklistData(_elements1[count], false));
listField.insert(count);
}
main.add(listField);
_getDataMenu =new MenuItem("Get Data", 200, 10) {
public void run(){
int index = listField.getSelectedIndex();
ChecklistData data = (ChecklistData)_listData.elementAt(index);
String message = "Selected data: " + data.getStringVal() + ", and status: " + data.isChecked();
//Dialog.alert(message);
// get all the checked data indices
IntVector selectedIndex = new IntVector(0, 1);
//ChecklistData data;
for (int i=0;i<_listData.size();i++) {
data = (ChecklistData)_listData.elementAt(i);
if(data.isChecked()) {
selectedIndex.addElement(i);
String selectedvalues = data.getStringVal();
System.out.println("Selected items are:"+selectedvalues);
}
}
data = null;
// now selectedIndex will contain all the checked data indices.
//String message = "Selected data: " + data.getStringVal() + ", and status: " + data.isChecked();
}
};
selectall = new MenuItem("Selectall", 200, 10){
public void run(){
int elementLength = _elements.length;
for(int count = 0; count < elementLength; ++count)
{
_listData.setElementAt(new ChecklistData(_elements[count], true), count);
}
}
};
Delete = new MenuItem("Delete", 200, 10){
public void run(){
int index = listField.getSelectedIndex();
_listData.removeElementAt(index);
// update the view
listField.delete(index);
listField.invalidate(index);
}
};
}
private void reloadList() {
// TODO Auto-generated method stub
_listData.setSize(_listData.size());
}
public void drawListRow(ListField list, Graphics graphics, int index, int y, int w)
{
ChecklistData currentRow = (ChecklistData)this.get(list, index);
StringBuffer rowString = new StringBuffer();
if (currentRow.isChecked())
{
rowString.append(Characters.BALLOT_BOX_WITH_CHECK);
}
else
{
rowString.append(Characters.BALLOT_BOX);
}
//Append a couple spaces and the row's text.
rowString.append(Characters.SPACE);
rowString.append(Characters.SPACE);
rowString.append(currentRow.getStringVal());
//Draw the text.
graphics.drawText(rowString.toString(), 0, y, 0, w);
/*if (currentRow.isChecked()) {
if( -1 ==_checkedData.indexOf(currentRow))
_checkedData.addElement(currentRow);
rowString.append(Characters.BALLOT_BOX_WITH_CHECK);
}
else {
if( -1 !=_checkedData.indexOf(currentRow))
_checkedData.removeElement(currentRow);
rowString.append(Characters.BALLOT_BOX);
} */
}
//Returns the object at the specified index.
public Object get(ListField list, int index)
{
return _listData.elementAt(index);
}
public int indexOfList(ListField list, String p, int s)
{
//return listElements.getSelectedIndex();
return _listData.indexOf(p, s);
}
//Returns the screen width so the list uses the entire screen width.
public int getPreferredWidth(ListField list)
{
return Display.getWidth();
}
protected boolean navigationClick(int status, int time) {
int index1 = listField.getSelectedIndex();
/*System.out.println("Selected item index:"+index1);
//int[] list =listField.getSelection();
//String s = Integer.toString(list);
System.out.println(" items are:"+_elements[index1]);
//ChecklistData data = (ChecklistData)_listData.elementAt(index1);*/
//Get the ChecklistData for this row.
ChecklistData data = (ChecklistData)_listData.elementAt(index1);
String message = "Selected data: " + data.getStringVal() + ", and status: " + data.isChecked();
System.out.println("message is:"+message);
//Toggle its status.
data.toggleChecked();
//Update the Vector with the new ChecklistData.
_listData.setElementAt(data, index1);
//Invalidate the modified row of the ListField.
listField.invalidate(index1);
return true;
}
}
I want a basic edit field where the first character entered goes to the right most position ...something like this..
2
23
234
can any one tell me how to do this...
Here's one way to do it:
import net.rim.device.api.system.Characters;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.DrawStyle;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.XYRect;
import net.rim.device.api.ui.component.BasicEditField;
public class RightInsertTextField extends BasicEditField {
private String lastGoodTxtInputEntry = null;
private int maxCharInputLength = 20;
private Field nextFieldForFocus = null;
/**
* Basic constructor.
*
* #param defaultValue
*/
public RightInsertTextField(String defaultValue) {
super("", defaultValue);
}
public void paint(Graphics g) {
String txt = this.getText();
// 1. (Optional) keeping a check on input length can help
// minimize custom code needed to handle wrap-around text.
if (txt.length() > this.getMaxCharInputLength() && this.getMaxCharInputLength() > 0) {
txt = this.lastGoodTxtInputEntry;
this.setText(txt);
} else {
this.lastGoodTxtInputEntry = txt;
}
// 2. get rid of the default cursor painting by coloring over it with
// the same color as the background
XYRect xy = g.getClippingRect();
g.setBackgroundColor(Color.WHITE);
g.fillRect(xy.x, xy.y, xy.width, xy.height);
g.clear();
// 3. Align text to the right.
g.setColor(Color.BLACK);
g.drawText(txt, 0, 0, (DrawStyle.RIGHT + DrawStyle.ELLIPSIS), getWidth());
}
/**
* Look out for 'ENTER' being pressed.
*/
public boolean keyChar(char key, int status, int time) {
// Prevent new lines in input field.
if (Characters.ENTER == key) {
if (this.nextFieldForFocus != null) {
this.nextFieldForFocus.setFocus();
}
return true;
} else {
return super.keyChar(key, status, time);
}
}
public void setMaxCharInputLength(int maxCharInputLength) {
this.maxCharInputLength = maxCharInputLength;
}
public int getMaxCharInputLength() {
return maxCharInputLength;
}
/**
* #param nextFieldForFocus
* the nextFieldForFocus to set if 'ENTER' is pressed.
*/
public void setNextFieldForFocus(Field nextFieldForFocus) {
this.nextFieldForFocus = nextFieldForFocus;
}
}
This would help
editField = new EditField("", "", maxChars, EditField.NO_NEWLINE | EditField.NON_SPELLCHECKABLE){
private String text = "";
protected boolean keyChar(char key, int status, int time){
switch (key){
case Characters.BACKSPACE:{
try {
text = text.substring(0,text.length()-1);
invalidate();
} catch (IndexOutOfBoundsException e) {}
return true;
}
}
text = text + key;
invalidate();
return true;
}
protected void paint(Graphics graphics) {
graphics.drawText(text,0, 0, DrawStyle.RIGHT, width - 10);
super.paint(graphics);
}
};
Use style Field.FIELD_RIGHT.
Pretty sure that there is no built in way to do this, you gona have to implement your own text box