Commands not all working in J2ME app - java-me

Part of my j2me project involves use of the filesystem, so I'm starting with a simple file browser. The current issue I'm facing is the implementation of the command processor. To wit:
<CODE>
public void commandAction(Command c, Displayable d) {
if (c.getLabel().equals("Exit")) {
notifyDestroyed();
}
// File retrieval code (or call to it) to go here later.
if (c.getLabel().equals("Enter")) {
current_name = getRidOfTrailingSlash(current_name)
+ "/" + mainscreen.getString(mainscreen.getSelectedIndex());
// + "/" + "MemoryCard/";
System.exit(0);
if (! setName(current_name)) {
dirlist = rootlist;
current_name = "/";
}
showDirs();
}
if (c.getLabel().equals("Up Dir")) {
if (current_name.equals("/")) return;
current_name = getRidOfTrailingSlash(current_name);
if (setName(current_name)) current_name = current_fc.getPath();
else current_name = "/";
if (current_name.equals("/")) dirlist = rootlist;
else {
try {
dirlist = current_fc.list();
} catch (IOException ioe) {}
}
showDirs();
}
if (c.getLabel().equals("Create")) {
System.exit(1);
// Create code to be added later
}
if (c.getLabel().equals("Delete")) {
System.exit(2);
// Delete code to be added later
}
} // End of command actions
</CODE>
I am working on debugging the code for "Enter", and plan to write the code for "Create" and "Delete" at a later date. So for now I have them exit to an expected Security exception.
The code that sets up the commands is as follows:
<CODE>
public String getRidOfTrailingSlash(String s) {
if (s.equals("/")) return "";
int len = s.length();
String end = s.substring(len - 1);
if (end.equals("/")) s = s.substring(len - 2);
return s;
}
public List makeFileList(Enumeration names, String[] cmds) {
int i,s,cmdtype;
String c;
List l = new List(current_name, List.EXCLUSIVE);
while (names.hasMoreElements()) {
c = (String) names.nextElement();
l.append(c, null);
}
s = cmds.length;
for (i=0; i<s; i++) {
c = cmds[i];
if (c.equalsIgnoreCase("Exit")) {
cmdtype = Command.EXIT;
} else
if (c.equalsIgnoreCase("Up Dir")) {
cmdtype = Command.BACK;
} else {
cmdtype = Command.BACK;
}
// I've also tried using ITEM, OK, and one or two other
// command types for the default. Same effect.
l.addCommand(new Command(c, cmdtype, 1));
}
return l;
}
private void showDirs() {
String commands[] = { "Enter", "Up Dir", "Create", "Delete", "Exit" };
mainscreen = makeFileList(dirlist, commands);
mainscreen.setCommandListener(this);
Display.getDisplay(this).setCurrent(mainscreen);
}
</CODE>
My current issue is that the commands are not all being executed. "Exit" and "Up Dir" are working properly. However, the other three commands don't function at all in the Emulator. They show up in the menus, but selecting them does absolutely nothing when they should be routing the program flow through the System.exit() calls. If I select any of these any number of times, "Up Dir" and "Exit" still work afterward. Furthermore, the select function in the file list doesn't do anything either.
On the phone that I'm writing this for (An LG Rumor Reflex), the select function (checking and unchecking items in the list) works, as do the commands "Create", "Delete", "Up Dir", and "Exit". However, the "Enter" command doesn't even appear in the menu!
What am I doing wrong, and why the different behavior on the phone versus the Emulator?

Related

Cisco JTAPI phone register/unregister status

I am using the below code to check the phone status(if phone is up or down). When phone is down sends an alarm. However this doesn't show when 8800 series phones are down. Is there any other method to check the Phone register/unregister status?
#Override public void terminalChangedEvent(TermEv[] eventList) {
if ( eventList != null ) {
for (TermEv eventList1 : eventList) {
if (eventList1 instanceof CiscoTermInServiceEv){
if(terminalInService.test()==true){
LogSQL.removeLog(terminal.getName());
}
System.out.println(terminal.getName());
terminalInService.set();
return;
} else if (eventList1 instanceof CiscoTermOutOfServiceEv &&
terminalInService.test()==true) {
offline();
}
}
}
}
Second Question, I was not able to find the methods or documentation about "com.cisco.cti.util.Condition" class. What does Condition.set() and Condition.test() methods do?
Looks like you have the right general idea - JTAPI should work fine for 88xx models, assuming you have the correct device->user association, and user permissions (Standard CTI Enabled, and Standard CTI Allow Control of Phones supporting Connected Xfer and conf needed for 88xx).
Here is my version working on CUCM 11.5:
package com.mycompany.app;
import com.cisco.jtapi.extensions.*;
import java.util.*;
import javax.telephony.*;
import javax.telephony.events.*;
import javax.telephony.callcontrol.*;
import javax.telephony.callcontrol.events.*;
import com.cisco.cti.util.Condition;
public class DataTerm implements ProviderObserver, TerminalObserver {
public static final int OUT_OF_SERVICE = 0;
public static final int IN_SERVICE = 1;
private Address destAddress;
private CiscoTerminal observedTerminal;
private boolean addressInService;
private boolean terminalInService;
protected int state = OUT_OF_SERVICE;
Condition conditionInService = new Condition();
Provider provider;
public DataTerm(String[] args) {
try {
System.out.println("Initializing Jtapi");
String providerName = "ds-ucm115-1.cisco.com";
String login = "dstaudt";
String passwd = "password";
String dest = "2999";
JtapiPeer peer = JtapiPeerFactory.getJtapiPeer(null);
String providerString = providerName + ";login=" + login + ";passwd=" + passwd;
System.out.println("Opening " + providerString + "...\n");
provider = peer.getProvider(providerString);
provider.addObserver(this);
conditionInService.waitTrue();
this.destAddress = provider.getAddress(dest);
this.observedTerminal = (CiscoTerminal) destAddress.getTerminals()[0];
try {
if (destAddress != null) {
System.out.println("Adding Terminal Observer to Terminal" + observedTerminal.getName());
observedTerminal.addObserver(this);
}
} catch (Exception e) {
}
} catch (Exception e) {
System.out.println("Caught exception " + e);
}
}
public void terminalChangedEvent(TermEv[] events) {
for (int i = 0; i < events.length; i++) {
Terminal terminal = events[i].getTerminal();
switch (events[i].getID()) {
case CiscoTermInServiceEv.ID:
System.out.println("Received " + events[i] + "for " + terminal.getName());
terminalInService = true;
break;
case CiscoTermOutOfServiceEv.ID:
System.out.println("Received " + events[i] + "for " + terminal.getName());
terminalInService = false;
if (state != OUT_OF_SERVICE) { // you only want to notify when you had notified earlier that you are IN_SERVICE
state = OUT_OF_SERVICE;
}
break;
}
}
}
public void providerChangedEvent(ProvEv[] eventList) {
if (eventList != null) {
for (int i = 0; i < eventList.length; i++) {
if (eventList[i] instanceof ProvInServiceEv) {
conditionInService.set();
}
}
}
}
}
The "com.cisco.cti.util.Condition" seems to be based on this pattern:
public interface Condition
Condition factors out the Object monitor methods (wait, notify and notifyAll) into distinct objects to give the effect of having multiple wait-sets per object, by combining them with the use of arbitrary Lock implementations. Where a Lock replaces the use of synchronized methods and statements, a Condition replaces the use of the Object monitor methods.
Conditions (also known as condition queues or condition variables) provide a means for one thread to suspend execution (to "wait") until notified by another thread that some state condition may now be true. Because access to this shared state information occurs in different threads, it must be protected, so a lock of some form is associated with the condition. The key property that waiting for a condition provides is that it atomically releases the associated lock and suspends the current thread, just like Object.wait.
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html

Get Visible Text from RichTextBlock

In a UWP app, I am using a RichTextBlock that gets populated with some content. It has word wrapping enabled and has a max lines set so that regardless of the length of its content, it will only show a certain number of lines of rich text.
I'd like to know if there is a way to figure out what is the visible text?
So if I have:
<RichTextBlock TextWrapping="Wrap" MaxLines="2">
<RichTextBlock.Blocks>
<Paragraph>
<Paragraph.Inlines>
A bunch of runs go in here with text that are several lines
</Paragraph.Inlines>
</Paragraph>
</RichTextBlock.Blocks>
</RichTextBlock>
I'd like to know how much of the text is actually visible.
I'm trying to detect cases where the text is longer than a set number of lines and append a "... Read More" at the end of the last line (replacing the last 13 chars with "... Read More")
So I wrote some code to get the behavior that I want, but unfortunately this is rather slow and inefficient. So if you're using it in an app that is primarily to show a lot of text that needs to be truncated (like a ListView with a lot of text items) then this would slow down your app perf. I still would like to know if there is a better way to do this.
Here's my code (which only handles Run and Hyperlink inlines so you'll have to modify to handle other types that you need):
private static void TrimText_Slow(RichTextBlock rtb)
{
var paragraph = rtb?.Blocks?.FirstOrDefault() as Paragraph;
if (paragraph == null) { return; }
// Ensure RichTextBlock has passed a measure step so that its HasOverflowContent is updated.
rtb.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
if (rtb.HasOverflowContent == false) { return; }
// Start from end and remove all inlines that are not visible
Inline lastInline = null;
var idx = paragraph.Inlines.Count - 1;
while (idx >= 0 && rtb.HasOverflowContent)
{
lastInline = paragraph.Inlines[idx];
paragraph.Inlines.Remove(lastInline);
idx--;
// Ensure RichTextBlock has passed a measure step now with an inline removed, so that its HasOverflowContent is updated.
rtb.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
}
// The last inline could be partially visible. The easiest thing to do here is to always
// add back the last inline and then remove characters from it until everything is in view.
if (lastInline != null)
{
paragraph.Inlines.Add(lastInline);
}
// Make room to insert "... Read More"
DeleteCharactersFromEnd(paragraph.Inlines, 13);
// Insert "... Continue Reading"
paragraph.Inlines.Add(new Run { Text = "... " });
paragraph.Inlines.Add(new Run { Text = "Read More", Foreground = new SolidColorBrush(Colors.Blue) });
// Ensure RichTextBlock has passed a measure step now with the new inlines added, so that its HasOverflowContent is updated.
rtb.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
// Keep deleting chars until "... Continue Reading" comes into view
idx = paragraph.Inlines.Count - 3; // skip the last 2 inlines since they are "..." and "Read More"
while (idx >= 0 && rtb.HasOverflowContent)
{
Run run;
if (paragraph.Inlines[idx] is Hyperlink)
{
run = ((Hyperlink)paragraph.Inlines[idx]).Inlines.FirstOrDefault() as Run;
}
else
{
run = paragraph.Inlines[idx] as Run;
}
if (string.IsNullOrEmpty(run?.Text))
{
paragraph.Inlines.Remove(run);
idx--;
}
else
{
run.Text = run.Text.Substring(0, run.Text.Length - 1);
}
// Ensure RichTextBlock has passed a measure step now with the new inline content updated, so that its HasOverflowContent is updated.
rtb.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
}
}
private static void DeleteCharactersFromEnd(InlineCollection inlines, int numCharsToDelete)
{
if (inlines == null || inlines.Count < 1 || numCharsToDelete < 1) { return; }
var idx = inlines.Count - 1;
while (numCharsToDelete > 0)
{
Run run;
if (inlines[idx] is Hyperlink)
{
run = ((Hyperlink)inlines[idx]).Inlines.FirstOrDefault() as Run;
}
else
{
run = inlines[idx] as Run;
}
if (run == null)
{
inlines.Remove(inlines[idx]);
idx--;
}
else
{
var textLength = run.Text.Length;
if (textLength <= numCharsToDelete)
{
numCharsToDelete -= textLength;
inlines.Remove(inlines[idx]);
idx--;
}
else
{
run.Text = run.Text.Substring(0, textLength - numCharsToDelete);
numCharsToDelete = 0;
}
}
}
}

using like operator in if operator in C#

I have a textbox for search (that is, textBox1)
A user, for example, enters "aba" in textBox1.
"abandon" puts in datagridiew1.
The user clicks on datagriview1:
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
richTextBox_MWE.Text = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
if ("richTextBox_MWE.Text like '%" + textBox1.Text + "%'")
{
label5.BackColor = Color.Green;
}
}
I want if "abandon" is such as "aba" in textBox1, label5.BackColor becomes Green.
Simple way is use the textBox1(where actually filter content going to change) change event
if(!String.IsNullOrEmpty(richTextBox_MWE.Text) && richTextBox_MWE.Text.Trim().Contains(textBox1.Text.Trim()))
{
label5.BackColor = Color.Green;
}
You want to use some kind of mix of C# and sql :) You can use the String.Contains method to achieve what you want.
if(richTextBox_MWE.Text != null
&& richTextBox_MWE.Text.Contains(textBox1.Text.Trim())
{
...
}
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
richTextBox_MWE.Text = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
if (!String.IsNullOrEmpty(richTextBox_MWE.Text) && !String.IsNullOrEmpty(textBox1.Text) && richTextBox_MWE.Text.Contains(textBox1.Text.Trim()))
{
label5.BackColor = Color.Green;
}
}
Here the contains will accept the value to be searched.
See snippet from my code. The txtProductCode is a text box that user is filling the product_code for searching in the list view.
string tmpProductCode = txtProductCode.Text.Trim();
string tmpProductCodePattern = "^" + Regex.Escape(tmpProductCode).Replace("%", ".*") + "$";
In my loop of product_code(s) the prodCode will contain the product_code value for each loop.
productCodeClause = false;
if (tmpProductCode.Equals(""))
{
productCodeClause = true;
}
else
{
if (Regex.IsMatch(prodCode, tmpProductCodePattern))
{
productCodeClause = true;
}
}
I hope this will be helpful.

File connection+j2me

I want to make the application where I can get all the images no matter whether it is in phone or in external memory. I want to import all that images in my application. How can it be possible? I came to know that it is possible through file connection. But not getting exact idea.
Get all the file system roots using FileSystemRegistry.listRoots()
Open connection to each root in turn using FileConnection fconn = (FileConnection)Connector.open(root)
List the folder using fconn.list().
For each entry in the list, if it ends with an image extension (file.getName().endsWith(".png") etc), then it's an image.
If the entry is a folder (file.isDirectory() returns true) then use fconn.setFileConnection(folder) to traverse into that directory/
Do the same recursively for all folders in all roots.
Here is a code snippet I once used for my application. It more or less does the same in funkybros steps.
protected void showFiles() {
if (path == null) {
Enumeration e = FileSystemRegistry.listRoots();
path = DATAHEAD; //DATAHEAD = file:///
setTitle(path);
while (e.hasMoreElements()) {
String root = (String) e.nextElement();
append(root, null);
}
myForm.getDisplay().setCurrent(this);
} else {
//this if-else just sets the title of the Listing Form
if (selectedItem != null) {
setTitle(path + selectedItem);
}
else {
setTitle(path);
}
try {
// works when users opens a directory, creates a connection to that directory
if (selectedItem != null) {
fileConncetion = (FileConnection) Connector.open(path + selectedItem, Connector.READ);
} else // works when presses 'Back' to go one level above/up
{
fileConncetion = (FileConnection) Connector.open(path, Connector.READ);
}
// Check if the selected item is a directory
if (fileConncetion.isDirectory()) {
if (selectedItem != null) {
path = path + selectedItem;
selectedItem = null;
}
//gathers the directory elements
Enumeration files = fileConncetion.list();
while (files.hasMoreElements()) {
String file = (String) files.nextElement();
append(file, null);
}
//
myForm.getDisplay().setCurrent(this);
try {
if (fileConncetion != null) {
fileConncetion.close();
fileConncetion = null;
}
} catch (IOException ex) {
ex.printStackTrace();
}
}//if (fileConncetion.isDirectory())
else {
System.out.println(path);
//if it gets a file then calls the publishToServer() method
myForm.publishToServer();
}

C# powershell output reader iterator getting modified when pipeline closed and disposed

I'm calling a powershell script from C#. The script is pretty small and is "gps;$host.SetShouldExit(9)", which list process, and then send back an exit code to be captured by the PSHost object.
The problem I have is when the pipeline has been stopped and disposed, the output reader PSHost collection still seems to be written to, and is filling up. So when I try and copy it to my own output object, it craps out with a OutOfMemoryException when I try to iterate over it. Sometimes it will except with a Collection was modified message. Here is the code.
private void ProcessAndExecuteBlock(ScriptBlock Block)
{
Collection<PSObject> PSCollection = new Collection<PSObject>();
Collection<Object> PSErrorCollection = new Collection<Object>();
Boolean Error = false;
int ExitCode=0;
//Send for exection.
ExecuteScript(Block.Script);
// Process the waithandles.
while (PExecutor.PLine.PipelineStateInfo.State == PipelineState.Running)
{
// Wait for either error or data waithandle.
switch (WaitHandle.WaitAny(PExecutor.Hand))
{
// Data
case 0:
Collection<PSObject> data = PExecutor.PLine.Output.NonBlockingRead();
if (data.Count > 0)
{
for (int cnt = 0; cnt <= (data.Count-1); cnt++)
{
PSCollection.Add(data[cnt]);
}
}
// Check to see if the pipeline has been closed.
if (PExecutor.PLine.Output.EndOfPipeline)
{
// Bring back the exit code.
ExitCode = RHost.ExitCode;
}
break;
case 1:
Collection<object> Errordata = PExecutor.PLine.Error.NonBlockingRead();
if (Errordata.Count > 0)
{
Error = true;
for (int count = 0; count <= (Errordata.Count - 1); count++)
{
PSErrorCollection.Add(Errordata[count]);
}
}
break;
}
}
PExecutor.Stop();
// Create the Execution Return block
ExecutionResults ER = new ExecutionResults(Block.RuleGuid,Block.SubRuleGuid, Block.MessageIdentfier);
ER.ExitCode = ExitCode;
// Add in the data results.
lock (ReadSync)
{
if (PSCollection.Count > 0)
{
ER.DataAdd(PSCollection);
}
}
// Add in the error data if any.
if (Error)
{
if (PSErrorCollection.Count > 0)
{
ER.ErrorAdd(PSErrorCollection);
}
else
{
ER.InError = true;
}
}
// We have finished, so enque the block back.
EnQueueOutput(ER);
}
and this is the PipelineExecutor class which setups the pipeline for execution.
public class PipelineExecutor
{
private Pipeline pipeline;
private WaitHandle[] Handles;
public Pipeline PLine
{
get { return pipeline; }
}
public WaitHandle[] Hand
{
get { return Handles; }
}
public PipelineExecutor(Runspace runSpace, string command)
{
pipeline = runSpace.CreatePipeline(command);
Handles = new WaitHandle[2];
Handles[0] = pipeline.Output.WaitHandle;
Handles[1] = pipeline.Error.WaitHandle;
}
public void Start()
{
if (pipeline.PipelineStateInfo.State == PipelineState.NotStarted)
{
pipeline.Input.Close();
pipeline.InvokeAsync();
}
}
public void Stop()
{
pipeline.StopAsync();
}
}
An this is the DataAdd method, where the exception arises.
public void DataAdd(Collection<PSObject> Data)
{
foreach (PSObject Ps in Data)
{
Data.Add(Ps);
}
}
I put a for loop around the Data.Add, and the Collection filled up with 600k+ so feels like the gps command is still running, but why. Any ideas.
Thanks in advance.
Found the problem. Named the resultant collection and the iterator the same, so as it was iterating, it was adding to the collection, and back into the iterator, and so forth. Doh!.

Resources