Handle event for html button codename one - codenameone

In form I embedded WebBrowser component with lots of html contents (Mainly Table, buttons ) for rich ui. Is it possible to handle event on clicking html button ?

Sure, look at the kitchen sink demo for a sample.
Generally just navigate to a URL on the event and implement your own BrowserNavigationCallback to handle navigation to that specific URL.
This is the code from the Kitchen Sink demo notice the setBrowserNavigationCallback block:
final WebBrowser wb = new WebBrowser();
if(wb.getInternal() instanceof BrowserComponent) {
Button btn = new Button("Add");
final TextArea content = new TextArea();
Container north = new Container(new BorderLayout());
north.addComponent(BorderLayout.CENTER, content);
north.addComponent(BorderLayout.EAST, btn);
cnt.addComponent(BorderLayout.NORTH, north);
content.setHint("Add to web document");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
((BrowserComponent)wb.getInternal()).execute("fnc('" + content.getText() + "');");
}
});
((BrowserComponent)wb.getInternal()).setBrowserNavigationCallback(new BrowserNavigationCallback() {
public boolean shouldNavigate(String url) {
if(url.startsWith("http://sayhello")) {
// warning!!! This is not on the EDT and this method MUST return immediately!
Display.getInstance().callSerially(new Runnable() {
public void run() {
((BrowserComponent)wb.getInternal()).execute("fnc('this was written by Java code!')");
}
});
return false;
}
return true;
}
});
}

Related

Codenameone - Calendar createDay() Navigation

I hand-coded my app using CN1 (based on CN1's standard form template). Mostly for using Calendar for appointment app (I have reason not to use Picker).
Here's my main Form class
public class celebriesta {
private Form current;
private Resources theme;
private Form home;
public void init(Object context) {
theme = UIManager.initFirstTheme("/theme");
// Enable Toolbar on all Forms by default
Toolbar.setGlobalToolbar(true);
// Pro only feature
Log.bindCrashProtection(true);
}
public void start() {
if (current != null) {
current.show();
return;
}
home = new Form("Home", BoxLayout.y());
mainCalendar Calendar = new mainCalendar();
home.addComponent(Calendar);
Calendar.setUIID("Calendar");
//Create Form1 and Form2 and set a Back Command to navigate back to the home Form
Form form1 = new Form("Form1");
setBackCommand(form1);
Form form2 = new Form("Form2");
setBackCommand(form2);
Form form3 = new Form("Form3");
setBackCommand(form3);
//Add navigation commands to the home Form
NavigationCommand cmd1 = new NavigationCommand("Form1");
cmd1.setNextForm(form1);
home.getToolbar().addCommandToSideMenu(cmd1);
NavigationCommand cmd2 = new NavigationCommand("Form2");
cmd2.setNextForm(form2);
home.getToolbar().addCommandToSideMenu(cmd2);
NavigationCommand cmd3 = new NavigationCommand("Form3");
cmd3.setNextForm(form3);
Calendar.createDay().pressed();
Calendar.createDay().released();
Calendar.createDay().setCommand(cmd3);
//Add Edit commands to the home Form context Menu
Image im = FontImage.createMaterial(FontImage.MATERIAL_MODE_EDIT, UIManager.getInstance().getComponentStyle("Command"));
Command edit = new Command("", im) {
#Override
public void actionPerformed(ActionEvent evt) {
System.out.println("Editing");
}
};
home.getToolbar().addCommandToRightBar(edit);
home.show();
}
protected void setBackCommand(Form f) {
Command back = new Command("") {
#Override
public void actionPerformed(ActionEvent evt) {
home.showBack();
}
};
Image img = FontImage.createMaterial(FontImage.MATERIAL_ARROW_BACK, UIManager.getInstance().getComponentStyle("TitleCommand"));
back.setIcon(img);
f.getToolbar().addCommandToLeftBar(back);
f.getToolbar().setTitleCentered(true);
f.setBackCommand(back);
}
public void stop() {
current = getCurrentForm();
}
public void destroy() {
}}
I've override Calendar class accordingly
public class mainCalendar extends Calendar { #Override
protected Button createDay(){ Button day = new Button();
Image im = FontImage.createMaterial(FontImage.MATERIAL_MODE_EDIT, UIManager.getInstance().getComponentStyle("Command"));
day.setIcon(im);
return day;
}
#Override
protected void updateButtonDayDate(Button dayButton, int currentMonth, int day) {
//Customize day values
dayButton.setText("" +day);
}}
The main Form manages to get to Form 1 & 2 (sidemenu). I know Form 3 does exist but not sure why it didn't managed to be 'reached' from createDay(). And I suspect it's something wrong somewhere around this code in main Form
Calendar.createDay().pressed();
Calendar.createDay().released();
Calendar.createDay().setCommand(cmd3);
Need advise and/or help.
Have a look at a sample code here that creates a custom calendar day component. You don't need the below code:
Calendar.createDay().pressed();
Calendar.createDay().released();
Calendar.createDay().setCommand(cmd3);
Calendar day pressing and releasing is handled through an actionListener which you can implement through overriding the bindDayListener() if you're using a custom day component or addDayActionListener() if you're using the default day button. An example will be:
Calendar.addDayActionListener(evt -> {
//show your next form here
});
Unless you need a high-level customization, I don't see a point subclassing the Calendar class.

Display html text in codenameone

I would like to display html formatted text that I have as a string.
Does the WebBroswer component support this ?
If yes, what method to use ?
Thanks,
Sanket
Code:
private void loadCourseDesc() {
Container courseDescContainer = new Container(new BoxLayout(BoxLayout.Y_AXIS));
NETextArea title = new NETextArea(AppState.current_Course.getTitle());
title.setUIID("biggreylabel");
courseDescContainer.addComponent(title);
Container c1 = new Container(new BoxLayout(BoxLayout.X_AXIS));
Label l = new Label("Fees:" + AppState.current_Course.getFees());
l.setUIID("mgreylabel");
c1.addComponent(l);
Label l1 = new Label("Completion Date:" + AppState.current_Course.getExpiryDate());
l1.setUIID("mgreylabelLM");
c1.addComponent(l1);
courseDescContainer.addComponent(c1);
WebBrowser wb = new WebBrowser(){
#Override
public void onLoad(String url) {
super.onLoad(url); //To change body of generated methods, choose Tools | Templates.
instance.forceRevalidate();
}
};
wb.setScrollableY(true);
System.out.println("::---" + AppState.current_Course.getDesc());
wb.setPage(AppState.current_Course.getDesc(), "http://localhost/");
courseDescContainer.addComponent(wb);
replace(courseDescContainer);
Code for replace:
private void replace(final Container c) {
Display.getInstance().callSerially(new Runnable() {
public void run() {
instance.replaceAndWait(currentCentre, c, null);
currentCentre = c;
instance.forceRevalidate();
}
});
}
It supports it by adding the component into the container, to set HTML instead of a URL just use setPage instead of setURL.

How do I get Codenameone to capture video?

I am using the following code to try to capture video with codenameone 2.0
tProperty.setHint("name the property that is a media");
final CheckBox cbVideo = new CheckBox("Video");
final Button bCapture = new Button("Capture Media");
final MediaPlayer mpPlayer = new MediaPlayer();
bCapture.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ect){
try {
if (cbVideo.isSelected()) {
String value = Capture.captureVideo();
mpPlayer.setDataSource(value);
mpPlayer.setName(tProperty.getText());
}else {
String value = Capture.captureAudio();
mpPlayer.setDataSource(value);
mpPlayer.setName(tProperty.getText());
}
}catch (Exception e){
}
}
});
cM.addComponent(tProperty);
cM.addComponent(cbVideo);
cM.addComponent(bCapture);
cM.addComponent(mpPlayer);
Command [] cmds = new Command[1];
cmds[0] = new Command("Done") {
public void actionPerformed(ActionEvent evt) {
//do Option1
}
};
Dialog.show(editType, cM, cmds);
When running in the simulator, clicking on the CaptureMedia button, it will present the file chooser interface. But then I am unable to choose any file at all whether audio or video because the choose file button is diabled.
How do I get to test the video capture in the simulator?
I think it's a layout problem, you are adding the MediaPlayer component before the video was created, so it's preferred size is 0.
Try to place the video in the border layout center so it's preferred size is ignored and the player will have enough space to display.
Try this:
final Form hi = new Form("Hi World");
hi.setLayout(new BorderLayout());
final Button bCapture = new Button("Capture Media");
bCapture.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ect) {
try {
final MediaPlayer mpPlayer = new MediaPlayer();
String value = Capture.captureVideo();
System.out.println("Captured Video " + value);
if (value != null) {
System.out.println("Playing Video");
InputStream is = FileSystemStorage.getInstance().openInputStream(value);
String strMime = "video/mp4";
System.out.println("Input Stream" + is.available());
mpPlayer.setName("bla");
mpPlayer.setDataSource(is, strMime, new Runnable() {
public void run() {
System.out.println("reset the clip for playback");
}
});
hi.addComponent(BorderLayout.CENTER, mpPlayer);
hi.revalidate();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
);
hi.addComponent(BorderLayout.NORTH, bCapture);
hi.show();
There is a regression in playing local videos in the Codename One simulator although it should work on the device. The next update of Codename One will fix it but for now you can workaround it by playing from a stream which should work just fine.
Just use the FileSystemStorage class to get an InputStream to the video and invoke the appropriate playback code. Note that this is less efficient than the play via URL API so when the regression is fixed you should probably return to the URL based API.

HTML and webbrowser

I tried to use html page in my code for that i found way from kichensink application, i am using same code and same page.html file applicatin working on simulator but not working on devices. Ondevices i got a blank screen. Below is my code. Please help me on this.
void ShowForm()
{
Form f = new Form("testweb");
Container cnt = new Container(new BorderLayout());
cnt = createDemo();
f.setLayout(new BorderLayout());
f.addComponent(BorderLayout.CENTER, cnt);
f.show();
}
public Container createDemo() {
Container cnt = new Container(new BorderLayout());
final WebBrowser wb = new WebBrowser();
if(wb.getInternal() instanceof BrowserComponent) {
Button btn = new Button("Add");
final TextArea content = new TextArea();
Container north = new Container(new BorderLayout());
north.addComponent(BorderLayout.CENTER, content);
north.addComponent(BorderLayout.EAST, btn);
cnt.addComponent(BorderLayout.NORTH, north);
content.setHint("Add to web document");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
((BrowserComponent)wb.getInternal()).execute("fnc('" + content.getText() + "');");
}
});
((BrowserComponent)wb.getInternal()).setBrowserNavigationCallback(new BrowserNavigationCallback() {
public boolean shouldNavigate(String url) {
if(url.startsWith("http://sayhello")) {
// warning!!! This is not on the EDT and this method MUST return immediately!
Display.getInstance().callSerially(new Runnable() {
public void run() {
((BrowserComponent)wb.getInternal()).execute("fnc('this was written by Java code!');");
}
});
return false;
}
return true;
}
});
}
cnt.addComponent(BorderLayout.CENTER, wb);
wb.setURL("jar:///page.html");
return cnt;
}
Hi,I did few changes setlayout for container and add to another cotainer with scrollable true for container and scrollable false for form but now it's giving me error on devices and error is: "web page not available" page.html not found. Whereas page.html is already placed in src with .res file and application on simulator working fine.
Regards,
Jeny
You can't make a border layout scrollable, including nested scrollables and scrolling native+Codename One widgets in sync is probably not a good idea.
Which device are you having a problem on? There was an issue with browser component on Android for some use cases, its fixed now.

Custom Item Template Wizard button click doesn't fire?

I am following this exactly:
http://msdn.microsoft.com/en-us/library/ms185301.aspx
but can't get it to work. The form appears when I try and add my new item, but when I input text and click the button, nothing happens.
For posterity's sake here is my code:
The non-empty methods in the Wizard class which extends IWizard
public void RunStarted(object automationObject,
Dictionary<string, string> replacementsDictionary,
WizardRunKind runKind, object[] customParams)
{
try
{
// Display a form to the user. The form collects
// input for the custom message.
inputForm = new UserInputForm();
inputForm.ShowDialog();
customMessage = inputForm.get_CustomMessage();
// Add custom parameters.
replacementsDictionary.Add("$custommessage$",
customMessage);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
// This method is only called for item templates,
// not for project templates.
public bool ShouldAddProjectItem(string filePath)
{
return true;
}
The user input form code:
public partial class UserInputForm : Form
{
private string customMessage;
public UserInputForm()
{
InitializeComponent();
}
public string get_CustomMessage()
{
return customMessage;
}
private void button1_Click(object sender, EventArgs e)
{
customMessage = textBox1.Text;
this.Dispose();
}
}
And the button is indeed named button 1:
this.button1.Location = new System.Drawing.Point(200, 180);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(100, 40);
this.button1.TabIndex = 0;
this.button1.Text = "Click Me";
this.button1.UseVisualStyleBackColor = true;
So I don't have much experience with Windows Forms (do web apps), but I am following the directions on MSDN and it's pretty clear cut. Any suggestions? Can anyone else get this to work?
Okay I figured it out. I had to add the event handler in the form's constructor manually:
public UserInputForm()
{
InitializeComponent();
button1.Click += button1_Click;
}
Why this isn't in the documentation on MSDN boggles my mind.
If you use the WinForms designer mode to drag your button from the Toolbox, and then double-clicked the button in the designer view, it would have added the event handler and stubbed that Click method for you. Just FYI.

Resources