WWDC2004 Session 431

Transcript

Kind: captions Language: en okay good afternoon thanks for waiting single s talk got off a little early everybody ready to build some great java application that's not what I was hoping for but ok let's see if I can do better at the end I've been on stage every day so in case you don't already know me my name is Matt rant and I work in developer tech support for java and i'm going to talk to you about making the most of the features that are provided to you both by the java to standard edition and provided by us on mac OS 10 we've got tips today for developers of all shapes and sizes and backgrounds people who are new to mac how many people are java developers new to mac OS 10 very few that's great that's really exciting how many people are max developers that are new to java wow that's really interesting great well welcome to everybody so we've got tips for all kinds of people knew the mac new to java and people who are experienced in both and I guess that's a majority of our crowd since I didn't see a lot of hands in the first two questions so what are we going to learn we're going to learn about making a standard java application a real Mac os10 application something that really doesn't feel like it was written in Java and your users would never know the difference we're going to do step-by-step analysis of a real Java app I was working on demos for this app over the last couple of weeks and I was doing it's 10 steps so I was writing ten tiny little demos proof of concepts of each of these things and you know I thought that I could show these things and you guys would say yeah little grade Matt you were ten lines and you showed us how this works in theory but I have a real application so what I did was I searched around on sourceforge for something that would be a good nominee nominee for this talk and that application is called pooka I don't know where the name came from don't ask me it's an open source email client so it's check female does imap and pop it's built with swing using ants and it also uses java and uses java male and java help it does you know all the things you'd expect the mail client to do and it supports multiple looking fields it has multiple GUI formats and it's got a really nice dynamic customizable looking feel you can change just about everything labeled menu shortcuts which actually will make one of our steps very easy later on but there's the URL sourceforge.net I would encourage you to check it out after this talk just to see how far will have come at the ends of this at the end of the top so we're going to do start to finish so what's the start the start is downloading an application to the desktop and so what's the use case here a user either installed your application using an installer in the case of a lot of Java applications you download them off the web or often FTP site and usually it's just a jar file or a number of jar files and from a mac perspective jar files really aren't application I mean their files that you can double-click and launch and that's great but from a mac users perspective somebody who doesn't know what Java is or cocoa or carbon they just want an appt a dar file is going to be very foreign to them it's got a very generic icon as I'm sure I'm sure you've all seen usually got an unfriendly file name will show you what pooka looks like when we downloaded it in a second and usually or often there's more than one jar file and that becomes a real problem which one do i double-click what do i do what's the user supposed to do now of course they could use the terminal this is a UNIX operating system but you know we like to think that we've done a lot of work so that our end users don't ever have to know that it's unit so asking your user to download something go to the terminal and type some strings really not the optimal thing could run a shell script it's a little easier depending on how you format it you can name it doc command and they could double-click that still going to bring up a terminal window you know it might freak your users out something like my grandmother would probably call me if I emails are an application told your double click something and then she saw something with some really foreign-looking text on and of course there is the finder if you've done the right thing with your jar your jar you you should be able to double click it in launch the app if you haven't done the right thing with your jar you might try to double click it nothing happens so what's step one step one is packaged your application for Mac OS 10 the easiest thing to do you can do this no matter what what platform you're actually building on is just write a manifest file with a main class attribute this is a screenshot from s code of the manifest file that was already in focus so they actually did step or half of step one already so I applaud them for that this is a double clickable jar and Mac os10 and it comes up without any problems what we would really like you to do of course is use our tools are bundler which takes all of your jars in any of your other files and creates a real Mac os10 executable that's double clickable on the desktop it gives you a friendly application name that shows up in the dock and up in the menu bar you can set mac and java properties you can set an icon to make it look even more friendly and we talked about this in a couple talks specifically the deployment talk yesterday but you can also ask for a java version and when you do that using the JVM version key we'd like you to use the star and plus modifiers instead of explicitly saying something like 13 10 or 14 1 and particularly if you have jni libraries and you're adding day and I libraries to a package those will automatically get detected by the application you don't have to worry about setting the Java library that path variable like you might have to do on other platforms so how many of you have used jar bundler in the past okay well about how okay so then this demo won't be totally pointless can we go to demo one please alright so step one so here's pooka and it's one file which is great downloaded from source board it's got a jar icon it's got I'm guessing this as a version number and I'm guessing this is when it was built I have no idea let's try to double click it and see what happens the app will come up eventually and what it does we see we have our dock icon which is a generic Java icon and it's got some interesting name which we all know is just the main class which is what the Java launch or takes by default and well it looks like we have some work to do let's not configure an email account right now let's do we can do about this let's launch jar bundler and let's just drag this jar right in there and it's going to add it to the class path for me set a couple of very simple properties the bundle name is how this will show up in the desktop and then the dock so we'll call it call a pooka and this is a nice little feature it's asking me to enter a main class and you know maybe I don't remember the full package path especially since I didn't write this application so we can show it the jar and it's going to have to do some work to parse the whole thing it's a huge application there's a lot of files in the jar but you notice that it did find a class in there with a main method defined so it automatically selected that so now we have this icon here and what can we do about that and this is actually such a trivial step that I really want to show people how to do it I pulled this icon out of the jar file this is the logo for pooka I'm so I'm going to do is launch icon composer and just drag the picture in here it's going to ask me to scale it down and then I'm just going to move it down scale it and it's going to also extract the Alpha mass that's in here because it is a it is a transparent picture so I'm going to save this save to the desktop call it pooka icon go out of here I'm going to drag this guy right in and there's our icon so I think we're done so let's create our appt call it pooka and there's our app and already we have a doc icon with a proper name proper name up here and obviously we still have some work to do but there's nine steps to go so can we go back to the slides please so now I want to talk to you a little bit about gooey themes and the concept of looking feels and colors and standard shapes and sizes they talked a little bit about this yesterday Barry and Tommy did a great job with it so I'm going to run through this as quickly as I can so the message is that Java is cross-platform right ones run everywhere but there's also a caveat to that it's cross-platform you never know which platform this application is going to be run on you don't know what the standard sizes are four buttons and scroll pains and all other kinds of widgets clothes boxes background colors font sizes are probably going to be different not only across platforms but across look and feel and if you make assumptions about these things if you're only building and testing on one platform you could bring it over to another platform building on Windows coming over to the mac and you can be in a lot of trouble so this brings us to step two which is make no assumptions don't force the look and feel trust the default use layout managers try not to calculate explicit sizes for your controls try to get your colors your icons your fonts your borders from the system ask the UI manager asked the toolkit things like the text field background color the margin for the editor pains close icons for your internal frames if you're using a day desktop pain all those things can be gotten from the look and feel and you'll always get the right one instead of assuming you know what where you're running and the other thing which was the point from yesterday is if you want or don't want anti-aliasing make sure you say you do or don't don't ever assume that it's going to be on or off from one place to another now I'd like to go back to demo one and just show you what I mean so this is the double clickable we just built with jar bummer and I'm so used to the magnified version I can't move where the preferences are so let's go to the themes options which were right here and we have all our look and feels here and this is kind of a nice feature of Phuket lets you select one so let's go select aqua and it's in aqua no it's not well it kind of is I mean I have an aqua control here and you know this button seems to change and I see my aqua scroll bars but it looks half and half so let's see what went on here and unfortunately I had to get the source out it is sourceforge so it's that's not that big a deal and what we can go to this is the main class of the application and if I did my homework and I did I notice right here is that big enough can everybody see it too small ok let's let's take care of that right now that okay alright so once I scroll and adjust for the new size and I smartly mark all these steps so here we are we are setting the background color of the frame to grey and this is basically well I'm running on metal right so let me just be extra careful and make sure everything shows up gray in case the look and feel for some reason forgets to paint them and as we can see when we switch to something that doesn't have a default gray background that's not how it doesn't really turn out so great so in the interest of time I'm not going to build these things in front of your eyes but we basically comment out the gray thing and with that one line change now we're truly in aqua looks as you might expect it to and you probably can guess looking at this window what the next step is going to be but I will leave you in suspense for a couple more seconds can we go back to the slides please the next step of course would be the menu bar so what's the problem with the application menu for mac OS 10 as you know has a menu bar at the top of the screen we have an application menu that gets popped up for every app that you launched but j menu bar is in swinging up here in the window they don't appear at the top of the frame the application menu that we try to conveniently create for you isn't completely responsive because Java has no concept of it the quit menu item will just quit it's not intercepted by your Java code automatically to tau Kennedy preferences item doesn't appear by default and the about menu item isn't integrated into whatever informational thing you might have had on other platforms so this brings us to step 3 making a Macintosh menu bar most of you probably know this you set the Apple lasu screen menu bar properties to runtime property and that immediately jumps your J menu bars up to the top of the screen with no additional work this is just something you can specify either in the properties item of your info.plist you can do it as a dash D property at runtime and from the terminal or you can do a system step property with it before you initialize a WT and the other item would be the application menu and unfortunately you can't do this in a completely universal way we did have to write some api's that you guys can use and that gives us to the extended awt vawt package and the main the main item here is the Khan Apple II awt application listener and there's an adapter class that you can extend as opposed to implementing the interface and this will allow you to halt handle all the items in the application menu about preferences quit gives you a couple of other methods that we probably won't go through today because we've got a lot to cover and you can report and once you implement those things you can replace the things in your file or edit menus that you had on other platforms you know a lot of people have preferences under edit they have options or preferences under help or they have their about stuff under help so you know you can detect whether or not you're on a Mac and if you know you're doing that use the application listener if you're on another platform go ahead and put that menu where it was before and we've great way of doing this with the OS 10 adapt their sample code which basically uses reflection to load a class that implements all these interfaces so basically you have that code it's built and it runs and you only load it when you're on Mac OS 10 and because if you're loading it reflectively the class load never occurs on Windows or Linux so you know to worry about forking your code and building a mac version of this so I was talking about detecting a math and how do we do that well this is really the most recommended way by Apple to do it go ahead and get the OS name property send it to lower case just to be thorough and then see if it starts with mac OS 10 it's pretty intuitive Barry and Tom talked about this yesterday I just wanted to go over go over it one more time and this is covered in technical technote 2110 so if we can go back to demo one we want to show you real quick what a Macintosh menu bar is supposed to look like so as you can see we do have the application menu and it does have the proper name now because we set that bumble name item in jar bellman when we built it when I click about here I get this default about thing that Apple pulls up if you haven't implemented the ewt interfaces notice there's no preferences here and it gets really ugly when I do something like this I start typing an email and then I go to quit and it's gone now Puka probably had some kind of are you sure you want to save stuff when you go to file exit or when you go to close the window manually but you need to intercept that quit item and so how do we do that well let's go to step 3 and basically I just inserted some quick code here i have a mac integration class so I localized all my Mac code in one place and I basically told it to do an application menu registration call the static method very simple let's see what it does how many of you've seen the OS 10 adapter sample codes and tap ok all right so we need to go over this so here we have my at Mac integration class and what I call the menu registration there's a lot of verbiage here but basically what I'm doing is I'm reflectively loading another class that will show you in a second my application adapter class and I'm doing all the registration for about quit etc etc let's go over there and see the application adapter class so what this basically does is it creates an apple ii awt application and you notice that we're no longer using reflection here this class is completely contained it's now calling the Apple api's directly and the reason it can do that is because we're not even loading this class unless we're on the Mac so now we can be safe we're adding an application creating an application adding the application listener this is the standard eew t code and then we have all our implementations down here handle quit handle about handle preferences let's see how we did now you can see the menu bars at the top for starters and create a new message here and now when I do apple q sorry command queue I do get the standard pooka close code I didn't write this dialog this was part of the standard app but now we hooked into it properly with a very minimum lad of effort can we go back to slides please thank you so now I want to talk about user interaction and a couple a bunch of these things i'm not going to demo because pooka actually does them very well but i want to talk about them anyway so a lot of GUI apps are often written and tested only on a single platform I deal with this all the time and developer support things like hard coded menu modifiers people explicitly playing control I'm writing a menu i'm on windows all the apps seem to use control so i'll do ctrl C for copy i'm on windows i have a two button Mouse so to get right to get contextual menu all check for the button to mask on a mouse click or a mouse prep and it'll magically work right wrong unfortunately much to the vein of the mutts in the vein of the the GUI the GUI theme step earlier there are things that you can ask java for and java will just tell you what the right thing is for the right platform and among those things are the menu modifiers and the context menu trigger what action is supposed to trigger a contextual menu it's very abstract you don't us to do any event parsing or worried about what platform you're on it'll just do the right thing for you no matter where you're running and you know the idea here is hard code as little as possible use Java to its fullest extent and this is the menu example there's a toolkit get menu shortcut key mask method that gives you control on windows and meta which is the equivalent of command on the Mac and with that it will give you the right thing wherever you go and this is all the code you need to do to create a J menu item I've seen people do halfway and you know I appreciate their effort where they do if on Windows use control if on Mackey's man it's way too much work this is all you have to do I promise and context menus is the same thing there's a simple method called is pop-up trigger on a mouse event and that's the only thing you need to ask don't worry about button to button 3 don't worry about whether or not the control key has been held down if it's one button Mac mouth just ask Java is this a pop-up menu so yes it's going to go ahead and proceed as I can now there is one caveat here and that's there is something of a difference between Windows and Mac specifically on the Mac a context menu is activated on the pressing of the mouse so if you do a ctrl click it's going to as soon as you press the mouse button down the menu will pop up trigger will occur it's not going to be on the release like on Windows and the other thing is that you never know what kind of mouse is running on the Mac we ship a one button mouse you can easily buy a 235 button now so somebody could have a right mouse or they could have configured their mouths for it to be you know the thumb mouse or something like what's the mask for that I don't even know so ask the toolkit the caveat of the mouse press issue though is that right dragging as well as control dragging is not going to work on a mac so if you have Java code that does a right drag that's simply not going to work because as soon as that right mouse button is prepped Java is going to think it's time for a context menu that's something to be aware of and pooka actually as you can see it's done a good job of this itself so I don't need to do the context menu demo let's move right along to documents a lot of Java applications have documents that they read and write to the trick is how do I open these from outside Java code meaning you know it would be great if I could double-click this document drag it over my app whatever and have my application launch and open it because Java is not in the integral part of the system at least other systems this is kind of an issue the finder should really know how to do this it knows for cocoa and notes for carbon how do we do it for Java well this is also part of the e WT and it's step 5 which is register your documents and this is really remarkably easy if you've already done the work to load to do the OS 10 adapter style stuff loading up the EA WT implementation reflectively and safely all you have to do is implement one of the method which is handle open file and then you need to go into your info a plist either in jar bummer or in the finder or an Xcode if you're building with Xcode and just set one very simple key which is CF bundle document types it has some sub items which we have documented but this is the same thing you would do for cocoa and carbon there's no job of special stuff so just look up the standard apple documentation do this implement this one method and basically all you want to do this is going to pass you a java.io.file and you just hand that file so whatever logic you already have for opening your documents there's a little aside this is supported in java web start for 1.5 so if you're doing web start deployment that you'll get without even need do any of this work up top and this is a screenshot of vm copious keys obviously you can't read them but it's basically a blow-up of the sea of fumble document types property and it has things like the icon that you might want to specify for the document filename extensions that you want to own mimetypes if you have them so on and so forth we'll have a link to that documentation later okay so this is the this is the big winner for me I get this a lot this isn't winning when we're dealing with files I download a lot of applications now and then and you know I started up and nothing happens I go into console and sure enough java could not find the file c colon backslash something and this is so easy to avoid so really don't ever assume i've said assume nothing before but that also applies to the file system to what you know what system you are on things like drive letters back classes or even colin's because this isn't mac OS 9 either those can be potentially fatal if you have some critical file that you need to load and you've got a specific path you may be doomed and this brings us the step 6 there are java methods for this too there are constants for things like the rice file separator on the right platform there was a path separator if there's some kind of paths that you need to construct there's a user durand user home system properties just using system.getproperty and those will give you the user home directory or the current running directory of the application so if you want to do things like do relative relative files off of the home directory you don't need to ask the user during your installation whereas home directory is or anything like that just get the property some java and then build off of that and if you have things on the classpath whether they be in your jars or just on somewhere else in the class path that you said whether they be images or something else you can just call your class loader and ask for the system resource and you'll get a URL to that file and it's already you don't even need to worry about TAF names and you can also use info the map that we make available you in the info adoptee list to do some other path access I'm going to talk about that right now this is a picture of the info.plist oh I'm sorry this is a picture of Jar bubbler and I know you can't read these so I have the text on the right there are two big macros that we have one of them is app package the other one is Java root an app package points to the absolute path to your double clickable application and the Java route is the contents resources Java subdirectory of that package now these macros are available are you are for use by the Java launcher meaning you'll never see them at runtime in your Java code but what you can do is because you already have a plist and you have properties as you can see up here in jar bundler you can set a job of system property and set the value to app package or Java root or some extension there up and and the pack of the the launcher stub will build these and set them assistant property so at runtime you can do get system property for whatever I set and you will have that path available to you so we talked about documents already I know it sounds a little confusing but now we're talking about other people's documents other people's applications how do i launched a website what's the default browser on the system do i really want to call the system configuration framework probably not how do i know if there's how do i know if there's a browser installed how do i know which one I can launch if I have another applications document especially with this an email program is going to get attachment how do I open that attachment how do i find it launched it how do i feed the dock to the application so this is the this is the other one that we really haven't talked about at the conference before it gets a lot of play on the mailing list the runtime exec method can be your friend a lot of people are afraid of it but particularly open command because it's hooked directly into launch services and you can test this out from the terminal you just type open and some file name and it will go to whatever the currently registered application is for that document and it will go ahead and open it up you feed it a URL that'll launch Safari or you can override that behavior by using dash a if you know specifically that there's an application installed somewhere you can tell it open this document with this app and we recommend that when you're calling runtime exec you use a separated string array with your spaces because if you use a single space separated string that could work but if you have a single argument with spaces in it that's that's going to fall apart on you but the real key here is I'm telling you this but I don't want you to overuse runtime exec use the Java API is where you can just like the previous steps there are ways of doing this if you want to get a list of files don't do a runtime exact on LS just ask the fat and get a file objects for the directory that you're in asset to list of files you can do a make you can do a maker with the files class you can rename a file with the file class and this is just a code example it looks pretty legible of how we do this constructing a string array here obviously the first item is open because that's that's the command we want to send to the terminal and then look I'm using user down home so this is going to open an MS word doc called my doc in the user's home directory and basically we run time exec returns a Prophet's object so you can get that process object and if you need to do I owe with it or just to take care of any error of reporting anything like that you can do that through the process object and I would like to show you demo that right now make sure I'm on on schedule here I think so so here we are with our application menu bar and we have our correct menu shortcuts with the command key as we'd expect to see them so we're we're making good progress so that is playing around with cuca some more and there's this address book item let me open up the address book and it brings me to this address book editor obviously it's pookas address book and I go over the addresses and they're empty I really don't want to enter all my friends addresses again so what can we possibly do about this well this is where the beauty of runtime exec comes in I know I have an address book application here on the system and it would be a shame if I had to do cutting cut cutting and pasting anything like that where are we only step 7 okay okay and that brings us here I mean I wrote some really simple methods in my mind Mac integration class to open the address book the real address book and again I know where address book is installed everything system standard is installed in flash application so we have a path here and here's the same runtime exact code that were roughly the same code that I showed you in the slide and I'm calling this over here this is the code that responds to the menu buttons the menu item up in the menu bar this is from the pooka code this is nothing that I wrote and basically all I did was insert something right here to open the address book so let's see how that works and again the app shouldn't look any different cuz all we're doing is changing the menu item but I go ahead and I click the address book menu item and all right so that's what I'm used to seeing now I don't have to enter all this stuff again if I need to edit addresses I can do it the way I'm used to doing this is six lines of code shouldn't be any problem at all so let's go back to the slide please here's the next item help and I'm not asking for help I just talking about though there are plenty of concepts of user assistance and Java provides those as well obviously the most popular one is Java help and data help find it works on the max just fine you saw a screenshot of it up there the trick is that it's not a part of the standard edition and part of part of our idea behind distributing the whole JDK as part of our systems that you don't to worry about redistribution and then you go into these additional features nice to do Java help I have to go find some third-party tool to generate a Java health help set and that's not the kind of work we want to do and furthermore after you do all that work you have this Java help window come up and it really doesn't look that Mac like there's nothing wrong with it but it's just not familiar Mac users in particular particular are used to using the system health viewer and now some people might say whoa hold on I'm not rewriting my entire health but the Java help sets are already written in HTML which is the same thing that the healthy reuses so we have a very portable situation here so that brings us a step ii use the health viewer you can create a help look to support your application very very easily you can use the existing HTML from your java help help set the otha help will still work if you did things correctly you shouldn't have to interfere with anything you've already done and the great thing about integration would matter with the mac OS 10 health viewer is that after you load up your help Mac os10 help will now search your applications help content even when the app isn't running if you're using Java help you have to launch the app and then go to help and then only within the context of your application can your use or get assistance and I'll show you why that may be a good thing later so here's what you have to do to actually use the help viewer from your application here's another info.plist screenshot there's two big info.plist keys one of them is CS bundle help folder the other one is CS fund will help look neat and that's it basically obviously put the name of your hope your folder and the help of name is something a little more specific and I'll go into that in a second and I will show you a demo now when we go to demo one so let me first show you what I'm talking about this is our step 7 application so go up here to the help menu and here's our Java help now it's not that bad it's an aqua you know everything's cool but you know it doesn't it does you get the idea that this is something that was not written on a Macintosh these icons are a little funny as you can see the Java help frame does not know enough to give itself a menu bar so let's see if we can do something better about that and I have been blowing through these projects up until now because this is where it starts to get interesting and I wanted to take a special extra special amount of time with these next three steps so here's our step 8 project and what I've written here is yes don't gasps it's jni code it's a very simple native void here with the show help methods and I'll explain what the bad show help is when we go back to the slides and here's our day and I function we go to show help and all we have to do is get the standard NS application because again we're running on top of cocoa and there's a very simple method called show help and once we do that the system the cocoa system goes in looks at the info.plist finds out what the help of folder is find out the help book name and that's how it knows to load up the help folder and what's the front pages and the only remaining step was for me to call this application to call this new method from the help action which was already written in Phuket now there's something missing here and that's the excuse me that's the help bundle itself so what you're looking at right here is the Java help help set from pooka I took it out of the jar this is the folder that it always was got the same content everything else I did a couple simple things you can see this Mac health index item this is a very simple front page that i wrote got a frame set I wrote another simple page because I wanted this to be a frameset thing with all the table of contents and the left looking just like the Java helped it and the real thing here is this meta tag that I added to the front this is the Apple title meta tag this is what help viewer looks for when it goes to load up a help set so this needs to match the content here needs to match what you put in your CF sogndal help book name property and that's really all I did I didn't change any of the other content the other thing I did was I drop this guy on top of the apple health indexer which is part of the development which is under developer / applications in your developer tools and what that does is it makes it searchable I added a few keywords meta tags in a few places and i created a search index for apple help so let's see where that gets us bring up our step 8 pooka app and now when i go to help we're launching healthier and it's going to go ahead and parse the health content this is inside the dot app package this is the same content that was in the Java help and if i did my HTML right which I can't guarantee these links should work well that's great okay I mean really this doesn't seem like a big win for a Java developer especially somebody that's new to the platform so great i did this work and I have the same help I had before but where this really gets interesting is you'll notice I'm not running in pooka anymore let's go to the finder now go to Mac help and this is just the standard Macintosh help where is the finger and I get a bunch of hits here but what if I searched all health and asked how do i encrypt email messages and now if I sort this by relevance you see that pooka appears at the top because of the keywords i entered in the meta tag and the key is that pook is not running anymore and so your user may it may use your application all the time and if it's not running and they're running in the fire and they want to know how to do something they can search the macintosh help and your application will pop up and maybe show them something that they didn't even know how to do before if you're using java help they have to be using your application to learn about it using the massive house health they don't have to be and that's the big win there and again this was five minutes of HTML work and about 30 seconds of info.plist work and obviously i'm going to make this that help code available to you so you don't have to do anything to call java method we go back to the slides please so this is where the bad she'll help method comes in once we start working with J&I there are some things to be careful about whether you're calling to or from native code there are threatening issues java.awt and the app get the cocoa GUI operate on separate threads and they expect their events to appear in certain places if you're calling from Java into app get you need to be careful because typically if you're coming from Java you're coming from a javathread you may even be coming from the awt thread and Coco has a mechanism for this is called perform selector on main threat and that basically sends an asynchronous message to the event queue so that when you're doing some app kit operations you don't have to worry about a deadlock and likewise if you're calling from coco into java you want to make sure if you're going to do things like update the UI you want to make sure you get on the event too especially in case of swing which is single threaded and you can do that using event queue invoke later or swing utilities invoke later which is just a wrapper around that same call and you want to let Java return all as soon as possible and that's what this does it will drop you on a new thread on a new runnable rather and put yourself on the AWT thread so you can return I mean I think you can probably see the situation here where I have a Java event and in response to that job event I make a call to app kiss and then apke takes a call back into Java to do something like a repaint and we're done so and that's where the bad show help came in i'm not going to demo that but what the bad show helped it was it made the help request off of the main off of the main app kit thread and that's really not you know you might say what's the big deal all we did was launched a separate application and that's true it's not that big a deal in this case but what happens is if there's no help book folder specified or I can't find the health book folder a dialog comes up and that dialogue comes up from cocoa so if we did this directly on the awt thread and then asked hit dialogue came up we would have been in big trouble and again it's my job to make sure you guys don't have to worry about this but I need to say it it was mentioned earlier in Ted's talk and Xcode for java development because he was talking about someday and I think Stu and this is very very important if any of you were going to do any day and I said you really need to be aware of this so with that I'd like to talk some more about the really cool stuff what can we really do so far we've been talking about compatibility and you know cute little bells and whistles but what can we do to really really make this app cool and you know it's a sad fact but Java can't do everything it just can't it's cross-platform it doesn't know which platform it's running on which is you know a good thing for you if you want to deploy as many places you can but it doesn't know its hosts that deeply we've already seen that with the screen menu bar with the application menu and to an extent with the health viewer there are plenty of system ap is that you've learned about all weeks there are plenty of components and you know you may think that they're unavailable to you or are they and so this is step 9 we have another piece of being the extended awt called Coco component and what Coco component lets you do is it's a java.awt component but what it lets you do is it creates a hook that allows you to write a day ni library to extend nens view and then plant that in a in a Java hierarchy so you can do anything you can get a webview NS opengl view and a be people picker view even the Qt movie view from the new cutie kit that they've been talking about this week you can drop any of those into a java application you can bring these features right to java and i'm going to show you how to do that right now can we go to demo one please who I should have done that earlier okay so let's run step 8 again and we got halfway there with step 7 when we launched the address book to do our editing and now what I want to do is I want to write an email so here's this little address icon that pooka has right here and great I'm back to that address book that I didn't want to answer all my email addresses in yet again so what can we do about this well we can do a little bit of work see if we can get a cocoa component in here and of course we already did I'll show you how so here's my job of people picker view it extends the cocoa component and it's actually pretty simple obviously we load the library uses jni there are a couple of things you have to implement that I'll leave to to you after the talk we have a pretty expensive javadoc documentation on this you need to have something that creates the NS view and I have I have some methods down here that I've defined myself that will show you later and so the counterpart to this is going to be the native code here and we have the day and I callback shown right here let me open this up for you a little better I know it's scary C code I bet you didn't think you were going to see that in this talk huh so this is our standard cocoa initialization code create a new people picker view and of course this extends the a B people picker view from address book and I think you can see where we're going with this let's just go ahead and run it before I explain anything else create another new message click my button and this time we have the real address book and this is really what I wanted to see I didn't want to enter this stuff all again I didn't want to look around and figure out who I want to email is copy it paste it into the other thing and once we have this in the app and we got the whole job a team in here we can email whoever we want an email scott you know Caroline and so what's happening here is I'm double clicking into this cocoa view I'm intercepting the events taking the address book information sending it back to Java because remember this is a java frame so i'm taking these strings and putting them in the to field I admit it slightly complicated but let me show you how I'm doing that here's our here's our people picker view and soon as I remember how I did it so Coco is pretty dynamics and with this M with this view this is specifically an address book method which is the set name double action as in i have a double click on this view what do I do with it and I told it to do the mail to selection method and this is it right here and basically you can see a lot of a B methods here this is address book API I really don't want to teach you the address book it's not the point here what I'm doing is I'm getting the person that was just fill out and just double click and then down here we call back to the Java object that instantiated us now how did we do that how do we know where our Java pier is well I do that up here first thing we need to do is have the Java VM on hand at all times and there's a handy j and I function called an eye on load and basically as soon as you call system load library this method gets called this function gets called and then you can just have a JVM sitting there and just grab the day vm on load and then you have it available to you at any point and what we do then is when the view is initialized and here's our create NS view method and whenever you get a Jay and I call back from Java there's two possibilities one of them is you have if it's an object call if it's an object method you get a reference to the J object that was that that was calling you if it's if it's a static method you get a reference to the J class so basically I just basically we just cast that objects and make sure we have a hold of it and here's our in it we pass the day object and so how you hold on to this if you create something called the global rest and this is something you do in Jay and I to hold on to a Java object in native code and there were some caveats to that namely the fact that this is a real java reference so if you know out all your references in your Java code you still have this one so garbage collection may not occur now there's also an equivalent to this which is a weak global reference which works like a weak reference and that's probably the way you want to go but for the interest in the interest of thread safety and all those things I wanted to create a global ref here and that's really that's really where we have we have our we have the cash vm we go ahead and we get the jni environment from it we get the class from our job appear we go find a method called new email to that I wrote in Java and we pass the string that we got from addis address book back to our Java object and that's exactly what's happening in the demo we double-click the address book view it gets it gets a navy person I asked for the email address I send that back the job a Java gets the string and puts it into two seagulls all right I think I've beaten that to death so can we go back to this slide so what's the last thing the last thing of course would be the dock it's a really nice innovative thing in Mac OS 10 and it really doesn't work with Java or maybe it does if you get a lot of things for free as you've seen already you get the name in the dock you get your dock icon if you set it and the new feature in Java 14 to update one is window tracking any of your java frame appear in the doc menu and you can go ahead and select those there's no work from you and I think that's a nice little addition that's all you get sup you're not able to badge the doc or change the icon you can't bounce the doc and you can't set any custom menu items either or Kenya so here's step 10 step 10 would be to really use the doc and I've written a sample code called javadocs not to be confused with the Javadoc without the k and i'll be releasing that after the show once i get rid of the lewd comments in it while i was cramming for this show and basically it opens up the doc to java developers anything you want to do you can do from Java code now we can change the icon at runtime you can add items to the menu and you can alert the user if you're not in the front I'd like to show you demo that so this is our step 9 application still open and so here's our doc man you can everybody see that you don't need to read it but you can see it this item up here is that free window tracking menu that I mentioned early or any java furring that comes up is going to be selectable in the doc but wouldn't it be great if I could do more than that and so what I'm going to do first is a fun song got some some of the java team sitting in the front row here trying to figure out who i want to send an email to i'll send an email of my fiance just give her a little free advertisement for her company while i'm at this conference here and you know the real convenient here is that Cayenne works for a wireless company called good technology and she basically carries an email device everywhere whether and we have a minor problem here which is that I haven't logged into my email account take care of that okay try that one more time okay we'll do it again and as you can see I've been using either the file menu or this button at the top of the frame to create a new message that's really not the best way to go let's see if we can come up with something better let me go ahead and run step 10 log into my email one more time and here we go so looks like the same app obviously the difference now is of course I have some doc menu items here and you know I only created two I didn't want to get too creative and I didn't want to make the doc menu take up everything else but so I click new message and I get a new message basically what I did here was I'll show you in a minute but this is java code that is calling you know a utility function to create a doc menu item I pass it in action and a string so it knew what the label should be and it knew how to respond when it was clicked and there's our response and let's see if the other cool thing about the doc is if something special happens when it's not in the front you get some kind of notification you do the bounces or you know maybe it badges if you're a male and so this is as penance for what went wrong on Monday night I did something at the last minute yesterday to see to see if I could do something a little more exciting for you today I'm going to give Cayenne a minute to respond to me and just in case she doesn't i'm going to send myself an email okay as you can see I've been testing this pretty extensively let's create a new message the other thing I need to be careful of let's edit that and this will be another neat demo notice i just changed that address so independent will try to check the email one more time see what happens and if nothing seems to happen i'll go ahead and just all right maybe she's in a meeting but I swear her technology works very well alright so we go ahead and send an email and let's see if this one shows up ah look she did respond and the doc is bouncing not only is it bouncing but it's changed so what happened here what happened was because cayenne is in my address book we got a new email from her we got the email address from the message because we're in Java went back in to address book did a search on her address returned a person from addressbook got the picture and put it in the doc and then bounced it so basically i could probably check mail again soon enough because my message should be in there somewhere oh there's my email look at that neck that's an old picture it's funny you know before I started working at apple I'd had time to do things like lift weights it was kind of cool so let's look at how I did this so here's our dock utilities class and this is in a separate project that that I didn't have the time to build in here but this is not a cocoa component this is regular jni code and there's two things here there's an action from doc menu item and that's going to be our callback that's going to be what see sends us and then we have all these need of a native functions so this is the one to balance the dock if we need to this is the one to set the image back and I don't know if you notice but when I clicked on the dock icon the standard one came back and that was part of the awt reopen application event so when I notice that we've been focused back to the front we go ahead and get the standard icon put it back because we're no longer alerting the user and we want to go back to normal so this will bounce us and here's our and here's our API to add the dock menu item you can do it two ways and do a straight a menu item or you can do with an action which is really the more politically correct way of doing it in swing and now we take our dive into native code and hopefully if I played my cards right when I release this you guys won't ever have to look at this code the idea is for you guys to be able to do this from Java whether it's show it to you anyway so here's our ad doc menu item function we had a bunch of stuff this is the this is the this is the class that called us because it's a static function this is the object this is the object which could either be in action or add a menu item and this is the name that we pass so these are our two arguments from the Java world we basically get these guys and this is a simple call to our cocoa doc utils is my objective c class and let's go see what that does and we've got a whole bunch of layered code to create a doc menus and NS menu down here but all you're sending from Java is a string with a string and in action so we know what to call back to and the way this works it sets itself isn't as a delegate for the NS application which is the underlying cocoa application that's running and there's a delegate method called application doc menu which is basically every time I do this every time I click on the dock icon the application calls its delicate and asks for a menu so we respond by giving it the menu that we've created what happens now when we and you can see the problem here so it's not really a Java menu it's a cocoa menu so how do we get back to Java when this is clipped how do we know and as soon as I remember which one it is a lot of functions here oh yes action from doc menu item that seems pretty pretty standard we basically get our callback I set this as the action responder on the dock menu and we cast our pier when we initialize the object again using the same technique as we did in the a B the AV people picker example we do the same thing get the day n IM find the class and find our actions from doc menu item the java action from doc menu item option and we pass back the pier be originated because job is going to need to you have more than one menu item you need to know which one got clicked let me go back to job to the dock utilities here we go this is what C is going to call to us it's going to pass some kind of object and like I said earlier it could be either an action or a Jay Manuel item so if it's day menu item we just get that and do a do click on it and the reason this is you know like i said the real politically correct way to do it is with an action but the idea here is the human interface guidelines say that you should only do you should only put things in the dock that are already in the menu bar so if you already have something you already have a Jay menu there just go ahead and pass it to this API and we'll take that and we'll do it as if is if the user had clicked it in the menu bar which is supposed to be how it operates of course if you have an action that would be the same the same idea and you know as a result we respond to it we need to go to that new message action that we had earlier or the check mail action and I believe that's all I got we go back to the slide so where have we gone in the last hour we started with this anonymous random application off of source boards that had an obscure file name didn't look anything like it belongs on the Macintosh and we ended up with this we have an application with the doc with an application icons with a proper name with the doc icon a doc menu it has integration with the address book has integration with other system applications and as integration with the systems health this is a Macintosh application this isn't just a Java app that runs on the Mac so we did this in an hour it didn't really take me an hour but I downloaded this program randomly and I wanted to do that to demonstrate to you that this is not precooked stuff I never saw the source code to the fat before and if I was able to do this you guys who know the code to your own apps should be able to do without a problem and it's still cross platform because of those reflective techniques even the jni stuff we don't load those classes that call the jni code they'll never load native libraries so you can dump all these files in your standard distribution and never worry about link errors or anything like that there's no need to be afraid of the fact that we're using native code here so it's nothing else make an application bundle or at least a manifest file make your application double clickable as Mac like as possible give yourself a nice desktop icon and it usually takes just a couple seconds watch for portability pitfalls I didn't beat those to death because I've beat him to death over the last two years and Tom and Barry talked about them too pretty good length yesterday use your info.plist and use the e WT a p.i to do quite a bit already get your application menu stuff you can set your properties get the menu bar at the top to do things like vanish the grow box so on and so forth use the apple health that's probably the easiest of these steps that I've showed you all I had to do is change a little bit of HTML code it and drag the folder over the apple health indexer which isn't even necessary that was just to make the search more robust hate that word and you know runtime exec Jana you can use them you don't need to be afraid you just need to be careful and once you know the rules is just like anything else all of you've been new to some kind of programming technique in the test you just need to know what you're doing and that's why I'm here tell me so you want to learn some more obviously we have a disk image and I'm sorry but I don't have the finished pooka product on the disk image and that's because I was cramming it well after the disk image was due the the reference library which has a great document called Java one for development for Mac os10 talks a lot about the portability pitfalls the EA WT stuff that I was talking about earlier we have a javadoc reference for the apple extensions for the EA WT there's also an e io class extended io class that will let you do some mac specific file interaction but that's really for legacy Development people who are used to using mrj on Mac OS 9 so unless you're one of those people that's probably something you can skip over and I'd really like you to read the human interface guidelines also if you're really interested in making your job apps as Mac life as possible there's a lot of stuff that speaks within the context of you know assuming you're programming with C or objective-c but there are a lot of high-level design aesthetic things that can easily apply to your java application and they're particularly useful thing is that the human interface guidelines have a table with all of our reserved system keyboard shortcuts and that can be really useful where if you're if you're worrying about your keyboard shortcuts on the mat and you know you say I I did f12 on my app and it works on Windows and when I do it on the mac some kind of crazy stuff drops down makes a splash on the screen so if you read the human interface guidelines you would not have to worry about that and of course the OS 10 adapt our sample code I think I've gotten a lot of good feedback about this and I think it's really really important because this is this is a big deal for people who have always real java purists who have said i want to write apple code I don't want to reference in Apple packages I don't want to build two different versions in my app you don't have to just look at this code it's one file it's about 20 lines and really can open up a whole bunch of new things that you can do with your Java app identifying Java on Mac OS 10 that's another another document that we have and I was talking about detecting the mac and the native document Association like I said earlier this is just a standard max documentation this is the stuff that you would do for carbon or cocoa or anything else you do that for Java and there's another article that I just found the other day on Java net where a guy who's sadly his name escapes me wrote a great article on doing this both on Windows and on Mac and i'm proud to say that the steps to do it on the mac or about half as many and providing user assistance for apple health this is both design guidelines for building a help book but also talked about setting those info.plist keys in case you didn't write them down fast enough earlier as well as what you need to do there's going to be some stuff talking about calling carbon functions and stuff like that but again you won't need to worry about that because we're going to get you the code to do it's in Java