Saturday, November 20, 2010

MigLayout - you really should try it

At my new job they used the NetBeans GUI editor to create their panels / dialog boxes. At some point they started to use MigLayout now want to replace all the existing panels. I started with around 220 and now have about 160 to convert.

So why use MigLayout? Why not GridBagLayout or one of the other Swing layouts? My previous job used GridBayLayout for everything even when a very simple BorderLayout would work. I wanted them to switch to MigLayout but it never happened. I have used MigLayout for a few of my side projects and I really like it.

MigLayout Pros:
  • Handles all your layout needs - if you draw it you can lay it out
  • Very simple to learn - string driven
  • Easy to read even if another developer did the initial layout
  • Very concise making for compact code
  • Will handle Mac vs. PC differences in button layout ([Cancel] [OK]  vs [OK] [Cancel])
  • Handles high DPI settings
  • Will handle insets for each OS (also a con, see below)
  • Easily lets you keep a set of controls to be the same size. You can have all buttons in a panel be the same width by putting them in a size group
  • Add special gaps to any side of a control. For some layouts you may want a little extra spacing above or below a control
MigLayout Cons:
  • Handles insets for each OS but the Mac uses large insets with can throw off look and will cause issues if you use setSize in your code for a dialog box. You can override the insets so you get the same look on every OS
  • Since it is string based you will not find out if you typed something in wrong until run time. Of course you are going to run the application anyway to make sure you layout is fine but your code is not validated by the compiler which is something you get used to with the base layouts
  • Another JAR file to include in your download
The Pros outweigh the Cons by a large margin. I have been able to take a screen shot of the current panel, drop it in Paint.NET on my second monitor and quickly type the new MigLayout code just looking at the screen shot. I don't have to sit down and draw out things like I did when I was doing a mix of BorderLayout, FlowLayout, GridLayout etc. I don't have to constantly do a row++ or column++ to add things to a GridBagLayout and I don't have to fill in some big GridBagConstraints object or pass a pile of parameters to a help method to add a component. Really it is as simple as this:

setLayout(new MigLayout("ins 5", "[grow]", "[][grow][]");
add(new JLabel("Enter comments:", "wrap");
add(textAreaScrollPane, "growx, growy, wrap");
add(okButton, "gapabove 10, split 2, aligny right, sg btn, tag ok");
add(cancelButton, "sg btn, tag cancel");

This would be a standard comment entry dialog with a label telling you want to enter, a text area in a scrollpane that grows vertically and horizontally to fill the space and the [OK] and [Cancel] buttons that are the same width right justified in the dialog box. The buttons are tagged so each OS can swap the order if needed. I put a 10 pixel gap above the [OK] [Cancel] button area to separate it a bit from the text area. The "sg btn" just puts them both in the same size group named "btn" you can name it whatever you want and have as may different size groups as you need. This is a tiny example. I have layouts at work with over 50 controls in them, everything is handled perfectly and all of it sizes as the user sizes the dialog box with no problems.

See a bunch of funky numbers in there? See me incrementing rows and columns? Nope, pretty clean stuff. Check out the MigLayout website to find out more. I am not associated with the program in any manner other than being a happy user for many years.

Thursday, November 11, 2010

Objective C is like programming with the dinosaurs

I finally got the HTML / GZIP / XML parsing to work on the Mac. Do you know what the problem was? I was not using the same version of the TouchXML code as the person who did that left. I described some of those issues in the last post.

This morning I downloaded an even newer version of TouchXML figuring that was the issue. It still crashed. I installed Wireshark on my PC and on the Mac. I though maybe the server call was hosed so I looked at the packets and they were fine. That meant it was the code at fault. Another developer and I worked on tracing through things and figuring out the odd way you have to query the contents of variables. If I would have known how to do that earlier I would not have messed with Wireshark.

For me it is hard to fathom why the XCode IDE is so behind the times. It is just not anywhere near as powerful as IntelliJ, Eclipse, NetBeans, Delphi, Borland C++ or Visual Studio. It is not that I am not a Mac guy it is just that I have used a lot of very nice IDEs. Have Mac developers not used other IDEs? Eclipse and IntelliJ are available on the Mac, I have used both on the Mac. They work just as well on that platform as they do on the PC. XCode is crappy. It does not have may hot keys, it does not support tabbed files, it loves to pop up all kinds of windows and the debugger stinks.

I just want to see the contents of my variables but it does not show them even things as simple as string don't show up. I used the GDB window to type "p (char *)[(NSString *)[element data] UTF8String] to see the data in a String! This is just crazy to me. In Java or C# I just hover over the variable and I see the contents. Even if it is just a NSString I still have to do "p (char *)[data UTF8String]. I had some really deep variables and it was a real pain to type all the typecasting to get any data out of them.

The IDE works, the debugger works, it is just a pain to get to your data.

Getting to the actual issue - the debug window was trying to tell me the problem. I thought it was crashing in a method but it turns out the method did not exist. Of course I am used to the compiler telling me with a very obvious compiler error not having this happen at run time in a debugger window. The new version of TouchXML changed from childElements to children and elementCount to childCount. I thought it was crashing in the childElements call getting back 0 elements thus annoying the loop. This is due to Objective C being a dynamic language. Part of my learning experience but man was it an annoying experience.

This is a bizarre situation, I was upgrading by accident as I had no idea what version the original developer used. Normally you would know you are upgrading and when the debugger complained you would spot the problem quickly. I was just happy I was able to get things to compile initially. I thought that meant I had the proper TouchXML code.

Things are not all rosy still. It is giving me back blank strings when I request the "name" for one of my XML items. I will have to chase that down too. Not crashing, just a blank string. No idea what is going on there. Just getting to a variable with no depth is bad but getting to a collection of things is going to be a major hassle. I hope I can find it quickly in the morning. Probably just leads to other issues and I am not going to trust the code until I can run it through all of its paces.

I will check it all in, including the new TouchXML classes tomorrow if I can get the XML strings to display. It is making us wonder if it would have been better to start this application from scratch instead of trying to update the code. That is pretty sad actually. Not something that I have done in other languages in a long time, just punted, unless the code was just super crappy. I think the code is generally OK it is the IDE and the language this is fighting me.

Tuesday, November 2, 2010

Initial iPhone Development Experience from a PC Java guy

At my new job I get to do some iPhone development. Not new development but some enhancements to an existing application. So far it has been a real uphill battle.

First all the code was not checked in to SVN. That meant I could not compile things after the initial check out. Once I figured out you can click on a red (ie bad) file and do Get Info to see where it thought it should come from I was able to figure the missing images. Luckily they were checked in to the build directory - not that the build directory should be in SVN but it was. The other files are part of TouchXML. I figured that out using Get Info and was able to locate the files on the web. Then all the frameworks links had to be updated as it was originally done with the 3.1 SDK but I have 3.2 and 4.0 installed on the Mac Mini I am working on so I had to point to newer versions.

First I copied the TouchXML files into the ExtraLibs directory as was suggested on the web but figured that was not really optimal for others to use and get from SVN so I moved them under the project. If we do more than one iPhone app that needs to share them we will move them into a shared project but there are no plans to do that at this time.

Next up was figuring out the xCode IDE. It does not appear to be as full featured as Eclipse or IntelliJ. All the basics are there but it seems to be missing some of the advanced things I am used to like multiple open files in tabs and hot key support for various actions. The keyboard actually drives me bonkers. I have a regular PC keyboard hooked up so at least I have a full set of keys and don't have to press extra FN to get to things I use on a regular basis. Pressing HOME - which I expect to go to the start of the line - takes me to the start of the file. I know, I just need to learn Mac keys but old habits are hard to break. I also have to press the Windows Key a lot to do things. Getting the hang of that.

I was able to get the program running in the debugger once I got all the libraries / frameworks linked properly to the project. It would run but accepted no mouse or keyboard input. I finally figured out I was running the emulator in iPad mode. Switching to iPhone mode and it worked. I thought iPad was just a big iPhone, sure app would maybe look ugly but should run. This is not the case. Don't have time to figure that out right now. It is my understanding the last build for the original developer works fine on the iPad. The IDE keeps switching back to iPad mode though which is really annoying. When I start it up to a rectangular emulator I know it is wrong, shut it down, change the target and start it up again.


Once you are familiar with the Android on screen keyboard the iTouch one seems really limited. All keys show as uppercase on the keyboard, the only way to know you are in uppercase is to see glow around the Shift Arrow. Keys only do one thing so you have to switch to symbol mode to get numbers and another mode to get some symbols. On the Android you can just hold down on a key and get to the associated symbol. Plus I love Swype now that I have started to use it. Finally the keyboard on the iTouch totally covers up where I am typing so I can't even see what I am entering and there is no Next button so I have to type then press ENTER then press on the next entry field and type. Data entry, which I have to do for user name and password really stinks. I have an iTouch at home and have used it a lot in the past. After using my Android phone I am much happier with it for data entry. Personal choice.

I finally got it to log in but now it crashes processing some XML data from my HTTP request. The data is coming back in GZIP format, because that is how I asked for it, but I don't think it is getting converted to plain text. I am in the bowels of code trying to figure that out. Maybe the TouchXML handles it or maybe some other code. I could be I got a newer version of TouchXML. The original author is not at the company and no one else has worked with this code. I don't know Objective C and have not worked on the Mac much so I am pretty handicapped at this point. It is a challenge.

For me the whole Android configuration was much easier and since I already know Java I could get up and running pretty quickly. I also knew Eclipse and the PC keyboard allowing me to start typing and experimenting right away. I started on a clean app so I could learn at an easier pace. Finally I did not get tossed a 3rd party library right at the start which meant I could write tiny bits of code and to see what happens without the worry of multiple frameworks in my way. And I comment my code, none of the iPhone source for this app is commented and it is not using iPhone standards for naming conventions making it extra fun.

The app is working on the iTouch. It is the code from the original author. I don't know if my build will run on the iTouch and it is just the emulator that is screwy. I can't put my code on the iTouch as I don't have the signing certificate set up yet. This was a fresh install of the development environment. It is nice the Android does not care about signing for you to run and debug on your device. Maybe the iTouch does not either, just seemed to be annoyed without that set up during my initial attempts. I need to get that working to see if I have to run that way for things to work but I also hate to kill the one working instance I have of the application.


Interface Builder (IB) is also another new area. Since the iPad version was not working I thought maybe some of the event connections got broken and I decide to hook them back up. They were not broken but I did learn a bit about IB while trying to figure that out. I also saw some on the net needed to remove / re-add connections to make things work so I went through that whole experiment. Threw me off when hitting the (+) button did nothing. It is a dragging starting point and not so much a button. You drag over to your classes and it will pop up things you can connect to. All makes sense once you know what to do.

I will say I was a bit surprised at all the information I could find on the Web. I was under the impression that Apple was keeping a lot of information under lock and key. The whole programming on the iPhone was supposed to be shrouded in mystery. I did not find that to be the case. Pretty much anything I did a search on via Google popped up numerous results with quick answers. My misconception probably came from a few years back when a lot of the SDK talk was NDA making it hard to publish much without raising the ire of Apple.

SVN support in xCode seems workable but again does not work as it does in a lot of other PC based IDEs. I was finally able to check in code - mainly the missing files - but it took some doing. I think part of the issue was the build directory files being checked in which annoyed SVN on both the PC and the Mac side of things. There were temp files with ~ in them which SVN does not care for in the least. I cleaned it up using TortoiseSVN on the PC then the PC and Mac both worked. There just are so many more free tools on the PC to get things done in this area and again I have used them in the past. It was easy for me to quickly give up on the Mac, do it on PC and move back to Mac to move forward on the app again.

Am I saying the Android development environment is totally superior to the iPhone or the PC is better than the Mac? No, I was more familiar with everything about the Android environment - IDE, Windows and Java so it was easier for me. Not being a Mac person I am learning a whole new way of looking at things. I am not saying right or wrong, just different and difficult at this stage. I have learned enough programming languages and frameworks in the past that I figure I can get up to speed in a reasonable amount of time. I will learn the keyboard, various short cuts and all the cool stuff you can do with Interface Builder, xCode, Objective C and the iPhone SDK. Right now I am in the newbie struggle mode but I will enjoy the challenge and hope to find many things on the Mac that I miss on the PC.

Maybe I should port my Android game to the iTouch which would give me a balanced picture of development on both sides. I will have to wait until we give the Mac Mini to QA at work and I start using a Macbook for my iTouch development so I can do that conversion at home on my own time. Of course I still have some performance and other tweaks I want to do to my Android version and I would like to finish them up first but starting a new job has meant I am mentally burnt out by the time I get home so final touch up to a game is really not high on my list. Making money from a game is so I should push myself...

Monday, October 18, 2010

My first Android app - 18 things I learned

I have written my first Android application. It is a game and it works pretty well on my phone and the emulator. I still want to tweak the sound effects to match the themes and to maybe add a two player mode. Then I will have to decide how to release it on the market. I could go with a lite free version and a small charge paid version or I could go with an ad supported free version. Leaning toward the ad supported free version at this point.

For this discussion the actual app does not matter. I want to cover what I learned. First off I have been programming in Java for a number of years so this is not about Java programming.

1. If you know Java then Android programming feels pretty natural but there are enough differences that you can't make assumptions. I got burnt more than once.

2. Setting up the environment took more than I expected. Everything is out on the web and I was happy to find a lot of on-line support no matter my question. What took a bit was a lot to download for all the Android flavors from 14. to 2.2. I had a little issue finding the proper USB driver so I could debug on my actual phone.

3. Running directly on the phone is faster than using the emulator. Plus it really shows the experience as you use your finger instead of a mouse. When you drag small things around with the mouse they are easy to see, not so much with the finger. The emulator is pretty solid. I did not find differences between what the phone did and what the emulator did.

4. Eclipse is a really nice IDE. Drop files into the drawable directory and they show up as resource IDs automatically. It does have some issues. It did not install the app 100% of the times when I pressed the run button. Could be the phone's fault. I was not totally consistent in swiping to unlock and getting ready to run. I also had the IDE pause when using intellisense, very annoying.

5. The UI does not stop running when you show an alert dialog. Something you get used to in Swing. Not a big deal, once you know that you just code with it in mind and it does make sense. You don't want to freeze the UI waiting on the user.

6. Rectangle is left, top, right, bottom instead of x, y, width, height. Just something to remember. 

7. Checkbox uses isChecked and setChecked. I had code to do isSelected and setSelected. The code compiled but did not do what I expected. Made an assumption. Never understood why Swing did not use the properly named methods. Glad Android does.

8. There is no Combobox but there is a Spinner. When I think Spinner I think numbers but the Android Spinner does the work of the Combobox and it does it just fine.

9. Strings belong in string resources, not in your code. I am familiar with this as the Java code I have written has been internationalized. Of course I was not doing that by default, I was hacking together code to make it work but in the end I moved all the strings into string resources.

10. The canvas is pretty powerful. All the features I needed were supported and well named.

11. Not all phones are equal. Different screen resolution being the big one. I have a new phone so I have a big screen. I set the emulator for a smaller screen. I need to tweak the code even more to fit as many screens as possible and to not leave dead space on big screens.

12. You have to draw a lot of icons. I had an icon in my drawable directory but it was not the one I would see on the phone. I had to drop special sized ones in each of the drawable directories to have the proper one to show up. Even at that the proper one only showed up under applications. I had put a short cut to my app on one of my screens but that icon did not change during the next app install. I had to remove it and re-add it to the screen to get it to change. Icons are not a standard Windows size - 256x256, 128x128, 64x64 but are 72x72, 48x48 and 36x36.

13. Playing sound is easy but they don't always play to the end. I need to figure out why that is happening. The API is really straight forward.

14. The amount of on-line information is impressive. The official Android help pages are a great starting point then I would use what I found there to find some solid example code. I was always able to find what I needed with minimal searching. 

15. The preference system is simple. I needed to save the sound, flashing and theme settings. Find a quick sample and 5 minutes later it was in place.

16. The options dialog was harder than I thought it should be. This seems like something that nearly every app will need so I thought there would be base classes to handle it. I found what I needed on the web but I can see where we will not see standardized dialogs.

17. I love the menu button, something I wish the iTouch had, but I had to dig around to find images for that area. These images tend to be gray scale with an indented look. Not typical color icons. I wanted to stay consistent with t;he Android look so I found where they are hidden in the SDK samples.

18. I was worried the game would take a long time to write but I got it done in a few days. I had the game running in Swing so the engine was ready to roll. I took the game to a new level with themes and greatly improved graphics. I also put in a help system using a basic alert dialog. I never did a help system with the Swing version as I did not want to learn RoboHelp or some other HTML based help system. I really could have cheated like I did with Android, just never push myself to do it.

All in all I am very impressed with the Android platform. I am late to the game so others have done the hard stuff and published a ton of code samples for me to use. It appears the SDK team learned from various Swing mistakes and weirdness producing a cleaner API. I am sure I forgot a lot of other things I learned, this is just my first Android app and I don't consider the app done. It is fully functional but like any piece of art it never really feels done. I will have to choose a stopping point and release it one day.

Monday, October 4, 2010

I now own and Android phone

Various things came into play but I decided to buy an Android phone. I have the Samsung Galaxy S via T-Mobile, which was my current carrier. First, my son is doing a lot of things with Boy Scouts so he has needed a phone while out in the neighborhood selling popcorn, trash bags and grocery store coupon books. He has also had to borrow others phones numerous times to get hold of us after camp outs.

Second my wife calls me to get web information while she is out and about. Mainly phone numbers and addresses. She has an older BlackBerry but with the new data plan it also gets web access.

Finally I am going to get to do some coding on a project for the Android and just using the emulator seemed like not the way to go. You always want to run on the real hardware if you have the chance.

I have an iTouch so most of the operation is very familiar. Still learning all the ins and outs. Seems to be a solid phone, very fast and I am happy with it so far. Nice to have the web in your pocket all the time. I was able to monitor NFL scores while out shopping yesterday.

Wednesday, September 29, 2010

Internationalization in Java - when is a number not a number?

The Java product I work on is internationalized and localized - well it turns out for the most part. I updated the code some time back to allow the user to type in numbers in their locale so a German speaking user can type 600,25 (notice the comma instead of a decimal point) and we should consider that to be 600.25 in English.

Two problems arose, the masked entry field I wrote handled this just fine allowing user to type in numbers using their locale settings but the code in others areas converted the typed text to a Double using Double.valueOf(text) and it would fail by tossing and exception. I switched the code to NumberFormat.getInstance().parse(text), adjusted to catch the proper exception and everything now works. This code area allows users to enter custom property values.


One thing I found out, NumberFormat returns a Number. That might be a Double or a Long. If you parse 85 you get a Long. If you parse 85.43 you get a Double. You can ask the Number for its doubleValue if you always want the double. I was getting a typecast error on occasion until I figured this out. If you send in an empty string you get a parse error. You may want to check for that before you parse to assign a default value of Double.MAX_VALUE to indicate empty or 0 if you want empty strings to equal a zero value.

Second problem came from the advanced search area where we allow users to search for previously entered data. We used the same masked entry control but never converted the output to a number. The server takes the search statement as a string so there seemed to be no need. Of course there is a need. The code looks a bit silly but I take the text, convert to a number and convert back to text so it will be in English format to send to the server.
String numOne = numberFieldOne.getText();

// We convert to a number then back to text for i18n reasons
// All numbers set to server in English format, this forces that rule
try
{
   numOne = NumberFormat.getInstance().parse(numOne).toString();
}
catch (ParseException e)
{
   numOne = numberFieldOne.getText();
}

Everything is up and running again. The company has a big push toward international expansion so it was critical that we solved these issues. I must say Eclipse pop-up help on methods is very handy. I viewed the pop-up for Integer.valueOf and it suggested using NumberFormat instead. I love it when you are handed the answer without needing to do a web search right from the IDE.

Converting existing code to i18n can be painful, making it i18n from the start and keeping it that way can be a big help. I will add this discovery to my i18n toolbox. Seems pretty rare for users to type in floating point values but it does happen and you need to account for it.

Monday, September 27, 2010

Why does Java paint different under different Mac browsers?

I understand there are differences between Java on a PC vs. Mac vs. Linux. We have code in place to check for each. Even some code for OS subsets such as some special code for Win7 and Vista vs. older Windows flavors. They added fancy pants painting to the combobox in Vista so my custom control paint needed to reflect those changes.

What gets me is I can run our applet on my PC under Chrome, Firefox, IE, Safari or Opera and it looks the same. All the colors match, buttons look identical, my custom controls paint exactly the same. I can see no differences.

Today I get a few bugs about things not painting correctly on the Mac. No big deal, I grab the development team's laptop, update the OS, update Java and install latest versions of Safari, Firefox, Opera and Chrome. Run Chrome as my testbed and fix the items reported by QA. Just an hour or so of pretty easy work. Then I decided to run the software to see if I spotted any new issues and I found some with toolbar button painting. I resolved those under Chrome then ran it in Safari. Background is a lot darker over the main toolbar but buttons are readable. Then I run it under Firefox and when you have a toggle button on the toolbar you can not tell which button is toggled. It gets a special outline and color in Chrome, Safari and Opera just not Firefox.

Safari on Mac
Firefox on Mac

The three right most green buttons are a toggle group, only one will be selected. They are fit to screen, fit to width and fit to height. On Safari you can clearly tell you are in fit to screen mode. Under Firefox you have no idea.

According to the Java console window that pops up as I run Java in each browser I am running JDK 1.6 update 20 in each one. I am not using any special paint code for this button, just using standard JToggleButton. I did not touch code in this area for my other bug fixes. I run an older version of our applet and it still looks bad in Firefox. Why does the JToggleButton paint differently in a JToolBar between browsers? Why is the browser controlling the background color of the toolbar in some cases? This is not how WORA is supposed to work. Of course I know WORA does not work between OS vendors or versions but I did not expect the browser to mess me up.

My other Mac bug was about things painting outside the custom control. On the PC in Java if you set a clip region outside the control you are currently painting it still gets auto clipped to your control. It was a simple fix, I just did an intersection between the current clip and the rectangle I was about to paint thus if it was out of bounds on the Mac I did not paint where I should not be painting. No Mac check, worked fine on PC with the intersection check. I did add a comment as to why the clipping is there and really it is the most legal way to handle things but it was the Mac that forced the work back on the developer, not saying the Mac was wrong, just the PC Java was friendlier.

We need to test more often on the Mac. It is an important platform. We have clients using it. Stinks that I have to dig down this deep to fix things and now I have a new problem between browsers that I am not sure how to even fix. Has anyone else run into the JToggleButton paint issue?