Making your own GUI apps

calc-2_16x9

Over the last few articles, we’ve had a bit of fun coding up a number of games in Java from basic WWII arcade flight simulators to codifying ancient semi-electronic handheld driving games. But chances are you’ll also want, or be asked, to code up something a little more serious.

Making your own apps with a graphical user interface (GUI) is a fundamental part of any coder’s armoury, and in Java, it involves understanding the Layout Managers.

And to keep things practical, we’ve come up with a simple Home Loan Calculator to explain how it all works.

You can find the source code here. Unzip the file, load up the inner zip file straight into NetBeans IDE (File, Import Project, From ZIP) and run it. You can download the NetBeans IDE/Java development kit bundle for free from this website.


WARNING

This story contains information about home loans but is provided for example only. Do not use this information as financial advice, but always seek out a financial advisor or your accountant before making any important financial decisions.


Border, Flow, Grid

One of the key factors in any GUI app is presentation — the user interface can often make or break an app, even if the app’s functionality is first-class.

To reduce the complexity, Java has its own Layout Managers to take care of GUI component layout automatically. You tell Java which type of layout you want, add those components to the frame or panel and Java does the rest. Well, sort of, as we’ll see shortly.

Java has three types of layout manager — BorderLayout, FlowLayout and GridLayout.

borderBorderLayout divides a frame or a panel into five compass-like regions — north, south, east, west and ‘center’.

When you add a component, you tell Java the region where that component should sit through constant values such as BorderLayout.CENTER or BorderLayout.NORTH.

Of the five, the centre region is the only one that expands to fill any empty space within the frame or panel — the other four only take up as much space on the edges as required.

flowFlowLayout is a bit different. In fact, pretty much all it does is run your GUI components together from left to right across the panel or frame. Any component that does fit on a row flows on to a new row.

What you can do with FlowLayout is decide whether to align GUI components to the left, centre or right of the panel or frame.

gridGridLayout is different again — here, you divide the frame or panel into an x-y matrix.

But rather than tell each component which matrix cell it belongs to, Java just fills in your components from left to right, starting at top-left, until the row is full, and then it starts on the next.

These options might sound a bit primitive, but when combined with the ability to nest panels within panels, you can get some decent-looking GUIs happening.

However, coding GUIs manually in Java can be time-consuming, which is why WYSIWYG-style GUI designers have appeared, like WindowBuilder for Eclipse and NetBeans’ own Swing GUI Builder.

designerBut as a code-learning tool, there are two schools of thought; one, that GUI designers are great for newbies because they make it easier to create apps without learning too much code; and the other, that you learn better by doing things manually to start with and keeping the GUI tools for when you know what you’re doing.

One factor worth considering is that not all auto GUI designers produce the neatest of code – and if you have to debug that code at some stage, your own code may be easier to follow than auto-generated code you may not have seen before.

Another issue, relying on a particular GUI designer can make you IDE-dependent. If you change jobs and you need to change from NetBeans to Eclipse, being locked into NetBean’s GUI designer might be a problem.

Home Loan Calculator

calc-1With home prices going nuts over the last couple of years, we thought a quick home loan calculator would be a useful and practical way of bringing all of these concepts together.

The idea is that you enter in the loan amount, loan start date, annual interest rate, loan term, the number of payments per year and an optional per payment amount.

Click the big Calculate button on the top-right and the app goes to work, churning through the numbers to create a payment schedule underneath. Finally, it calculates the actual payback period, total amount and total interest you’ve paid.

The new GUI component in this app we haven’t looked at before is the JTable. JTable is Java’s table container, but the actual data gets stored in a ‘TableModel’ interface object, the code for which looks something like this:

DefaultTableModel dataModel = new DefaultTableModel();
JTable table = new JTable(dataModel);

We create a DefaultTableModel object called ‘dataModel’ and it’s attached to the JTable object called ‘table’. The trick to remember is that you add data to the ‘dataModel’ TableModel object, not the ‘table’ JTable.

Calculating the home loan

formGetting back to the app, this gives us another chance to use Java’s Math class and its Math.pow function.

Home loans are calculated using a well-known amortisation formula shown here. They traditionally work on a basic roster of 12 monthly payments per year and either a 25- or 30-year loan term. Enter all the numbers into the formula and you’ll get a base payment per month.

For example, a $350,000 loan over a 25-year term at 4% per annum with 12 monthly payments per year works out to $1,847.43 per month.

whileOut of that payment, the first thing you pay is the interest and that’s calculated simply by taking the loan amount and multiplying it by the interest rate divided by the number of payments per year.

So on the first payment of our example, we’re paying $1,166.67 in interest and the remaining $680.76 of that payment goes towards the loan amount, so that we now only owe $349,319.24.

This process continues every payment until the loan amount is zero.

The app just mirrors this process, using a while-loop to run through each payment period, adding the repayment details to the table until the loan amount is zero.

Paying off the loan faster

Over the 25-year loan term, we’ll end up paying $204,228.68 in interest. But one of the simplest ways to reduce that is by cutting the monthly repayment in half and making fortnightly rather than monthly repayments.

Do that and the loan period drops to 21 years and 10 months and the total interest to $175,371, saving just under $29,000.

Now we’re not financial advisors or accountants, so don’t make any decisions based on this information. Always talk to your bank manager or financial advisor before making any important financial decisions.

But mathematically speaking, what’s happening here is that, by paying fortnightly, you’re making 26 payments a year or the equivalent to 13 monthly payments instead of just 12. That extra payment lops off that bit extra from the loan and you pay it off that little bit sooner, saving you interest.

The point of the app is you can muck around with the numbers, press the Calculate button and recalculate the repayment schedule with new totals. The app is also designed to automatically choose the larger of either the default monthly payment or your chosen payment.

What the app doesn’t do

Now as we said, this is only a quick, simple app and it doesn’t take into account any fancy extras, such as fixed interest periods — that can be added but we’ll leave it for you as an exercise. There’s also no save option, but again, we’ve covered this before, so it’s not difficult to do.

App layout

layoutThe way we’ve laid the app out is through a series of nested JPanels.

The base is the standard JFrame, which is given a standard FlowLayout, but to have the labels all appear neatly arranged, we’ve added a number of JPanels, each using a mix of GridLayout and BorderLayout managers.

Looking at the Loan Details section of the user interface, that whole section is a JPanel called ‘panelInputs’ that has a BorderLayout.

The JLabels down the left-hand side exist in another JPanel called ‘panelLabel’, but here, we’re using a GridLayout manager with the grid arranged in a seven-row matrix.

The ‘panelLabel’ panel is then added to the ‘panelInputs’ panel with a set position of BorderLayout.WEST so that it’s on the far-left side of the panel.

We then create another JPanel called ‘panelField’ with the same seven-row GridLayout and add in the JTextFields the user enters the data into. This is also added to the panelInputs panel but set to BorderLayout.CENTER.

Finally, we add the Calculate JButton to panelInputs and point it to BorderLayout.EAST, so that it’s on the panel’s far-right hand edge.

Next, we create the JTable. Using the ‘addColumn’ method, we add the column headers to the table. We then set what’s called the ‘ViewPort’, or its viewable screen size.

The last thing we do here is attach the table to a JScrollPane called ‘scrollpane’ — what this does is that, when the number of table rows exceeds the viewport size, Java automatically adds vertical scrollbars on the table’s right edge to allow you to see the hidden rows.

To finish off the GUI, we create another JPanel called ‘panelTotals’, which houses two more JPanels for labels and textfields displaying the totals at the bottom of the screen.

Click and clear

The JTextFields at the top have in-line instructions, but click inside them and the instructions disappear.

This is done by attaching an addMouseListener to each JTextField, so that whenever the textfield is clicked, any text is removed by simply setting the setText() parameter to empty.

Calculate dates

dateTo get calculations started, we attach a custom ActionListener to the Calculate JButton called ‘MakeCalcListener’ and as soon as it’s clicked, the getStartDate() method is launched.

One of the things Java standard-edition (SE) doesn’t do as well as it could is work with dates. It’s not bad, but it could be better.

We want to create a payment schedule with dates of each payment, beginning with the loan start date and calculating them right through the loan term. To do that, we parse the loan start date the user provides and create a Calendar object of type ‘GregorianCalendar’, which is the standard calendar most of the world uses.

What’s important about the Calendar class is that it makes it very easy to add days to a date and get the new date without having to manually calculate ends of months or leap years. The ‘getStartDate’ method turns the user supplied start date into a Calendar object.

It’s then used in the statement:

calLoan.add(Calendar.DATE,(int)(365/paymentsPerYear));

Here, we take the current date value of the ‘calLoan’ Calendar object and add in the number of days between each payment. The Calendar object allows you to obtain the day, month and year as separate parameters and use them as you will.

The only trick is that month values start from zero, so January is 0, February is 1 and so on. Calendar also can’t subtract one date from another, which would have been nice.

Make your own GUI apps

guiProbably the key thing to take away from this is that there’s no perfect way to make a GUI — really, it’s whatever works. Developing a decent GUI is an art form that involves combining the functional with the aesthetic.

One of the best ways to learn is by looking over your favourite apps with a critical eye — look at how the GUI components are arranged, how they’re grouped and where they’re located. Ask yourself if there’s a better way that this could have been done.

One of the best forms of feedback is from users you hope will use your app. If they can work out how to use your GUI with minimal assistance, chances are you’re heading in the right direction; for in the end, that’s what apps are all about.

You can have the best, most functionally brilliant app in the world, but if the thing is too hard to drive or looks like the dog’s breakfast, it won’t be as successful as it could otherwise be.

I wouldn’t call myself an expert, but GUI design is a highly valuable skill, as critical to successful software implementation as any class, function or method. It’s something every software engineer should appreciate.