One of the downfalls of Java is that when you are starting out, there are some concepts you need to learn before you're interested in them. Making buttons do something useful when clicked has some such prerequisites, so we'll start with these.
An interface is one of Java's equivalents to a contract. A barman fulfills the contract of serving me a pint.
Java's way of expressing this contract looks as follows:
public interface Barman
{
void servePintTo(Customer customer);
}
What this means is that anything that claims to be a Barman must have an implementation of the method declared there (servePintTo).
Here is a sample thing that claims to be a Barman:
public class AlMurray implements Barman
{
public void servePintTo(Customer customer)
{
System.out.println("A Random Joke");
System.out.println("What am I doing?");
System.out.println("Oh, yeah, serving you a pint!");
customer.receivePint();
}
}
A real example of such a contract, or interface, in Java, is ActionListener. An ActionListener is something that can listen to ActionEvents, in other words, to clicks on buttons and menu items (and a few others, but buttons and menu items are the important ones). Anything that claims to be an (implements) ActionListener can be used as an ActionListener. The ActionListener interface looks like this:
public interface ActionListener
{
void actionPerformed(ActionEvent event);
}
And this is a simple implementation of an ActionListener:
public class SimpleActionListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
System.out.println("Woah, something happened!");
}
}
Let's get this going as a working program! As usual there are some errors in the code, try to use the compiler output to help debug it.
public class Main
{
public static void man(String[] args)
{
JFrame frame=new JFrame();
frame.setSize(400,400);
frame.setLayout(new FlowLayabout());
JButton button=new JButton("Click Me!");
frame.add(button);
SimpleActionListener listener=new SimpleActionListener();
button.addActionListener(listener);
frame.setVisible(true);
}
}
And in another file, called SimpleActionListener.java:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class SimpleActionListener implements ActionListener
{
public void actionPreformed(ActionEvent event)
{
System.outer.println("You clicked!");
}
}
For more information on interfaces, see the interfaces tutorial as part of the Java tutorial.
Often, from an ActionListener, you'll want to do something with the original objects, but we can't access the variables that we declared in the Main class from outside the Main class. There are a few ways of getting around this, and here's one:
Add some fields (variables declared outside methods) to the ActionListener, and set them to hold the same value that the variables in main do:
public class LessSimpleActionListener implements ActionListener
{
public JFrame frame;
public JButton button;
public void actionPerformed(ActionEvent event)
{
button.setText("Clicked!");
frame.setTitle("Well done");
}
}
So here's the code that would go in the main method, to use this:
LessSimpleActionListener listener=
new LessSimpleActionListener();
listener.frame=frame;
listener.button=button;
Everything else is pretty much the same. Try to get that working.
When you have it working, try taking out either of the lines "listener.frame=frame" or "listener.button=button", then run it again. Take a good look at the output you get, and understand why you get it. If you don't, read the following tutorial: http://tmorris.net/pubs/npe/. We'll come onto some ways of stopping yourself from making this error by accident sometime. It is probably the most frequent runtime error that programmers make, especially new programmers.
The easiest way to make multiple buttons/menu items have ActionListeners is generally to make multiple ActionListener implementations. Here's an example of setting up a menu with a couple of different ActionListeners (with errors!):
public class Main
{
public static void main(String[] args)
{
JFrame frame=new JFrame();
frame.setSize(400,400);
JMenuBar bar=new JMenuBar();
JMenu fileMenu=new JMenu("File");
JMenuItem exitItem=new JMenuItem("Exit");
FileExitListener fileExitListener=new FileExistListener();
exitItem.addActionListener(fileExitListener);
fileMenu.add(exitItem);
bar.add(fileMenu);
JMenu helpMenu=new JMenu("Help");
JMenuItem aboutItem=new JMenuItem("About");
HelpAboutListener helpAboutListener=new HelpAboutListener();
aboutItem.addActionListener(helpAboutListener);
}
}
In a separate file, FileExitListener.java:
public class FileExitListener implements ActionListener
{
public void actionPerformed()
{
System.exit(0);
}
}
In a separate file, HelpAboutListener.java:
public class HelpAboutListener implements ActionListener
{
public int actionPerformed(ActionEvent event)
{
JOptionPane.showMessageDialog(frame,"This is version 0.001 of a very basic program");
}
}
Note that you'll need to look back at the concepts from earlier today to make that last example work.
To make more useful interactive applications, you'll probably find that you want to read text from text fields. If you have a JTextField variable, and it isn't null, you can get the text from it using theVariableName.getText(), which returns a String.
To set the text on it, use theVariableName.setText("Some text");
Another common problem that crops up here is converting a String (such as that from a JTextField) into an int (such as for maths). Google is very good when it comes to such things: Google for convert string int java
If there's anything you want to know, don't hesitate to use Google, or to contact me (if I don't know the answer I'll probably use Google anyway).
The concepts explained today are probably the hardest that you'll learn for the next few months, so try to get to grips with them. Applying them will be the fun bit.