I found a java implementation of a trie and would like to have a similar one in J2ME. Here is the code.
Node class
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
class Node {
private final char ch;
/**
* Flag indicates that this node is the end of the string.
*/
private boolean end;
private LinkedList<Node> children;
public Node(char ch) {
this.ch = ch;
}
public void addChild(Node node) {
if (children == null) {
children = new LinkedList<Node>();
}
children.add(node);
}
public Node getNode(char ch) {
if (children == null) {
return null;
}
for (Node child : children) {
if (child.getChar() == ch) {
return child;
}
}
return null;
}
public char getChar() {
return ch;
}
public List<Node> getChildren() {
if (this.children == null) {
return Collections.emptyList();
}
return children;
}
public boolean isEnd() {
return end;
}
public void setEnd(boolean end) {
this.end = end;
}
}
TrieNode Class
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class WordTree {
Node root = new Node(' ');
public WordTree() {
}
/**
* Searches for a strings that match the prefix.
*
* #param prefix - prefix
* #return - list of strings that match the prefix, or empty list of no matches are found.
*/
public List<String> getWordsForPrefix(String prefix) {
if (prefix.length() == 0) {
return Collections.emptyList();
}
Node node = getNodeForPrefix(root, prefix);
if (node == null) {
return Collections.emptyList();
}
List<LinkedList<Character>> chars = collectChars(node);
List<String> words = new ArrayList<String>(chars.size());
for (LinkedList<Character> charList : chars) {
words.add(combine(prefix.substring(0, prefix.length() - 1), charList));
}
return words;
}
private String combine(String prefix, List<Character> charList) {
StringBuilder sb = new StringBuilder(prefix);
for (Character character : charList) {
sb.append(character);
}
return sb.toString();
}
private Node getNodeForPrefix(Node node, String prefix) {
if (prefix.length() == 0) {
return node;
}
Node next = node.getNode(prefix.charAt(0));
if (next == null) {
return null;
}
return getNodeForPrefix(next, prefix.substring(1, prefix.length()));
}
private List<LinkedList<Character>> collectChars(Node node) {
List<LinkedList<Character>> chars = new ArrayList<LinkedList<Character>>();
if (node.getChildren().size() == 0) {
chars.add(new LinkedList<Character>(Collections.singletonList(node.getChar())));
} else {
if (node.isEnd()) {
chars.add(new LinkedList<Character> (Collections.singletonList(node.getChar())));
}
List<Node> children = node.getChildren();
for (Node child : children) {
List<LinkedList<Character>> childList = collectChars(child);
for (LinkedList<Character> characters : childList) {
characters.push(node.getChar());
chars.add(characters);
}
}
}
return chars;
}
public void addWord(String word) {
addWord(root, word);
}
private void addWord(Node parent, String word) {
if (word.trim().length() == 0) {
return;
}
Node child = parent.getNode(word.charAt(0));
if (child == null) {
child = new Node(word.charAt(0));
parent.addChild(child);
}
if (word.length() == 1) {
child.setEnd(true);
} else {
addWord(child, word.substring(1, word.length()));
}
}
public void load() {
WordTree tree = new WordTree();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(new File("C:/Users/Sironka/Documents/NetBeansProjects/Final Maa Adaptive System/dictionary/Maa Corpus.txt-02-ngrams-Freq.txt")));
String eachLine = null;
while ((eachLine = br.readLine()) != null) {
tree.addWord(eachLine);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println(tree.getWordsForPrefix("ore"));
}
public static void main(String[] args) {
WordTree trieloader = new WordTree();
trieloader.load();
System.out.println("");
}
}
Here are the challenges:
1. Changing the for loop format
2. Classes like linkedList, Collections are not available in j2me
Request:
1. converting the above to j2me. (A similar j2me implementation will help).
Please assist me in this since i am completely stuck in my project. The trie will assist me in text prediction (t9).
It seems there is no builtin implementation in J2ME but this code might be an option:
Just try the implementation mentioned in this post.
You can download the code here.
Related
I am reading java 8 in action and the author references this link: http://mail.openjdk.java.net/pipermail/lambda-dev/2013-November/011516.html
and writes his own stream forker that looks like this:
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class Main {
public static void main(String... args) {
List<Person> people = Arrays.asList(new Person(23, "Paul"), new Person(24, "Nastya"), new Person(30, "Unknown"));
StreamForker<Person> forker = new StreamForker<>(people.stream())
.fork("All names", s -> s.map(Person::getName).collect(Collectors.joining(", ")))
.fork("Age stats", s -> s.collect(Collectors.summarizingInt(Person::getAge)))
.fork("Oldest", s -> s.reduce((p1, p2) -> p1.getAge() > p2.getAge() ? p1 : p2).get());
Results results = forker.getResults();
String allNames = results.get("All names");
IntSummaryStatistics stats = results.get("Age stats");
Person oldest = results.get("Oldest");
System.out.println(allNames);
System.out.println(stats);
System.out.println(oldest);
}
interface Results {
<R> R get(Object key);
}
static class StreamForker<T> {
private final Stream<T> stream;
private final Map<Object, Function<Stream<T>, ?>> forks = new HashMap<>();
public StreamForker(Stream<T> stream) {
this.stream = stream;
}
public StreamForker<T> fork(Object key, Function<Stream<T>, ?> f) {
forks.put(key, f);
return this;
}
public Results getResults() {
ForkingStreamConsumer<T> consumer = build();
try {
stream.sequential().forEach(consumer);
} finally {
consumer.finish();
}
return consumer;
}
private ForkingStreamConsumer<T> build() {
List<BlockingQueue<T>> queues = new ArrayList<>();
Map<Object, Future<?>> actions =
forks.entrySet().stream().reduce(
new HashMap<>(),
(map, e) -> {
map.put(e.getKey(),
getOperationResult(queues, e.getValue()));
return map;
},
(m1, m2) -> {
m1.putAll(m2);
return m1;
}
);
return new ForkingStreamConsumer<>(queues, actions);
}
private Future<?> getOperationResult(List<BlockingQueue<T>> queues,
Function<Stream<T>, ?> f) {
BlockingQueue<T> queue = new LinkedBlockingQueue<>();
queues.add(queue);
Spliterator<T> spliterator = new BlockingQueueSpliterator<>(queue);
Stream<T> source = StreamSupport.stream(spliterator, false);
return CompletableFuture.supplyAsync(() -> f.apply(source));
}
}
static class ForkingStreamConsumer<T> implements Results, Consumer<T> {
static final Object END_OF_STREAM = new Object();
private final List<BlockingQueue<T>> queues;
private final Map<Object, Future<?>> actions;
ForkingStreamConsumer(List<BlockingQueue<T>> queues,
Map<Object, Future<?>> actions) {
this.queues = queues;
this.actions = actions;
}
public void finish() {
accept((T) END_OF_STREAM);
}
#Override
public <R> R get(Object key) {
try {
return ((Future<R>) actions.get(key)).get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
#Override
public void accept(T t) {
queues.forEach(q -> q.add(t));
}
}
static class BlockingQueueSpliterator<T> implements Spliterator<T> {
private final BlockingQueue<T> q;
public BlockingQueueSpliterator(BlockingQueue<T> q) {
this.q = q;
}
#Override
public boolean tryAdvance(Consumer<? super T> action) {
T t;
while (true) {
try {
t = q.take();
break;
} catch (InterruptedException e) {
}
}
if (t != ForkingStreamConsumer.END_OF_STREAM) {
action.accept(t);
return true;
}
return false;
}
#Override
public Spliterator<T> trySplit() {
return null;
}
#Override
public long estimateSize() {
return 0;
}
#Override
public int characteristics() {
return 0;
}
}
static class Person {
private int age;
private String name;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
#Override
public String toString() {
return String.format("Age: %d, name: %s", age, name);
}
}
}
How the code written by the author works:
First, we create a StreamForker out of a stream. Then we fork 3 operations, saying what we want to do on that stream in parallel. In our case, our data model is the Person{age, name} class and we want to perform 3 actions:
Get a string of all names
Get age statistics
Get the oldest person
we then call the forker.getResults() method, that applies a StreamForkerConsumer to the stream, spreading its elements into 3 blocking queues, which are then turned into 3 streams and processed in parallel.
My question is, does this approach have any advantage over just doing this:
Future<String> allNames2 =
CompletableFuture.supplyAsync(() -> people.stream().map(Person::getName).collect(Collectors.joining(", ")));
Future<IntSummaryStatistics> stats2 =
CompletableFuture.supplyAsync(() -> people.stream().collect(Collectors.summarizingInt(Person::getAge)));
Future<Person> oldest2 =
CompletableFuture.supplyAsync(() -> people.stream().reduce((p1, p2) -> p1.getAge() > p2.getAge() ? p1 : p2).get());
?
For me this doesn't make much sense with an array list as stream source.
If the stream source is a big file that you process with
StreamForker<Person> forker = new StreamForker<>(
java.nio.file.Files.lines(Paths.get("somepath"))
.map(Person::new))
.fork(...)
then it could prove beneficial since you would process the whole file only once, whereas with three seperat calls to Files.lines(...) you would read the file three times.
Using Spark 1.6 and the ML library I am saving the results of a trained RandomForestClassificationModel using toDebugString():
val rfModel = model.stages(2).asInstanceOf[RandomForestClassificationModel]
val stringModel =rfModel.toDebugString
//save stringModel into a file in the driver in format .txt
So my idea is that in the future read the file .txt and load the trained randomForest, is it possible?
thanks!
That won't work. ToDebugString is merely a debug info to understand how it's got calculated.
If you want to keep this thing for later use, you can do the same we do, which is (although we are in pure java) simply serialise RandomForestModel object. There might be version incompatibilities with default java serialisation, so we use Hessian to do it. It worked through versions update - we started with spark 1.6.1 and it still works with spark 2.0.2.
If you're ok with not sticking to ml, juste use mllib's implementation: the RandomForestModel you get with mllib has a save function.
At least for Spark 2.1.0 you can do this with the following Java (sorry - no Scala) code. However, it may not be the smartest idea to rely on an undocumented format that may change without notice.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.nio.charset.StandardCharsets.US_ASCII;
/**
* RandomForest.
*/
public abstract class RandomForest {
private static final Logger LOG = LoggerFactory.getLogger(RandomForest.class);
protected final List<Node> trees = new ArrayList<>();
/**
* #param model model file (format is Spark's RandomForestClassificationModel toDebugString())
* #throws IOException
*/
public RandomForest(final URL model) throws IOException {
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(model.openStream(), US_ASCII))) {
Node node;
while ((node = load(reader)) != null) {
trees.add(node);
}
}
if (trees.isEmpty()) throw new IOException("Failed to read trees from " + model);
if (LOG.isDebugEnabled()) LOG.debug("Found " + trees.size() + " trees.");
}
private static Node load(final BufferedReader reader) throws IOException {
final Pattern ifPattern = Pattern.compile("If \\(feature (\\d+) (in|not in|<=|>) (.*)\\)");
final Pattern predictPattern = Pattern.compile("Predict: (\\d+\\.\\d+(E-\\d+)?)");
Node root = null;
final List<Node> stack = new ArrayList<>();
String line;
while ((line = reader.readLine()) != null) {
final String trimmed = line.trim();
//System.out.println(trimmed);
if (trimmed.startsWith("RandomForest")) {
// skip the "Tree 1" line
reader.readLine();
} else if (trimmed.startsWith("Tree")) {
break;
} else if (trimmed.startsWith("If")) {
// extract feature index
final Matcher m = ifPattern.matcher(trimmed);
m.matches();
final int featureIndex = Integer.parseInt(m.group(1));
final String operator = m.group(2);
final String operand = m.group(3);
final Predicate<Float> predicate;
if ("<=".equals(operator)) {
predicate = new LessOrEqual(Float.parseFloat(operand));
} else if (">".equals(operator)) {
predicate = new Greater(Float.parseFloat(operand));
} else if ("in".equals(operator)) {
predicate = new In(parseFloatArray(operand));
} else if ("not in".equals(operator)) {
predicate = new NotIn(parseFloatArray(operand));
} else {
predicate = null;
}
final Node node = new Node(featureIndex, predicate);
if (stack.isEmpty()) {
root = node;
} else {
insert(stack, node);
}
stack.add(node);
} else if (trimmed.startsWith("Predict")) {
final Matcher m = predictPattern.matcher(trimmed);
m.matches();
final Object node = Float.parseFloat(m.group(1));
insert(stack, node);
}
}
return root;
}
private static void insert(final List<Node> stack, final Object node) {
Node parent = stack.get(stack.size() - 1);
while (parent.getLeftChild() != null && parent.getRightChild() != null) {
stack.remove(stack.size() - 1);
parent = stack.get(stack.size() - 1);
}
if (parent.getLeftChild() == null) parent.setLeftChild(node);
else parent.setRightChild(node);
}
private static float[] parseFloatArray(final String set) {
final StringTokenizer st = new StringTokenizer(set, "{,}");
final float[] floats = new float[st.countTokens()];
for (int i=0; st.hasMoreTokens(); i++) {
floats[i] = Float.parseFloat(st.nextToken());
}
return floats;
}
public abstract float predict(final float[] features);
public String toDebugString() {
try {
final StringWriter sw = new StringWriter();
for (int i=0; i<trees.size(); i++) {
sw.write("Tree " + i + ":\n");
print(sw, "", trees.get(0));
}
return sw.toString();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
private static void print(final Writer w, final String indent, final Object object) throws IOException {
if (object instanceof Number) {
w.write(indent + "Predict: " + object + "\n");
} else if (object instanceof Node) {
final Node node = (Node) object;
// left node
w.write(indent + node + "\n");
print(w, indent + " ", node.getLeftChild());
w.write(indent + "Else\n");
print(w, indent + " ", node.getRightChild());
}
}
#Override
public String toString() {
return getClass().getSimpleName() + "{numTrees=" + trees.size() + "}";
}
/**
* Node.
*/
protected static class Node {
private final int featureIndex;
private final Predicate<Float> predicate;
private Object leftChild;
private Object rightChild;
public Node(final int featureIndex, final Predicate<Float> predicate) {
Objects.requireNonNull(predicate);
this.featureIndex = featureIndex;
this.predicate = predicate;
}
public void setLeftChild(final Object leftChild) {
this.leftChild = leftChild;
}
public void setRightChild(final Object rightChild) {
this.rightChild = rightChild;
}
public Object getLeftChild() {
return leftChild;
}
public Object getRightChild() {
return rightChild;
}
public Object eval(final float[] features) {
Object result = this;
do {
final Node node = (Node)result;
result = node.predicate.test(features[node.featureIndex]) ? node.leftChild : node.rightChild;
} while (result instanceof Node);
return result;
}
#Override
public String toString() {
return "If (feature " + featureIndex + " " + predicate + ")";
}
}
private static class LessOrEqual implements Predicate<Float> {
private final float value;
public LessOrEqual(final float value) {
this.value = value;
}
#Override
public boolean test(final Float f) {
return f <= value;
}
#Override
public String toString() {
return "<= " + value;
}
}
private static class Greater implements Predicate<Float> {
private final float value;
public Greater(final float value) {
this.value = value;
}
#Override
public boolean test(final Float f) {
return f > value;
}
#Override
public String toString() {
return "> " + value;
}
}
private static class In implements Predicate<Float> {
private final float[] array;
public In(final float[] array) {
this.array = array;
}
#Override
public boolean test(final Float f) {
for (int i=0; i<array.length; i++) {
if (array[i] == f) return true;
}
return false;
}
#Override
public String toString() {
return "in " + Arrays.toString(array);
}
}
private static class NotIn implements Predicate<Float> {
private final float[] array;
public NotIn(final float[] array) {
this.array = array;
}
#Override
public boolean test(final Float f) {
for (int i=0; i<array.length; i++) {
if (array[i] == f) return false;
}
return true;
}
#Override
public String toString() {
return "not in " + Arrays.toString(array);
}
}
}
To use the class for classification, use:
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
/**
* RandomForestClassifier.
*/
public class RandomForestClassifier extends RandomForest {
public RandomForestClassifier(final URL model) throws IOException {
super(model);
}
#Override
public float predict(final float[] features) {
final Map<Object, Integer> counts = new HashMap<>();
trees.stream().map(node -> node.eval(features))
.forEach(result -> {
Integer count = counts.get(result);
if (count == null) {
counts.put(result, 1);
} else {
counts.put(result, count + 1);
}
});
return (Float)counts.entrySet()
.stream()
.sorted((o1, o2) -> Integer.compare(o2.getValue(), o1.getValue()))
.map(Map.Entry::getKey)
.findFirst().get();
}
}
For regression:
import java.io.IOException;
import java.net.URL;
/**
* RandomForestRegressor.
*/
public class RandomForestRegressor extends RandomForest {
public RandomForestRegressor(final URL model) throws IOException {
super(model);
}
#Override
public float predict(final float[] features) {
return (float)trees
.stream()
.mapToDouble(node -> ((Number)node.eval(features)).doubleValue())
.average()
.getAsDouble();
}
}
I'm trying to implement pagination for a project that loads a large set of data from the database.
I've done a lot of searching on the internet already to get db-pagination to work, but for some reason I still don't get it working the way I want.
I've followed the example as described in this topic:
JSF, RichFaces, pagination
The data is loaded, so that works; cache also seems to work. However, it seems to still load all the data. The sr.getRows() in the walk-method is always -1, so the call to the database also uses -1 for maxResults. I get all my data, but no pagination.
I don't want to introduce another dependency if I can avoid it.
Some of my data:
BatchDataModel
public abstract class BatchDataModel<T> extends ExtendedDataModel<T> {
private SequenceRange cachedRange;
private Integer cachedRowCount;
private List<T> cachedList;
private Object rowKey;
public abstract List<T> getDataList(int firstRow, int numRows);
public abstract Object getKey(T t);
public abstract int getTotalCount();
#Override
public void walk(FacesContext ctx, DataVisitor dv, Range range, Object argument) {
SequenceRange sr = (SequenceRange) range;
if (cachedList == null || !equalRanges(cachedRange, sr)) {
cachedList = getDataList(sr.getFirstRow(), sr.getRows());
cachedRange = sr;
}
for (T t : cachedList) {
if (getKey(t) == null) {
/*
* the 2nd param is used to build the client id of the table
* row, i.e. mytable:234:inputname, so don't let it be null.
*/
throw new IllegalStateException("found null key");
}
dv.process(ctx, getKey(t), argument);
}
}
/*
* The rowKey is the id from getKey, presumably obtained from
* dv.process(...).
*/
#Override
public void setRowKey(Object rowKey) {
this.rowKey = rowKey;
}
#Override
public Object getRowKey() {
return rowKey;
}
#Override
public boolean isRowAvailable() {
return (getRowData() != null);
}
#Override
public int getRowCount() {
if (cachedRowCount == null) {
cachedRowCount = getTotalCount();
}
return cachedRowCount;
}
#Override
public T getRowData() {
for (T t : cachedList) {
if (getKey(t).equals(this.getRowKey())) {
return t;
}
}
return null;
}
protected static boolean equalRanges(SequenceRange range1, SequenceRange range2) {
if (range1 == null || range2 == null) {
return range1 == null && range2 == null;
} else {
return range1.getFirstRow() == range2.getFirstRow() && range1.getRows() == range2.getRows();
}
}
/*
* get/setRowIndex are used when doing multiple select in an
* extendedDataTable, apparently. Not tested. Actually, the get method is
* used when using iterationStatusVar="it" & #{it.index}.
*/
#Override
public int getRowIndex() {
if (cachedList != null) {
ListIterator<T> it = cachedList.listIterator();
while (it.hasNext()) {
T t = it.next();
if (getKey(t).equals(this.getRowKey())) {
return it.previousIndex() + cachedRange.getFirstRow();
}
}
}
return -1;
}
#Override
public void setRowIndex(int rowIndex) {
int upperBound = cachedRange.getFirstRow() + cachedRange.getRows();
if (rowIndex >= cachedRange.getFirstRow() && rowIndex < upperBound) {
int index = rowIndex % cachedRange.getRows();
T t = cachedList.get(index);
setRowKey(getKey(t));
}
}
#Override
public Object getWrappedData() {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public void setWrappedData(Object data) {
throw new UnsupportedOperationException("Not supported yet.");
}
public List<T> getCachedList() {
return cachedList;
}
Bean (part)
private ListState state;
private BatchDataModel<Batch> model;
public BatchDataModel<Batch> getModel(){
return model;
}
public int getCurrentPage() {
return state.getPage();
}
public void setCurrentPage(int page) {
state.setPage(page);
}
public void setBatchService(BatchService batchService) {
this.batchService = batchService;
}
/**
* Initialize the variables, before the page is shown.
*/
#PostConstruct
private void init() {
filter = new Filter();
sorter = new Sorter();
state = getFromSession("batchList", null);
if (state == null) {
state = new ListState();
storeInSession("batchList", state);
}
}
public void loadBatches(boolean search) {
BatchDataModel<Batch> model = new BatchDataModel<Batch>(){
#Override
public List<Batch> getDataList(int firstRow, int numRows) {
try {
List <Batch> test;
test = batchService.selectBatches(userBean.getUser(), firstRow, numRows);
return test;
} catch (NozemException e) {
LOGGER.error(e.getMessage());
sendMessage(e.getMessage(), true);
return null;
}
}
#Override
public Object getKey(Batch batch) {
return batch.getBatchId();
}
#Override
public int getTotalCount() {
try {
return batchService.countBatches(userBean.getUser());
} catch (NozemException e) {
LOGGER.error(e.getMessage());
sendMessage(e.getMessage(), true);
return 0;
}
}
};
}
xhtml (part)
<rich:dataTable id="batchesTable" rows="2"
value="#{batchBean.model}" var="batch" first="#{batchBean.currentPage}"
styleClass="table" rowClasses="odd-row, even-row"
onrowmouseover="this.style.backgroundColor='#88B5F9'"
onrowmouseout="this.style.backgroundColor='#{a4jSkin.rowBackgroundColor}'">
(...)
<f:facet name="footer">
<rich:dataScroller page="#{batchBean.currentPage}" />
</f:facet>
ArrangeableModel is the key. This class needs to be implemented in the BatchDataModel class, together with a method and function. This way the same state is used and the walk-method gets the correct values in SequenceRange.
public abstract class BatchDataModel<T> extends ExtendedDataModel<T> implements Arrangeable {
private ArrangeableState arrangeableState;
public void arrange(FacesContext context, ArrangeableState state) {
arrangeableState = state;
}
protected ArrangeableState getArrangeableState() {
return arrangeableState;
}
}
I'm currently developing a J2ME application event manager. I'm using PIM but I don't have enough knowledge on this. Can someone help me or give me references on how to set in displaying, editing and deleting records?
Here's what I've done so far.
import javax.microedition.midlet.MIDlet;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.TextField;
import javax.microedition.lcdui.DateField;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Alert;
import javax.microedition.pim.PIM;
import javax.microedition.pim.PIMItem;
import javax.microedition.pim.EventList;
import javax.microedition.pim.Event;
import javax.microedition.pim.PIMException;
import java.util.Date;
public class AddCalendarEvent extends MIDlet implements CommandListener {
private Display display;
private Form addEventForm;
private Command cmdAddEvent;
private Command cmdExit;
private TextField summaryField;
private DateField startDateField;
private DateField endDateField;
private TextField noteField;
private TextField locationField;
public AddCalendarEvent() {
if(checkPIMSupport() == false) {
exitMIDlet();
}
initializeComponents();
}
public void initializeComponents() {
display = Display.getDisplay(this);
addEventForm = new Form("Add event");
cmdAddEvent = new Command("Add event", Command.SCREEN, 0);
addEventForm.addCommand(cmdAddEvent);
cmdExit = new Command("Exit", Command.EXIT, 0);
addEventForm.addCommand(cmdExit);
addEventForm.setCommandListener(this);
try {
EventList eventList = (EventList)PIM.getInstance().openPIMList(
PIM.EVENT_LIST, PIM.READ_WRITE);
if(eventList.isSupportedField(Event.SUMMARY) == true) {
summaryField = new TextField("Summary", null, 20,
TextField.ANY);
addEventForm.append(summaryField);
} else {
eventList.close();
throw new Exception("Summary field is not supported");
}
if(eventList.isSupportedField(Event.START) == true) {
startDateField = new DateField("Start date",
DateField.DATE_TIME);
startDateField.setDate(new Date());
addEventForm.append(startDateField);
}
if(eventList.isSupportedField(Event.END) == true) {
endDateField = new DateField("End date", DateField.DATE_TIME);
endDateField.setDate(new Date());
addEventForm.append(endDateField);
}
if(eventList.isSupportedField(Event.NOTE) == true) {
noteField = new TextField("Note", null, 20, TextField.ANY);
addEventForm.append(noteField);
}
if(eventList.isSupportedField(Event.LOCATION) == true) {
locationField = new TextField("Location", null, 20,
TextField.ANY);
addEventForm.append(locationField);
}
eventList.close();
} catch(PIMException pimExc) {
}
catch(SecurityException secExc) {
}
catch(Exception exc) {
exitMIDlet();
}
}
private boolean checkPIMSupport() {
String propValue = System.getProperty("microedition.pim.version");
if(propValue != null) {
return true;
} else {
return false;
}
}
private void addEvent() {
try {
EventList eventList = (EventList)PIM.getInstance().openPIMList(
PIM.EVENT_LIST, PIM.READ_WRITE);
Event event = eventList.createEvent();
if(eventList.isSupportedField(Event.SUMMARY) == true) {
String summary = summaryField.getString();
event.addString(Event.SUMMARY, PIMItem.ATTR_NONE, summary);
} else {
eventList.close();
throw new Exception("Summary field for event is not supported");
}
if(eventList.isSupportedField(Event.START) == true) {
long startDate = startDateField.getDate().getTime();
event.addDate(Event.START, PIMItem.ATTR_NONE, startDate);
}
if(eventList.isSupportedField(Event.END) == true) {
long endDate = endDateField.getDate().getTime();
event.addDate(Event.END, PIMItem.ATTR_NONE, endDate);
}
if(eventList.isSupportedField(Event.NOTE) == true) {
String note = noteField.getString();
event.addString(Event.NOTE, PIMItem.ATTR_NONE, note);
}
if(eventList.isSupportedField(Event.LOCATION) == true) {
String location = locationField.getString();
event.addString(Event.LOCATION, PIMItem.ATTR_NONE, location);
}
event.commit();
eventList.close();
showAlert("Info", "Event was successfully added.");
} catch(PIMException pimExc) {
showAlert("PIMException", pimExc.getMessage());
}
catch(SecurityException secExc) {
showAlert("SecurityException", secExc.getMessage());
}
catch(Exception exc) {
showAlert("Exception", exc.getMessage());
}
}
private void showAlert(String title, String message) {
Alert alert = new Alert(title);
alert.setString(message);
alert.setTimeout(Alert.FOREVER);
display.setCurrent(alert);
}
public void startApp() {
display.setCurrent(addEventForm);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
private void exitMIDlet() {
notifyDestroyed();
}
public void commandAction(Command command, Displayable displayable) {
if(command == cmdAddEvent) {
addEvent();
}
if(command == cmdExit) {
exitMIDlet();
}
}
}
Study the specification and tutorials suggested in jsr75 tag wiki .
This one looks like the best match to your issues: Getting Started With the PIM APIs
...This article provides a code-intensive introductory tutorial to the PIM APIs; it:
Introduces JSR 75
Describes the javax.microedition.pim optional package
Provides details about the PIM APIs
Offers a taste of the effort involved in using them
Provides code that you can adapt to the needs of your own wireless applications
...
Above tutorial also lists some resources recommended for further study in section For more information.
i have the following code which is giving me error:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Vector;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.List;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
public class DeviceClientCOMM implements DiscoveryListener, CommandListener {
static final boolean DEBUG = false;
static final String DEBUG_address = "0013FDC157C8"; // N6630
protected UUID uuid = new UUID(0x1101); // serial port profile
protected int inquiryMode = DiscoveryAgent.GIAC; // no pairing is needed
protected int connectionOptions = ServiceRecord.NOAUTHENTICATE_NOENCRYPT;
protected int stopToken = 255;
private Command backCommand = new Command("Back", Command.BACK, 1);
protected Form infoArea = new Form("Bluetooth Client");
protected Vector deviceList = new Vector();
private CameraMIDlet mymidlet;
private byte[] imag;
public DeviceClientCOMM(CameraMIDlet m, byte[] imag) {
mymidlet = m;
this.imag = imag;
infoArea.setCommandListener(this);
infoArea.addCommand(backCommand);
try {
startApp();
} catch (MIDletStateChangeException ex) {
ex.printStackTrace();
}
}
protected void startApp() throws MIDletStateChangeException {
makeInformationAreaGUI();
if (DEBUG) // skip inquiry in debug mode
{
startServiceSearch(new RemoteDevice(DEBUG_address) {
});
} else {
try {
startDeviceInquiry();
} catch (Throwable t) {
log(t);
}
}
}
private void startDeviceInquiry() {
try {
log("Start inquiry method - this will take few seconds...");
DiscoveryAgent agent = getAgent();
agent.startInquiry(inquiryMode, this);
} catch (Exception e) {
log(e);
}
}
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
log("A device discovered (" + getDeviceStr(btDevice) + ")");
deviceList.addElement(btDevice);
}
public void inquiryCompleted(int discType) {
log("Inquiry compeleted. Please select device from combo box.");
makeDeviceSelectionGUI();
}
private void startServiceSearch(RemoteDevice device) {
try {
log("Start search for Serial Port Profile service from " + getDeviceStr(device));
UUID uuids[] = new UUID[]{uuid};
getAgent().searchServices(null, uuids, device, this);
} catch (Exception e) {
log(e);
}
}
public void servicesDiscovered(int transId, ServiceRecord[] records) {
log("Service discovered.");
for (int i = 0; i < records.length; i++) {
ServiceRecord rec = records[i];
String url = rec.getConnectionURL(connectionOptions, false);
handleConnection(url);
}
}
public void serviceSearchCompleted(int transID, int respCode) {
String msg = null;
switch (respCode) {
case SERVICE_SEARCH_COMPLETED:
msg = "the service search completed normally";
break;
case SERVICE_SEARCH_TERMINATED:
msg = "the service search request was cancelled by a call to DiscoveryAgent.cancelServiceSearch()";
break;
case SERVICE_SEARCH_ERROR:
msg = "an error occurred while processing the request";
break;
case SERVICE_SEARCH_NO_RECORDS:
msg = "no records were found during the service search";
break;
case SERVICE_SEARCH_DEVICE_NOT_REACHABLE:
msg = "the device specified in the search request could not be reached or the local device could not establish a connection to the remote device";
break;
}
log("Service search completed - " + msg);
}
private void handleConnection(final String url) {
Thread echo = new Thread() {
public void run() {
StreamConnection stream = null;
InputStream in = null;
OutputStream out = null;
try {
log("Connecting to server by url: " + url);
stream = (StreamConnection) Connector.open(url);
log("Bluetooth stream open.");
// InputStream in = stream.openInputStream();
out = stream.openOutputStream();
in = stream.openInputStream();
startReadThread(in);
// String stringImage = Base64.encode(imag);
log("Start echo loop.");
out.write(imag);
out.flush();
// out.flush();
// stream.close();
} catch (IOException e) {
log(e);
} finally {
log("Bluetooth stream closed.");
if (out != null) {
try {
out.close();
stream.close();
logSet("Image Transfer done\n----------------\n\nWaiting for results...");
} catch (IOException e) {
log(e);
}
}
}
}
};
echo.start();
}
private void startReadThread(final InputStream in) {
Thread reader = new Thread() {
public void run() {
byte[] s = new byte[512];
//boolean flag = true;
try {
while (true) {
int r = in.read(s);
if (r != -1) {
logSet(new String(s, 0, r));
} else {
break;
}
Thread.sleep(200);
}
} catch (Throwable e) {
log(e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
}
};
reader.start();
}
private void makeInformationAreaGUI() {
infoArea.deleteAll();
Display.getDisplay(mymidlet).setCurrent(infoArea);
}
private void makeDeviceSelectionGUI() {
final List devices = new List("Select a device", List.IMPLICIT);
for (int i = 0; i < deviceList.size(); i++) {
devices.append(
getDeviceStr((RemoteDevice) deviceList.elementAt(i)), null);
}
devices.setCommandListener(new
CommandListener( ) {
public void commandAction(Command arg0,
Displayable arg1)
{
makeInformationAreaGUI();
startServiceSearch((RemoteDevice) deviceList.elementAt(devices.getSelectedIndex()));
}
});
Display.getDisplay(mymidlet).setCurrent(devices);
}
synchronized private void log(String msg) {
infoArea.append(msg);
infoArea.append("\n\n");
}
synchronized private void logSet(String msg) {
infoArea.deleteAll();
infoArea.append(msg);
infoArea.append("\n\n");
}
private void log(Throwable e) {
log(e.getMessage());
}
private DiscoveryAgent getAgent() {
try {
return LocalDevice.getLocalDevice().getDiscoveryAgent();
} catch (BluetoothStateException e) {
throw new Error(e.getMessage());
}
}
private String getDeviceStr(RemoteDevice btDevice) {
return getFriendlyName(btDevice) + " - 0x" + btDevice.getBluetoothAddress();
}
private String getFriendlyName(RemoteDevice btDevice) {
try {
return btDevice.getFriendlyName(false);
} catch (IOException e) {
return "no name available";
}
}
public void commandAction(Command arg0, Displayable arg1) {
mymidlet.DisplayMainList();
}
}
the errors are
C:\Documents and Settings\admin\My Documents\NetBeansProjects\DeviceClientCOMM\src\DeviceClientCOMM.java:51: cannot find symbol
symbol : class CameraMIDlet
location: class DeviceClientCOMM
private CameraMIDlet mymidlet;
C:\Documents and Settings\admin\My Documents\NetBeansProjects\DeviceClientCOMM\src\DeviceClientCOMM.java:54: cannot find symbol
symbol : class CameraMIDlet
location: class DeviceClientCOMM
public DeviceClientCOMM(CameraMIDlet m, byte[] imag)
You don't have an import for CameraMIDlet, so the compiler doesn't know which class you mean.
Assuming you've got an appropriate classpath entry, you should just be able to add the right import and it should be fine.
Are you sure CameraMIDlet exists for your use though? I can see some sample code in JSR-135, but I'm not sure it's a full API to be used...