Enterprise IT • 1:04:36
Java applications on Mac OS X are first-class citizens on the platform. This session covers the ways in which you can make your Java application work well on Mac OS X. Topics include implementing Aqua UI guidelines in Java, the new Apple extension APIs, and general techniques for making your application perform well on Mac OS X.
Speakers: Matt Drance, Ted Jucevic
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Very exciting. I'd like to thank you guys for coming here so early in the morning. I see a crowd like this, and I think, all right, job security. So my name is Matt Drance, and I work in developer tech support. So for all of you who may be submitting tech support incidents to DTS at Apple.com, there's a 50-50 chance that you'll be talking to me. The other chance is that you'll be talking to Ted Jucevic, who will be up here a little later to give the other half of this presentation.
So, what are we doing today? What are we talking about? So, Apple has been trying to convey the message as much as possible that we feel that Java applications are first-class citizens on Mac OS X. We offer a lot of tricks and tips and techniques that you can use to improve the user experience of your Java app on Mac OS X, make it feel as Mac-like as possible, and we also have a lot of deployment options for your end-user desktop applications that we're going to be talking about today.
And most of the technical details in this talk will be regarding the 141 J2SE that's now available for Mac OS X, Jaguar, and of course Panther. For Jaguar, it's available in software update, and there's also a developer update with tools and headers and such that you can get from the ADC website at connect.apple.com.
So, what specifically are we going to be talking about today? I'm going to talk a little bit about some pertinent directories on Mac OS X, where to put certain files, and where to find things. I'm going to talk about the Aqua look and feel for Swing. Just out of curiosity, how many people were at the State of the Union talk on Monday? Okay, a lot of you. So I'll run through that, since you saw most of it already. And I'm going to talk about some cross-platform UI programming techniques that will benefit you on the Mac, as well as on Windows or Linux, or anywhere else you're looking to deploy and develop.
And I'm going to talk about some specific things that you can do for Mac OS X to make things adhere better to the Aqua human interface guidelines standards, just really make your Java app as indistinguishable as possible from a Cocoa or Carbon application. And Ted will come up a little later. He'll talk about some of the runtime properties that we have available on Mac OS X and all the deployment options available to you as a developer.
So where things are. Like I said, we're now shipping, or we now have available the 141 SDK for Mac OS X. If developers are coming over from other platforms, typically we see a lot of shell script-based applications. And one of the more important areas and locations for running a Java app is the concept of a Java home. So you can get to things like Java and Java C and so on and so forth.
So on Mac OS X, we have an easily rememberable and placeable symbolic link that you can see up on the screen here called /library/java/home. And from there, you can go down to bin and view Java and Java C, et cetera, et cetera. And this will always be pointing to the current version of Java on Mac OS X. So currently, that's 141. Previously on 10.1, that pointed to 131. So that's something that you'll never have to update in your applications. You'll always get the newest version.
And as far as extensions and JNI directories, that's I guess the equivalent of other platforms would be a libx or a java.library.path. On Mac OS X, you can just drop your JNI libraries or your extension jars in library Java extensions off the root, as well as off the home directory, the user's home directory. So if you have some jars or JNI libraries that you don't want available to the entire system, that you just want within the scope of a single user, you can drop them there.
As far as doing JNI work or VM invocation work with native code, the VM headers are available inside the Java VM framework. You can see the path up here. If you're doing development with Xcode, or formerly known as Project Builder, all you need to do is add the Java VM framework to your project, and the headers will immediately be added, and you don't need to do any additions to your paths or anything like that.
So let's talk a little bit about the Aqua look and feel. A lot of you have already seen this since you've been to the State of the Union, but I'm going to run through it anyway. Aqua is the default swing look and feel for Java apps on Mac OS X.
We have some extra tweaks in there, like the screen menu bar, putting the menu bar for J frames, like we like to say, where it's supposed to be. We animate the default buttons on J frames and root panes. We animate the indeterminate progress bar with the, I guess, the barbershop stripe animation that you see on Cocoa and Carbon apps. There's a little bit on component sizing that you might need to get used to.
In certain places, we size our components the way the Aqua specs suggest that they be. So, for example, the picture behind me here is of a J combo box in a border layout. And you can see the window below is in metal, and the J combo box's button expands to the size of... the complete eastern container there. The Aqua version... Something's going on over there. The Aqua version is basically sized down to how you would expect it to look in an Aqua application on Mac OS X.
So there's things like that that you might need... that you might see change from platform to platform as you move over to X. And we do similar things with J buttons and with tabs in J tab panes, and that's something I'll be showing you in a little while. Speaking of J tab panes, one of the other parts of the Aqua specs suggests that tabs, no matter how many of them you have, be in a single row.
Other look and feels like metal and windows and... What's the slash one? Motif. Have support for multiple rows of tabs. Aqua does not like that. So with our Aqua look and feel for swing, we made a single row of tabs, and the problem there is if what if you have more tabs than fit on the window? That's the whole point of multiple rows. So we created a navigation control in 1.4 that will drop a menu down for all the tabs that you can use. You can't see and that will allow the user to jump across to the tab that they may or may not want to see.
These names of the tabs, of course, aren't very descriptive, but... So I'm just going to pull up a demo here. It shows you all the things I'm talking about. I understand that we've had quite a few questions about tabs in the last couple of days. So I figured we should maybe show off what we've got here in 1.4.
So this is a very simple demo, simply showing off what we have here in Aqua. This is how the tabs look. This is the standard font that you would see in a Cocoa application. And keep in mind that if a new OS were to come out and, say, change the layout and font size and type of all your controls and labels, and I can't imagine why something like that would happen, you'll get all that stuff for free if you use Aqua Swing. You don't really need to give much. You don't care to any of that stuff. So change the look and feel to metal. And one of the things you notice right away is that the tab icon size changed over here on my tab.
And my menu bar went down to the bottom here. So one of the things that Mac OS X does, and I'll go back to this tab icon. This is the icon that I'm using here. And it's the same one that I'm using at the top here. And that is being shrunk down by Aqua to have the tabs obey. So you only get one size of tabs. I know there are some people who were hoping there were multiple sizes. I'm sorry to say that there aren't.
And left, right, bottom placement, this is just regular Java calls. I can't remember what the specific call was for the tab pane to set the alignment. But it behaves as you would expect in Aqua. And we have toolbar buttons, the toggle buttons as you would expect, toolbar toggle buttons. We've got default buttons, and you can see the animation. Can you? Oh, good.
It's coming out well. And as you would expect, I hit the enter key, and the button is activated, and so on and so forth. And here are my progress bars. But my indeterminate progress bar seems to... That may be a bug on my part. Let's see if I remembered to actually turn it on or not. Oh, there it is.
So this is the indeterminate progress bar at the top, and it animates as you would expect it to as a Carbon or Cocoa application would do. And at the bottom, we have the determinate progress bar. And they still actually animate as you move the window around, which is kind of neat. That's something that didn't happen in 1.3.1. And that's one of our advantages from being a Coco-based UI now instead of a Carbon-based UI. I think that's enough. Can we go back to the slides, please? All right.
So let's talk a little bit about cross-platform programming techniques. There's a lot of things that I see working with a lot of developers. How many developers do we have here that are new to the Mac or looking at the Macintosh and coming over to Mac OS X? So most of this crowd are people who are primarily Mac OS X Java developers.
That's great. Excellent. But I'd like to extend a warm welcome to the people who are coming over, too. Last year, the crowd was mostly Windows and Solaris people coming over to the Mac. So it's great to see a crowd this big. So this list of tips and tricks that I came up with, basically I put together from working with a lot of developers coming over to the platform and looking at some common mistakes or preconceptions that they had in their heads about how Java behaved on every platform. And actually, some of it I've changed in the last 18 hours, just from my experience in the Java lab downstairs. So that's how committed I am to you.
So let's talk a little bit about working with components. This is kind of fuzzy. But generally, you want to do as little as possible when you're styling and sizing your components in Swing. If you need to ask, if you need to figure out, you're making a custom component, you want to know how big to make it, you want to know what color to make the background, you want to know what font to be using or what kind of icons to be using for a checkbox, for example.
Or, you know, get the Stripe background that you see in all the Aqua controls. You can usually ask the UI manager what to do for these kinds of things. And all these properties that I have here, for example, the combo box background, the J checkbox, menu item, check icon, those are all Swing standard properties. Those aren't Mac-specific things.
One of the greatest things to do as a Swing developer, something that I did very early on when I started to work at Apple, is just write a little unit test that calls UI manager, get defaults, and just dump all the keys and values of those. And that can do you a lot of good if you're looking to create custom components and you don't know how to make the Aqua Stripe background, for example.
You don't know what font to use. You don't know what icons to use for a checkbox, for example. And as far as sizing and placement, really the easiest thing, the best thing that I can tell you to do is use the layout managers. Layout managers do most of the work for you. They take care of spacing. They take care of size.
Our layout managers, unless you, you know, customize, and specifically do their best to size and space things according to the Aqua HI spec. And they respect preferred size in the most case. You usually want to make sure you're using a layout manager at the lowest level that respects the preferred size of a button, for example. The first one that comes to mind is flow layout, obviously.
So I want to talk a little bit about JDesktopPane. I don't see a lot of people using it that much anymore, but I just wanted to mention it. Our big mantra is just say no to JDesktopPane. The real reason is there's really just no equivalent to it on the Macintosh.
Carbon and Cocoa have no concept of an MDI interface. And it's very confusing to a user, and I'll show you what I mean in a second. There are plenty of alternatives to it. Like I said, I don't see a lot of people using it anymore. Most people are using, at least on the Mac, either just the multiple frame case, if you have a document-based application like a text editor, or with applications like JBuilder, LimeWire, Project Builder, iTunes, all these other ones have not necessarily just one window, but a single frame that has a bunch of different containers that move in and out, and navigation tabs and stuff like that.
And that's perfectly acceptable, and we definitely encourage that kind of development. So this is what I was talking about a second ago. You can see the JDesktopPane up here, and there's a window over here with the taxi cab, and it appears to be dragged off-screen or just over to the right, and there's BBEdit in the background, and you would expect, you know, my grandmother might expect that the other side of that window should be over BBEdit, but we don't know where that window has gone.
It's vanished. And, you know, we also have two docks here, and, you know, I don't know where I minimized one window to, if it's down in this dock or if it's in this other one. It's really kind of counterintuitive, and it doesn't really look like a Mac OS X application, in my opinion. So our advice is, Stay away.
So let's talk about menu shortcuts now. This is something that I still see a lot. I talked about it last year. But we have a new generation of developers, I guess, who maybe weren't here. So one of the biggest things I see with menu development is that people just-- Typically, from doing development primarily on Windows, see the control key as the shortcut, and they hard-code the control key as the menu shortcut. That's really not the thing to do. There's a much easier way of doing it.
You can just ask the toolkit, the AWT toolkit, to get the menu shortcut key mask, and it'll return control for you on Windows. It'll return control for you on Linux. It'll return command or meta on the Mac. And this is one call that you need to make. You don't need to check your OS version or OS vendor or anything like that, and you'll get it every time.
You're basically pushing the work off to the host platform, which is really what Java's supposed to be doing. Another thing we would suggest is checking out the Aqua HI guidelines to find out what letter shortcuts to use, things like S for save and O for open. We've got a big grid there for what the standard application things are. So you can make your app look exactly like BBEdit or Xcode, if that's what you want. So what's the other thing? Mnemonics.
This is just a... cosmetic thing worth mentioning. The Aqua Human Interface guideline really makes no mention of mnemonics. And they will work in Aqua Swing if you use them, with the exception of the screen menu bar. If you have mnemonics in your menu items in the screen menu bar, as soon as it goes up there, we're not going to paint them anymore.
Because that's kind of our prerogative to conform to the HI guidelines. If you have them, you know, with other controls or anything like that, they'll still be painted. But for menu mnemonics, we really suggest either conditionally placing them or not using them at all if you're targeting them. math.
So contextual menus and mouse clicks, right clicks, control clicks. That's the trick, isn't it? Which is it? So it could be either. It depends on what kind of mouse your user has. And as a developer, you don't know who's going to be using your application. So this can get to be a mess.
Fortunately, Sun has provided an easy method for this, very similar to the menu shortcut mask, called isPopupTrigger. You ask the mouse event, should I be showing a pop-up here? And it tells you true or false. It, again, defers the work to the host platform, and that's all you have to do about it.
No checking for masks or button numbers or anything like that. The only trick is that you typically want to, in your mouse listener, put this in the mouse pressed and the mouse released methods. On Windows, it does it in one. I believe Windows does it in mouse released. And on the Mac, I believe it's mouse pressed. I might have them backwards. The idea is use both. And, you know, again, control left is not button two. So those don't register the same events.
On the Mac, you know, all Macs come with a one-button mouse. So typically, the pop-up trigger is a control click. Somebody buys a two-button mouse later, and then they have the right click as the pop-up trigger. That is not the same event in Java. So you really should use this abstracted method because then you don't have to worry about it.
So I wanted to talk quickly about file access. I'm kind of being really high-level and abstract here. You know, there's different cases all the time. But really try not to hard-code file paths when you're getting to things. Use things like file dialogues. Use the user directory and the user home. Use the file separator system property, which gives you either a forward slash or a backslash or whatever is appropriate for the host platform.
If you have things like image files or anything that you need to load into your application, it's very easy to just put those on the class path and then get to them using calls like classloader.getsystemresource. There are a bunch of equivalent calls like that. And basically, you can access anything on the class path that'll do that kind of thing. And it's really handy to use with things like image icons or images. And then you don't have to use any kind of file path at all. You just use the file name. And that's really handy.
So a little bit about image formats. This is something that's come up. This is more of a performance issue, but since it deals with platform differences in image formats, I wanted to bring it up. An index color model in particular on Mac OS X is just not native or not acceptable to core graphics. So regardless of what we do in Java, those kind of images are going to perform badly. Core graphics also prefers images or color models with an alpha value specified.
When you're working with a buffered image, we suggest that you use the appropriate methods like create image or the best is create compatible image. Again, that'll push the work off to the host platform to...
[Transcript missing]
So I'm going to talk a little bit about coding for Mac OS X, things that you can do specifically on the Mac without a whole lot of impact on your code base and on the way you deploy or develop.
I'm going to talk about illustrating document changes, scroll bar policies, toolbar buttons, file dialogues, our new extended AWT API for doing things like handling the items in the application menu, opening documents that you may want to write or save to. And I'm going to talk about the Apple extended IO class also.
So document changes. First off, you may notice anybody who's working on Mac OS X, if you're working in BBEdit or Project Builder or anything like that, you notice whenever you have unsaved work, you get a little black dot in the close box. Well, believe it or not, you can do that with your Java application. We've added a little client property to JFrames and I believe JInternalFrames also. You just get the root pane and you set a client property called window modified to either true or false.
And then we'll just immediately paint that little black dot in the close box. So if you have a document. If you have a client-based application, you want to do this kind of thing. It's very simple and it's instantaneous. There's really not a lag or anything like that. You don't need to do any kind of threading games to make sure the AWT has been updated. It's pretty instantaneous.
So scroll bar policies. The Aqua HI guidelines talk about if you have a window with scrollable content, with potentially scrollable content, even if your content's not moving off the complete area yet, you should show the scroll bars at all times, even if at the time they're disabled. So on the left, I have an example of somebody who's read the HI guidelines and set their scroll bar policies to true or always for vertical and horizontal because they expect that the content will at some point go both down and to the right. And on the right is somebody who didn't read the Aqua HI guidelines or fell asleep during this talk and didn't do so.
So I want to talk about toolbar buttons, too. If you put a J button in a J toolbar in Aqua, you'll get the square toolbar-style button, as you'd expect. Some people want toolbar-style buttons without a J toolbar. And to do that, it's another client property. You simply put client property and set J button.button type to toolbar. And in my Aqua demo, you might have noticed that I had a toolbar button just floating around in a J panel there. And that's exactly what I did.
So file dialogs. This is something that came up in the lab a couple times. So a lot of people are inclined to use JfileChooser because they're using Swing, and this is in the JavaX.Swing package. But we really suggest using the AWT file dialog. And the reason for that is that it's very simply a heavyweight.
So it's going to use the OS file dialog. You're going to get the column view in Jaguar or in Panther. I'm not sure what they're calling it in Panther anymore, but there's a whole new file dialog in Panther. And if you use the AWT file dialog in your Java apps, when your Java app gets moved on to a system with Panther on it, you will get that file dialog. You won't need to wait for us to rewrite JfileChooser to look like the Panther dialog, for example.
And you do that with a simple system property, Apple AWT use file dialog packages. By the way, I didn't mention this at the beginning of the talk. If people are inclined to write this stuff down furiously, you don't need to worry about it because it is all on the web.
And we'll be giving you a link later. So if you've been cursing me for moving too fast, please don't worry about it. And basically this file dialog packages lets you not navigate inside .app and .package files. Normally those are technically folders. So a dumb file dialog might try to go into those and navigate the contents and resources and so on and so forth. So if you set this property, you can actually select those as files, which might be something that you want to do. that you want to do in your application.
So now I want to talk about our extended AWT APIs. This is the replacement for the MRJ Toolkit. For those who might have been around long enough to know those APIs, there's basically two real classes that you need to know about. There's the Apple EAWT application, which has two important methods.
One of them is to set the preferences menu to enabled, and that, like it sounds, enables the preferences menu item. And there's another method called AddApplicationListener. And what that does is this is your hook into being able to handle all the items in the application menu, things like the About application, the preferences, and the Quit menu item. And you would do that with the ApplicationAdapter class.
There's also an interface called ApplicationListener. But, you know, in the standard event model like they have in Java, they have adapters for almost every listener. We've done the same thing. And we really suggest that you extend the adapter class. just to make your code a little more readable.
So, as far as handling system Apple events, there are some extra methods available to you in the application listener, the application adapter. There's the open application event, which basically once the UI is finished loading and the open application Apple event's been received by the app, you can basically register a callback if there's anything you want to do, like pull up a tip of the day or a splash screen or anything like that.
And new to the Java update that was available as of Friday, there's a reopen application. And this is what happens when you click on the dock, like if you have no windows open in Safari and you focus Safari up to the front by clicking on its dock icon, you'll notice that it brings up a blank window, where BBEdit does the same thing and TextEdit does the same thing. And that's a reopen application event. So, you can receive that reopen application event and decide to put up your own blank window if you want.
There's also an open file handler, which this is kind of cool. This is something that really isn't doable too easily on other platforms. It'll let you register document types for your application. If you have a document-based app and you want to be able to double-click your documents or drag them over the application icon and have the application launch and open in your app, this is how you would do that.
This is your hook-in to that. It's basically a hook-in to launch services. And so there's two parts of it. You register the handle open file method. You implement that method. And then you have to go into the Info.plist and register your CFBundle document types, which is there's nothing Java-specific about that.
That's just part of the standard Mac OS X documentation. So if you go over to the bundle services documentation, find out how to tell launch services what kind of document you want to own, and then you're ready to go. And there's a print file handler. So if you're receiving Apple events from another application or from the finder, you highlight it and say, print, this is another hook-in for you to handle that event and maybe print a file from the finder.
One other call worth mentioning is the get mouse location on screen. This is in the application class. And this basically lets you get the coordinates of the mouse anywhere on screen. Why is that so special? Well, you could use a listener on your window or on your components or anything like that to get the location, but that's only going to work while the mouse is above that component, while it's in the real estate that that component occupies. So this method will let you do it anywhere on the screen, if it's not in Java real estate. And some application developers, especially in the education space, tend to want to do that kind of thing.
So one other thing worth mentioning is the Cocoa component class. This is something that I think Scott mentioned in the State of the Union the other day. It basically allows you to embed any custom NSVU, any Cocoa component inside your Java application. So it'll allow you to do things, you know, some simple native drawing.
We also have a sample code for the QD Cocoa component on our developer website, and that's actually what Scott demoed to you on Monday using the iSight and the Sequence Grabber from QuickTime. And since it's part of our pure Java API, it's also available to applets and Java Web Start. And to find out more about this, you can go to our Java Native Integration talk, session 620, which is on Friday, I believe.
Thursday, okay. And one last class, the extended I.O. class, the file manager. Now, this is something that if you're new to the platform or if you're 10 only, it's probably not very interesting to you. This is basically our preservation of Mac OS 9 functionality for people who needed it.
The find folder method for things like the preferences folder constant defined in the Mac events headers and the applications folder, for example, to set and get file creator and file type stuff, old resource stuff. That's stuff that you don't need to do on Mac OS X. If you have legacy stuff from Mac OS 9 that you're trying to bring over and you're still dependent on certain things like that, this is the class you want to use. And it also gives you a method for opening URLs with the default browser.
But again, that's something that you might not really need to do because on Mac OS X, you can simply pass open and a URL to the terminal, and that will talk to launch services and launch whatever browser you want. And to get to that from Java, you just pass the file, in those two strings to runtime exec, and you're done.
So now I want to do a little demo to you about-- just basically show you about use of the application menu and the application adapter and listeners. So this is my little text editor. I'm afraid it's not too feature rich, but it gets the job done. By creating a document here, simple text editor, Hello, WWDC. And you can see I don't have spell checking in here.
So I can save this and write it out to the desktop. Here's my AWT file dialog. It doesn't look like it's switched over to native or anything like that, but it does look exactly like a Mac OS X file dialog. So I'm going to save it on the desktop as test file.
And there it is on the desktop. So this is part of what I did with the Info.plist and the handling of the Open File application. So I can quit out of this application now, and I can just double-click the document, and it'll launch up my Java app and open up the document, as if it were written in Carbon or Cocoa. Very simple. And really, the way that I do this, it's not particularly pleasant, unfortunately.
[Transcript missing]
So as far as the reopen event, so I'm going to go over to Safari here, and now my text editor is not in the background. So I'm going to click on the dock, and now the reopen event has been passed through. And you can see that a new window came up for me. That was what I did by registering for the reopen callback. I created a new window.
And, you know, I tied it up to the preferences. So this is what I did. I called set preferences menu item enabled, and I did a handle preferences, brought up my preferences dialog, and I've got the reopen preference set here. So if I set that, it shouldn't create a new window anymore. Functional preferences. And then there's the about handler up here. Just create a simple about box.
And last but not least, of course, is the quit item. Now the quit menu item will, by default, call system.exe. So it's in your best interest to override the handle quit method in case you have things going on with
[Transcript missing]
So, I just showed you a bunch of Apple APIs, Apple-specific APIs, and some of you might be saying, oh, great, they're locking us in. Absolutely not.
There's no reason for you to be able to do this and not be locked and be locked into the platform. You don't need to worry about client or runtime properties. You can set those, and if another platform is not looking for them, it's not looking for them. Nothing's going to happen.
As far as use of the APIs, well, very simple. The easiest thing to do would be just to isolate all those handler methods in a separate class that you register with a simple static method and, you know, like a factory type of method that you simply call from reflection, either in your main method or in the constructor, your main class, wherever your initialization code is. Just use class for a name to bring it up, and, you know, basically, if it's not there, then it won't load.
But if you load the class statically, what happens is, you know, Java will try to recognize the application adapter that it's extended. You'll get a bunch of no class def found errors on Windows, and you don't want that. So, if you use reflection to load these up, things should be fine, and we've got a sample that does this. It's called OS X Adapter, and it's on our sample code website. So at this point, I want to bring Ted up to talk about runtime properties and deployment options, the other half of the talk. Ted? Great. Thanks, Matt. Good job. Good job.
All right. So what I'm going to talk to you about are just runtime properties that you can set on your application without having to recompile. So say you've already deployed on Windows or something like that or Solaris Linux. These are properties that you can set that will give you Aqua-type functionality, but you don't have to rebuild and stuff like that.
These, of course, will go into the Java properties key in the Info.plist or the Java 141.x. So you can set up your own plugin settings application. Now, you can also pass these in on the command line, something like that. So if you're doing something like J2EE stuff or something, you can pass it in.
But I'm going to go ahead and show you how to do that. For the most part, we prefer application bundles and stuff like that versus a shell script. So one of these is the Aqua look and feel, the screen menu bar. All you have to do is set the Aqua LAF use screen menu bar to true, and it'll actually move the screen menu bar, or the menu bar, up to the screen level. Normally in, say, like a swing application, it's actually in the frame itself. And with this, you can actually get what you'd expect on a Macintosh.
The resize control. Down here in the bottom left-hand corner, you can see I have this little textured surface saying, you know, you can drag this to resize it. You can add that on, again, with the property by just setting that true and without having to recompile your application.
[Transcript missing]
And if you didn't get this copied down, come up afterwards and we can actually just give you that. So full screen mode. You know, it's a new feature in 1.4.1, and we actually have a few properties that you can use when developing your application and also when you're deploying your application.
The top two, the fake full screen, or the top one, what that does is it will give you a window that's the size of your screen, but it doesn't actually, you know, grab the whole screen. That's useful in debugging to, you know, if you want to switch to your debugger and stuff like that.
It's not, you're not grabbing the whole screen. The second one, the Apple AWT full screen fade. When we go to a full screen mode, if you're changing resolution, we actually do a really nice fade to it and stuff like that. If you're not changing the resolution, we just go straight to full screen mode. But if you want that nice fade, set this property to true and we'll do the nice fade for you.
Another one, the third one, the full-screen capture all displays, what that does is, and that one's true by default, is when you go into full-screen mode, if you have multiple monitors, we also black out those monitors. If, say, like you wanted to have full-screen on one monitor and then have like a borderless window on another monitor to make it look like you have two full-screen windows, you'd want to set that to false. I didn't know that.
And then, of course, if you're going for a full kiosk mode type application and you don't want the cursor up there at all, the last property, you can set that to false, and that'll take care of that for you. Again, these are all documented up on our website, so you don't have to write them down if you don't want to.
So window positioning. We have a couple of properties that we have set for the Aqua to make things work as people would expect on the Mac OS X, but at times they cause problems with developers when they're writing their software, and so we add these properties so that you can actually change how it works. So the force-safe creation, if that was true, what it would do is if you were to create the window off-screen, You can actually set that to true, and it would force it to be on the screen.
And then the second one, for safe programming position, that one is true. And what that does is tries to prevent you from accidentally pushing it off the screen, the window. Now, some people actually like to create windows off-screen and push windows off-screen so that they can do rendering to it and then move it on-screen and stuff like that.
If so, you might want to set this to false. And then also, to keep the user from moving things off-screen, we also have a property for that. If you want the user to be able to move things off-screen and maybe not be able to get to them, you can set that to true.
So all those properties, again, now you can set all those properties without affecting, you know, recompiling your application. So if you bring your application over to Mac OS X and you don't want to recompile, you
[Transcript missing]
We do have double-clickable jar support, but unless you just have a single jar and you don't have any support files, it'll definitely work, but it's just not the recommended way.
The icon is not custom. It doesn't look like an application and stuff like that. And of course, you have shell scripts, but we really discourage that unless you're doing some enterprise deployment or something like that. So I'm not really even going to talk about it. Safari, of course, 1.0. You get full JDK 1.4.1 support.
We have the Java plugin available for Safari. And by default, you get the Aqua look and feel for free, as in all applets. can be affected in the Java plugin settings application. If you want to, if you want to set a default property or something like that, you can do that in this Java plugin settings application. It's actually in the application utilities Java folder. And you can manage your certificates, Java console, jar caching, all that in there. And actually, we have another session tomorrow that you can go to. And Scott will go into more detail about it.
will show you the Java console and all the cool debugging and stuff like that we now have for Safari and 141. So Java Web Start is... Well, I'll go ahead and explain it. It's for application deployment. It's a way that you can actually deploy an application over the web, but what you just do is you start with a link on a web page, your user clicks on that link, and then the separate application launches. You can actually pull your applications out of the browser, your applets. It's really kind of nice if the browser is causing issues, you can just have a separate deployable application.
The other cool thing is that if the user is disconnected from the web, if the application is set up properly, he can still run, or they can still run the application. Your icon that you set in the JNLP file, we actually will use that in the doc when you're running your application.
And there is also a preference application for the Java Web Start. It's also in the Application Utilities Java folder. It's called the Java Web Start, and that's what it is. And that has a Java console, just like the applets does. You can manage your certificates in there. And you can also configure, when you launch a Java Web Start application maybe two or three times, what we'll do is we'll actually create one on the desktop for you.
If that's something that you don't want, you can actually disable that in this application. And then, you know, everything will just work. You have to go back to this application to run your Java Web Start applications or click on the link again. And again, there's more information about this tomorrow in the 6.19 Java in the Web, so definitely attend that if you want. So the next one that we're going to talk about is the application bundle.
Now, what this is, is like Matt was saying, is application bundles on Mac OS X are actually folders. And this is actually one of the folders opened up so that I can kind of give you a tour of it in the Java perspective. So the first thing on the list is the contents folder, and pretty much everything goes into that, and that's just the root folder within the application bundle.
The top one, InfoPList, I'm going to come back to that. That's actually the one that configures everything and says where everything is, and I'll go into detail about that one. The next one down, the Java application, which is in the Mac OS folder... What that is is actually a native stub that we use to launch the JVM, read the properties in the Info.plist and stuff like that, and get your application up and running. If you use JARbundler or Xcode, we place that for you. We actually have documentation for where you can get that if you want to create your own bundles or something like that.
Next one, the package info, that's your type and creator on Mac OS X. It's not Java-specific, but it's something that you'll definitely want to look into. And then underneath that is the resources directory. Now, if you've gone to any of the localization talks for Mac OS X, you'll see that, you know, if you have these folders in your resources directory, what'll happen is when you launch your application, we actually look at the international settings of your, in your system preferences, and we kind of go down the list that you have in your system preferences, and when we find a match with one that you have in this folder, we'll actually invoke the JVM with that locale, that font, the keyboard all set up for you.
And so you can actually set up your application so that if you have the fonts and you have dialogues all set up for, say, Japanese or French or something like that, that on somebody's system where they want it to come up in French, it'll just happen, it'll just work in a very Macintosh way.
[Transcript missing]
You just have a single application icon. You don't have a bunch of different icons in a folder, and the end user doesn't have to figure out which file to double-click on. Also, when they move things around, they're just dragging a single application and stuff. And so what we encourage you to do is put everything in that folder if you want, like, C utilities, preferences, et cetera. And I'll be showing you that again. And then, of course, there's the Java application icon. What that is is that's the icon for your application when it's on the desktop. We have a default one that we actually provide for you, and I'll be showing you that.
So this is the info P list, and this is the one I told you I'd be coming back to. So this is the one that actually controls everything for... This is...I mean, it's also system-wide, where you can set, like, your bundle name, your icon, and stuff like that. But inside of there, there's actually a Java dictionary. And that Java dictionary is useful for setting your class path, your main class, your properties, arguments, the main stuff like that.
Now, there's two, I guess, shortcuts or macros that we use in there. The app package, and that is a... when you use this within the info P list within the Java dictionary, that is the path to the inside folder of your application package. So if the person moves things around on your hard drive, you always have a path to it on their hard drive.
So if they decide they don't want this in the applications folder, they want it on their desktop or something like that, it's not...you'll still be able to find everything relative. Now, the Java root, what that does is that actually points to the Java folder inside the application bundle.
And so a lot of times what you'll do is you'll use this on your class path because you'll use Java root slash and then your jars for your class path. And then that way it's always pointing to the Java folder. So the working directory is a key that typically the... When you double-click your application, the user.dir property, your working directory, is just inside the application package. Now, what you can do is set the working directory to the Java root, and that will make it so everything is in the Java folder, like I was telling you earlier, and so you can put your support files and stuff like that.
I'll actually be showing you that in my demo, but I pretty much always set that, but we leave you the option so that if you didn't want to set that as your working directory, you can set it to something else. Now, the JVM version is the next one.
This key is,
[Transcript missing]
And I have a list up here that kind of shows how things would work. So if you only specify 1.4.1, then you would only run on 1.4.1. If you 1.3.1, same thing, only 1.3.1. If, say, you wanted to run in all variations of 1.4, you can use the 1.4 star. And if you want to run on 1.4, 1.5, 1.6, on and on, you could use the 1.4 plus.
[Transcript missing]
is because, say, you have the 131 value in there, and 132 comes out. 131 will no longer be available on your system. And if you lock yourself into 131 or, say, 141, then when an updated version of Java comes out, your application will no longer run. So that's why I have those Xs on there saying, probably don't want these.
So localization, I talked a little bit about this when I was describing the application bundle. In the international panel of your system preferences, you can set your preferred locale and the hierarchy and stuff. And then I showed you the LPROJ folders and the resources. Now, you don't have to actually have anything in those folders.
All you have to do is create the folders, and then we just assume that your application is capable of handling those. Double-clickable jars just get the default locale, so the top one that they have selected in their international preferences. If, say, they have Japanese selected, then a double-clickable jar will automatically be invoked in the Japanese with the Japanese fonts and the keyboard and all that.
Now, the Info.plist, we used to have a property that we would set for your application name in the upper left-hand corner of the application window or the menu bar. But we're actually recommending now that you just use the standard Info.plist bundles CFBundle name. And if that value is set, we'll actually grab that value. The cool thing about using the CFBundle name is it's localizable.
So you can have your English name of your application up in the menu bar on an English system, and then you can have the French or German one on the other systems. And so it all just looks like what they expect it to. Also, if you use the localized CFBundle names, their names will actually change on the desktop to reflect the same thing. So the name in the menu bar matches what's on the desktop.
So Xcode, they haven't been focusing on Java, but they will for the future builds at Xcode. But it still works great for developing and deploying applications for Mac OS X. I use it a lot. And it's got GDB and JDB integrated into it, or a variation of the JDB. And so you can develop native code and Java code in the same application.
We actually have quite a few samples on our developer website that show that. If, say, you want to debug Java and native code at the same time, what people typically do is they'll use the JDB, the Java debugger, in Xcode, and then GDB from the command line. And so that you can attach the processes, and you can actually be stepping through your native code, and then when you code across the JNI bridge, step through the Java code also.
Of course, Xcode has the graphical interface for GDB and JDB, so that's really nice. I mean, I have used the command line version, but this is much easier than trying to remember things. If you have jars that you want to include in your application, you can either have them included in the application bundle within that Java folder, or you can actually have it merge the jars in so you can have just one giant jar in your application folder. And of course, Xcode is available for deploying applications, applets, jars. You can do pretty much anything with it. You can do Java Web Start, but we don't actually have a template for doing Web Start stuff. But of course, you can do any Java or native code.
So, Jar Bundler. I don't have many lines on it, but it's actually a great tool, and I'm going to give you a demo about it. This is our application builder. This is the one that was telling me about if you didn't want to recompile your stuff, this is the application that you'd want to use to package up your application.
One of the things that we have done is if there's a developer that we're very interested in bringing to our platform, if their application is written in pure Java, we'll invite them over for a meeting, and we'll download their Windows application or their Linux version of their application, copy all the jars over to Mac OS X, use Jar Bundler to package it up, and then when we're meeting with them to discuss them bringing their application to Mac OS X, we actually show them to them running on it. It's quite influential when you do that. So, like I said, it's a quick port solution. So, let's go over to the demo machine, and I'll actually show you a version of that.
So, this is Robocode. I downloaded it off the web. It's actually a pretty cool application that after WWDC, I'm going to actually learn to use and write some tanks for. But as you can see, this folder is how on most platforms applications are deployed. And for some people, it's not exactly clear that if you double-click this jar, this is how you launch the application.
So, as you see, it is coming up. We picked the name of the main class for the application name, but none of these properties are set for Aqua. You get the Aqua look and feel, but you don't get the screen menu bar and stuff like that with the jar.
So, let me actually show you how we can package this up and make an application that somebody would expect on Mac OS X. And then we can also add the properties and stuff like that to move the screen menu bar. And do, well, I'll show you all that. So, this is JAR Bundler. This is in the developer tools for the 1.4.1 update. Okay.
and what you can do is say, all right, we know that the main class is in the... is in the Robocode jar, so let's just go ahead and select that jar. It actually picks the main class for me. I think it reads it out of the manifest, and then if not, it'll actually search through there. And there's actually, it searched through and found a couple other mains, but we'll just go with the real one. If there's arguments to main that you want to pass in, you can set these in here.
We, of course, we want the screen menu bar. Simple checkbox, but what this is doing is it's actually setting that property for you that I talked about earlier to use the screen menu bar. And then this is the JVM version. For this one, I'm fully expecting it to work with 1.5, 1.6, and beyond, so I'm going to leave it with 1.4+. Again, if you want to restrict it to this 1.4.x, you can use the 1.4.6. star.
So this sets up the class path, and as you can see, I have the Java root and the Robocode jar. That's how it will be defined in the infop list. If there's properties that you want to add, say like if you wanted to add, say, the brushed metal or something like that, you can add it by using this button right here. You just set the key value and stuff like that.
So the CFBundle name, that's what I was talking to you about, is the localizable property for the application name. We'll just call this Robocode. I'm going to set the working directory to inside the application package, so it's actually inside the jar folder. And then if you want to set the heap size, the maximum heap size, these are all strings for the infop list that are Mac-specific for your type and creator. And... And stuff. So, and as you saw, I'm not using the about menu name property anymore. We're actually recommending people use the bundle name instead. And... So let's go ahead and create this application on a desktop. Robocode. Let's actually put it on the desktop.
And this is going to create a double-clickable application package for you. Now, this package is something that you could just put on, say, a CD or something like that, and they can just drag and stall to the applications folder. Everything, again, is relative to the application package, so wherever they put it, it doesn't matter. Now, what I'm going to do is copy the rest of these files, the support files, into the application bundle.
And using the pop-up, you select Show Package Contents, Contents, Resources, and Java. And let's just grab this all. I'll just replace that same jar that I actually already copied over. So, now, if I had actually written the Robocode application, I would probably know which of these files I actually need and which I don't. But since I didn't write it, I just threw everything in there. And it's not an issue. But if you're deploying your application...
[Transcript missing]
I didn't set the, I didn't recompile it, so I didn't add like a preferences menu or something like that.
So let's go ahead and actually just go ahead and run this thing. And you'll see why I want to play around with this afterwards. And then I heard that there was a way, no, let's go ahead and start the battle. This kind of reminds me of the old Core War game, except it's much more graphical.
Basically, you write applications or little tanks that go around and shoot each other and stuff like that. Now, I'm running on top of the 102 developer update, and you can see that graphics performance is getting much better on Mac OS X. So if you're having any problems with graphics performance, I'd definitely recommend downloading that update from connect.apple.com and trying it out. So that's the end of the demo. Let's go back to the slides.
So where's this documentation that we've been telling you about so that you don't have to write things down? If you go to our ADC home, connect.apple.com, you can actually download the documentation from there. You can also, if you go to developer.apple.com slash java, I try and keep all the web page up to date with the latest documentation that our text pub people put out.
But if for some reason I fall behind, click on the documentation link, and you'll have all their stuff, including their history for the previous releases. There's a great FAQ that Matt maintains, and this... will save a lot of people time if they just read this. A lot of the questions that are asked on the Java dev list, they've already been answered on there. I'd recommend looking at it before really doing any development at all.
Other resources, Enterprise Java on Mac OS X. This is, of course, on the developer.apple.com/java page, but there's also--that's a direct link to where the file is. The ADC developer site, developer.apple.com/java, that's the one I maintain, try and keep up to date for you. And then just the Java developer documentation. Just go to developerapple.com, click on the documentation, and then there'll be a link to the Java stuff.
So what next? Later, we have the desktop and server migration to Mac OS X, Java native integration on Mac OS X, deploying on XServe, and the feedback forum. If you have issues, questions, stuff like that, bring it to the feedback forum. We definitely want to hear all your comments at that forum. All right.
Who to contact if you have more questions, stuff like that. If you have business questions or you're running into issues, you know, you go ahead and send something to Alan Samuel, Bob Fraser. They'll hook you up with the right people, probably with Matt and I. We actually have the page I've been repeating about, the developer.apple.com.java page. That's where, like, if any new updates are posted or something like that, we announce it on that page.
And then this is an invaluable tool, the developer mailing list at list.apple.com, the Java dev mailing list. I keep an archive of every single email on that list. And working in DTS, it's actually kind of funny. We'll get a bunch of questions, we'll get questions sent in that people have answered on that list before. And so rather than waiting for us to answer the question, if people just searched the archive or kept an archive, most of the questions are actually answered on there. When that happens, we just usually send the answer back to the people and don't charge.