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