
Saturday April 26, 2008
YouTube Viewer add-on project
In this blog entry I talked about the YouTube Viewer add-on for Firefox. In the last blog I talked about how to use a freeform Web NetBeans 6.1 Project to build the iPhone mode add-on for Firefox. Download a similar freeform Web NetBeans 6.1 Project for YouTube Viewer.
Posted by sandipchitale
( Apr 26 2008, 04:49:09 PM PDT ) Permalink
Using NetBeans 6.1 freeform project to build iPhone mode add-on for Firefox project.
In the last entry I talked about an iPhone mode add-on for Firefox. I used a free form Web Project of NetBeans 6.1 IDE to build the iPhone mode add-on. The NetBeans 6.1 IDE has a great JavaScript editor. That was a big plus. Here is a visual tour of the Web Project setup. The Build Script <?xml version="1.0" encoding="UTF-8"?> <project name="iPhoneEmulator" default="all" basedir="."> <description>iPhone Emulator for Firefox.</description> <property name="build.dir" value="build"/> <!-- build iphone --> <target name="-create-iphone-jar"> <echo message="Build iphone.jar"/> <mkdir dir="${build.dir}"/> <zip destfile="${build.dir}/iphone.jar"> <zipfileset dir="." includes="content/**" /> <zipfileset dir="." includes="locale/**" /> <zipfileset dir="." includes="skin/**" /> </zip> </target> <target name="-gen-manifest"> <echo message="Configuring chrome-manifest"/> <mkdir dir="${build.dir}"/> <copy file="chrome.manifest" tofile="${build.dir}/chrome.manifest" overwrite="true"/> <replaceregexp file="${build.dir}/chrome.manifest" match="^(content\s+\S*\s+)(\S*/)$" replace="\1jar:chrome/iphone.jar!/\2" flags="g" byline="true"/> <replaceregexp file="${build.dir}/chrome.manifest" match="^(skin|locale)(\s+\S*\s+\S*\s+)(.*/)$" replace="\1\2jar:chrome/iphone.jar!/\3" flags="g" byline="true"/> </target> <target name="-create-iphone-xpi" depends="-create-iphone-jar,-gen-manifest"> <echo message="Build iphone.xpi"/> <mkdir dir="${build.dir}"/> <zip destfile="${build.dir}/iphone.xpi"> <zipfileset dir="${build.dir}" includes="iphone.jar" prefix="chrome" /> <zipfileset dir="${build.dir}" includes="chrome.manifest" /> <zipfileset dir="." includes="install.rdf" /> </zip> </target> <target name="all" depends="-create-iphone-xpi"/>
<target name="run" depends="clean,all"> <exec executable="firefox" osfamily="unix"> <arg file="${build.dir}/iphone.xpi"/> </exec> <exec executable="/usr/bin/open" osfamily="mac"> <arg value="-b"/> <arg value="org.mozilla.firefox"/> <arg file="${build.dir}/iphone.xpi"/> </exec> <exec executable="C:/Program Files/Mozilla Firefox/firefox.exe" osfamily="windows"> <arg file="${build.dir}/iphone.xpi"/> </exec> </target>
<target name="-clean-iphone"> <echo message="Clean iphone"/> <delete file="${build.dir}/iphone.jar" failonerror="false"/> <delete file="${build.dir}/chrome.manifest" failonerror="false"/> <delete file="${build.dir}/iphone.xpi" failonerror="false"/> </target> <target name="clean" depends="-clean-iphone"/> </project>
Here is the rest: 

Projects and Files window showing the layout:  
The NetBeans IDE is slowly starting to take shape as a premium AJAX, Web 2.0 and Mobile development IDE.
Posted by sandipchitale
( Apr 26 2008, 12:27:54 PM PDT ) Permalink

Sunday April 20, 2008
Open Location in iPhone Mode in Firefox
I have been hacking Firefox. Here is a simple iPhone mode add-on. This is very basic mode. You can type an address in the address field and hit ENTER. You can use the Reload button to reload the page. You can use Go Back and Go Forward buttons to navigate the history. You can use Add Bookmark button to add a bookmark to the current page. You can use the Show Bookmarks button to show the Bookmarks window. Just lkie the iPhone - the address bar is hidden when the document loads. You can reshow the address bar by clicking on the battery indicator bar. Any URL can be invoked in the iPhone mode from command line by using the -iphone command line argument.
> firefox -iphone URL
Use the File:OpenLocation in iPhone Mode... menu item to launch the iPhone mode. 
 
Talk about recursive :)
Download the add-on. Download the NetBeans 6.1 project. DISCLAIMER: This add-on is experimental. So no guarantees. Use the add-on at your own risk.
Posted by sandipchitale
( Apr 20 2008, 11:51:52 AM PDT ) Permalink

Friday April 18, 2008
Nested JavaScript functions and Non-static Inner Classes in Java
I am a Java programmer and understand the Java language concepts such as inner classes and scoping rules well. I have been learning JavaScript and trying to understand the scoping rules in JavaScript. Here are some of my observations about the similarities and differences between some aspects of nested JavaScript functions and Non-static inner classes.
| JavaScript | Java | var global = 0; function outerFunction() { var outerLocal = 1; function innerFunction() { var innerLocal = 2; // Can access outerLocal here // Can access global here }
return innerFunction; }
outerFunction.staticVar = 10; // elsewhere function callingFunction() { // Get a reference to innerFunction() var refToOuterDotInner = outerFunction(); refToOuterDotInner(); }
| public class Outer() { public static int staticField = 10; private int outerLocal = 1; public class Inner() { private int innerLocal = 2;
private void innerMethod() {
int methodLocal = 4; // Can access innerLocal here // Can access outerLocal here } }
public Inner getInner() { return new Inner(); } }
// elsewhere public void callingMethod() { Outer outer = new Outer(); Inner innerInstance = outer.getInner(); // Invoke method of inner class inner.innerMethod(); }
| innerFunction() is analogous to ---------> The scope of innerFunction() maps to two concepts in Java world - the scopes of innerMethod() and the instance of Inner class. The execution call stack of innerFunction() maps to the innerMethod() though.
| innerMethod() and instance of Inner class I think this is the source of confusion for Java programmer. At least it was to me.
| Three scopes when the innerFunction is executing: - Global
- scope of outerFunction
- scope of innerFunction - maps to last two scopes on Java side
| Three scopes when innerMethod() is executing. - No equivalent in Java
- Outer instance scope
- Inner instance scope
- innerMethod() local scope
| outerLocal in outerFunction is analogous to ---------> outerLocal is private to outerLocal but can be accessed from innerFunction() .
| outerLocal field of an instance of Outer class. outerLocal is private to the instance of Outer class but can be accessed from innertMethod() .
| | In terms of scope level innerLocal is analogous to ---------> | methodLocal and innerLocal
| no analogue
| the Outer class instance can be accessed using Outer.this
| call stack involves: innerFunction() callingFunction()
| call stack: innerMethod() callingMethod()
| outerFunciton.staticVar is analogous to ---------> Note the absence of () after outerFunction.
| static access to Outer.staticField
|
The scoping and access level rules of the inner functions allow for closures (a powerful concept) in JavaScript.
Do you have any insights to share?
Posted by sandipchitale
( Apr 18 2008, 07:25:38 AM PDT ) Permalink

Sunday April 13, 2008
TIP: Making JOptionPane dialog resizable
It is a well known issue that the dialogs shown by the javax.swing.JOptionPane are not resizable. In the last blog entry there was a tip in the code about just how to make the dialogs shown by javax.swing.JOptionPane resizable. Here is the relevant snippet of code:
// TIP: Make the JOptionPane resizable using the HierarchyListener editorPane.addHierarchyListener(new HierarchyListener() { public void hierarchyChanged(HierarchyEvent e) { Window window = SwingUtilities.getWindowAncestor(editorPane); if (window instanceof Dialog) { Dialog dialog = (Dialog)window; if (!dialog.isResizable()) { dialog.setResizable(true); } } } });
The tip works if you are using any java.awt.Component subclass as the message in javax.swing.JOptionPane. The tip works by listening to the hierarchy event on the message component, finding the java.awt.Dialog component and setting it's resizable property to true.
Posted by sandipchitale
( Apr 13 2008, 09:30:12 AM PDT ) Permalink

Saturday April 12, 2008
TIP: Displaying rich messages using JOptionPane and JEditorPane
In this and this blog entry I discussed technics to show images and multiline text in tooltips. The same technics can be applied to show rich messages using JEditorPane. Here is an example: import java.awt.Cursor; import java.awt.Desktop; import java.awt.Dialog; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Window; import java.awt.event.HierarchyEvent; import java.awt.event.HierarchyListener; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JEditorPane; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.SwingUtilities; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener;
public class NetBeansDay2008 { public static void main(String[] args) { // Turn anti-aliasing on System.setProperty("awt.useSystemAAFontSettings", "on"); final JEditorPane editorPane = new JEditorPane();
// Enable use of custom set fonts editorPane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE); editorPane.setFont(new Font("Arial", Font.BOLD, 13));
editorPane.setPreferredSize(new Dimension(520,180)); editorPane.setEditable(false); editorPane.setContentType("text/html"); editorPane.setText( "<html>" + "<body>" + "<table border='0px' cxellpadding='10px' height='100%'>" + "<tr>" + "<td valign='center'>" + "<img src='" + "http://www.netbeans.org/images/javaone/2008/nbday08_logo.gif" // Alternatively an image stored next to the NetBeansDay2008 // class can be used like this. //+ NetBeansDay2008.class.getResource("nbday08_logo.gif").toExternalForm() + "'>" + "</td>" + "<td>" + "<a href='http://www.netbeans.org/community/articles/javaone/2008/nb-day.html'><b>NetBeans Day</b></a><br>" + "San Francisco May 5th, 2008<br>" + "<br>" + "NetBeans - The only IDE you need!<br>" + "</td>" + "</tr>" + "</table>" + "</body>" + "</html>" );
// TIP: Make the JOptionPane resizable using the HierarchyListener editorPane.addHierarchyListener(new HierarchyListener() { public void hierarchyChanged(HierarchyEvent e) { Window window = SwingUtilities.getWindowAncestor(editorPane); if (window instanceof Dialog) { Dialog dialog = (Dialog)window; if (!dialog.isResizable()) { dialog.setResizable(true); } } } });
// TIP: Add Hyperlink listener to process hyperlinks editorPane.addHyperlinkListener(new HyperlinkListener() { public void hyperlinkUpdate(final HyperlinkEvent e) { if (e.getEventType() == HyperlinkEvent.EventType.ENTERED) { EventQueue.invokeLater(new Runnable() { public void run() { // TIP: Show hand cursor SwingUtilities.getWindowAncestor(editorPane).setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); // TIP: Show URL as the tooltip editorPane.setToolTipText(e.getURL().toExternalForm()); } }); } else if (e.getEventType() == HyperlinkEvent.EventType.EXITED) { EventQueue.invokeLater(new Runnable() { public void run() { // Show default cursor SwingUtilities.getWindowAncestor(editorPane).setCursor(Cursor.getDefaultCursor());
// Reset tooltip editorPane.setToolTipText(null); } }); } else if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { // TIP: Starting with JDK6 you can show the URL in desktop browser if (Desktop.isDesktopSupported()) { try { Desktop.getDesktop().browse(e.getURL().toURI()); } catch (Exception ex) { Logger.getLogger(NetBeansDay2008.class.getName()).log(Level.SEVERE, ex.getMessage(), ex); } } //System.out.println("Go to URL: " + e.getURL()); } } }); JOptionPane.showMessageDialog(null, new JScrollPane(editorPane), "NetBeans Day 2008", JOptionPane.PLAIN_MESSAGE); } }
Based on a tip from a reader I have added the code to turn on anti-aliasing and use of custom set fonts in JEditorPane. This shows the following visually pleasing dialog: 
See you there!
Posted by sandipchitale
( Apr 12 2008, 08:49:54 PM PDT ) Permalink

Wednesday April 02, 2008
Mac OS Leopard: /usr/bin/open -b org.mozilla.firefox 'file:///tmp/test.html/?a=b&c=d' does not work
I just ran into a bug where by a command like this:
> /usr/bin/open -b org.mozilla.firefox 'file:///tmp/test.html/?a=b&c=d' does not work correctly. It turns out the query string such as '?a=b&c=d' does not get passed to the Firefox as evident in the address bar. The http:// protocol based URLs work correctly.
I suspect the #reference to go to a specific anchor will also not work. I have not tried it though.
This is a bug (regression) on Mac OS Leopard (10.5). It use to work on Mac OS Tiger (10.4). I have already filed a bug with Apple for this.
BTW I have to use the /usr/bin/open command to reliably and repeatedly open a URL in Firefox (i.e. when Firefox is already running or not). That is because if I use the command such as: > /Application/Firefox.app/Contents/MacOS/firefox 'file:///tmp/test.html/?a=b&c=d'
when Firefox is already running it give me an error along the lines of "There is already an instance of Firefox running. You can only run one instance of Firefox.". I thought this information may be useful to some folks who are struggling with the same issue.
Posted by sandipchitale
( Apr 02 2008, 10:28:20 AM PDT ) Permalink
|