The main idea I didn't get from the Sun tutorial.

Okay, so I’m comfortable with Visual Basic’s program setup. (A main form + a bunch of modules to hold your functions.) What I didn’t understand in the tutorial on the Sun website was how the pieces fit together. Say I wanted to make a basic calculator program with a swing UI. Would I have a bunch of .java files for each object/class I make? Where would I call these methods, tell the program to run some on startup or event handling code? As of now I can write some decent object code but I have NO clue how to make them work together. Thanks for any help.

I’m not sure I understand your problem but the starting point of each application is the main method. From there, you can create new objects and call methods. For example, to create a basic window in swing, you could do:


import javax.swing.JFrame;

public class Example extends JFrame {

	public Example() {
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setTitle("Title of the window");
		this.setSize(800, 600);
		this.setVisible(true);
	}
	
	public static void main(String[] args) {
		new Example();
	}
}


The main method creates a new Example object, which is a JFrame. This code would be in Example.java. Each .java file holds one class so if you make several classes, you’d have several .java files. I’d search for some Swing tutorials on event handling, they should describe how to handle events with event listeners and such.

For example, to respond to an event when the user pressed a key, you can create a key listener (in ExampleKeyListener.java):


import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class ExampleKeyListener implements KeyListener {

	public void keyPressed(KeyEvent e) {
		System.out.println("You pressed: " + e.getKeyChar());
	}

	public void keyReleased(KeyEvent e) {
	}

	public void keyTyped(KeyEvent e) {
	}

}

which can be added to the window:


import javax.swing.JFrame;

public class Example extends JFrame {

	public Example() {
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.addKeyListener(new ExampleKeyListener());
		this.setTitle("Title of the window");
		this.setSize(800, 600);
		this.setVisible(true);
	}
	
	public static void main(String[] args) {
		new Example();
	}
}

In this case there are two .java files: the Example.java file which holds the code for starting the program (main method) and the code for the window, and ExampleKeyListener.java which holds the code that happens when the user presses a key. The same idea can be used for other events, like when the user moves the mouse or presses a button.

Basically, you can create an object when you need it and then call some methods or give it as a parameter. In this example, I created a new ExampleKeyListener object and I gave that as a parameter to addKeyListener. So, in your calculator, you’d have some buttons on the screen and each button could listen for a button press and then update the internal state of the program, like adding a number or so or displaying the result of the calculation.

That was actually the exact answer I was trying to get. :slight_smile: Thanks! So upon compiling those two .java files, I’d tell Netbeans (for example) to compile as I would anything else since it puts them in the same package when I make them. right?

Oh also, assuming I make a class to handle the calculations, I can call methods from it in other objects, right? It doesn’t have to be the one with the main?

i.e. in the event handling class, I can tell it to, instead of printing out a line, to look to say…calc.java to call calc.add? Or do I have to call new calc() first?

I would just fiddle and test all this myself, but I’m at work right now and I don’t think these computers have the SDK.

Yeah, you should put them together in the same package and after compiling both of them, you can run the program. I don’t have experience with NetBeans but I assume it works just the same - as long as they’re in the same package it should work (this is not required though since you can also import classes from other packages but you get the idea I think).

If you’re just starting out in java, it’s generally not a good idea to start with a big IDE like Netbeans or Eclipse. Start with notepad and the command line first, then progress to the bigger IDEs when you actually understand what’s going on under the hood.

hm, I’ll try that. I need more practice navigating with cmd anyway. I doubt I’ll deal with Swing much right away if I’m doing that, but I can still import the swing libraries as usual if I wanted to, right?

No it doesn’t have to be the one with the main, but remember that main is where your program starts. Assuming you have a class for calculations called Calc, you can call Calc.add only if add is a static method, otherwise you need to call new calc() first.

example:


public class Calc
{
    //can be called without creating a new Calc object
    public static int add(int num1, int num2)
    {
        return num1 + num2;
    }
    
    //cannot be called without creating a new Calc object
    public int add(int num1, int num2)
    {
        return num1 + num2;
    }
}

Hope that helps.

Oh, and instead of notepad and cmd, I would recommend textpad, it has basic syntax highlighting and a little compile and run tool, but doesn’t have extra features and such to confuse you.

I believe it is a good idea to start easy and later on jump to Eclipse/Netbeans.

I did not; I started out with Eclipse. Before I knew any Java. Needless to say, I was (am) confused, but I learned a lot by the actual IDE. Like trying to make a static call to a non-static method. I tried to do it, it said it wasn’t possible and I figured “aha! this is when to define a method as static!”. Thank you Eclipse.

But yes, I agree with them. Start easy.

I tend to disagree. On the commandline you may get more insight how the toolchain works, but for starting with swing development, nothing is easier as having a form designer and a “play” button to start your creation. Not to say that you get assistance to solve common errors like missing imports, which really helps when starting.

Yeah, when I started with Java we had to use Eclipse or JCreator as IDE… an IDE helps with development but it’s important to realize that you shouldn’t simply pick the first option in the help menu when a syntax error occurs: you really have to know what you’re doing otherwise you’re simply screwing your code just to let it compile. The IDE can assist but it can’t think for you.

Can everybody PLEASE stop extending JFrame?

It’s a major screwup in design when you think about it.

Do you extend a HashMap when you use it, too?
(A really bad teacher I had this year honestly insisted on extending the HashMap for every use… oh well)

.

Well, it’s a common way to do things in swing. In Netbeans it’s actually the only way to use the form editor. And despite extending HashMap, it makes sense in some ways, since you are creating a visual component, that could theoretically be reused. Having said that, I am not really glad, how such things work in swing. Encouraging composition over inheritance and interfaces to form a component would be better. But this is off topic here.

You should do a few simple examples and compile them with the command line first.

But I think that you’re better off with an IDE after that. When you do something wrong, it will tell you that you’re doing something wrong before you compile.

If you do want to use a regular text editor, I would recommend Textpad. It’s free and very convenient. It’s highly configurable, but the most important thing is that you can have a document selector window.

Textpad works well when you’re writing small-medium size programs, but it’s doesn’t scale up well when you’ve got hundreds of Java files spread out through alot of packages. I used Textpad for quite some time, but using a real IDE like Eclipse is much better.

I don’t want to expose hashmap in 99% of the cases that is why it doesn’t make sense.

JFrame is not so bad in most cases that I have seen it used. It still allows me to for example embed your application in mine. Say you have made a calculator app and I’m writing a big app that handles…

Wait, … hmm. mumbles something about JRootpane

Anyways I can’t agree that it’s a major screw up.

Well, do you extend the functionality of the JFrame? Nope. You simply use it.

For a novice programmer extending JFrame feels like blackmagic.

It’s much more natural to write:


JFrame frame = new JFrame();
frame.setTitle("hello world");
frame.getContentPane().add(new JButton("click me"));

That also makes a lot more sense when you want it to be ‘integrated’ into your main-method, which is what the OP was talking about. A JFrame is just an object, and you shouldn’t extend the class to use a JFrame in your application.

(Oh well…)

Well that is awfully subjective and there is nothing simple about it.
The fact that tons of book and not least the sun tutorial has it in their examples should be a good hint.

As soon as your ‘integrate’ that in your main method your making a other mistake explaining why that belongs in a separate public/protected method is goign to bring about a hell of a lot more voodoo. And rowing against the stream of the way the API was designed before the user has run it’s first GUI-app isn’t goign to help things either.

I don’t meant to be offensive but this is the only clean way I can explain it: You can be a zealotic composition purist about it but you would be discarding reality.

Whether or not it is a screwup is something that you can take to a nice academic debate(and no I haven’t picked a side). But in the light of reality calling it a major screwup is just wrong.

I’ve always wondered about this as well. Please straighten me out on this issue. :slight_smile:

People often say not to extend JFrame and instead just create one and put stuff into it, and cite “composition over inheritance” as the reason. The thing is, you’ve got to extend something to create your GUI app, right? For example, you might have a GUI app that requires a mildly-complex main frame (several text fields, buttons, etc. etc.). For your main class, you could extend JFrame and have all that stuff added to the content pane. But that is considered bad because you’re extending JFrame…

So what do you do instead? You could extend JPanel and drop all your app’s main frame’s widgets into it. Then in your main method, add that JPanel to the JFrame. But then you’re not really following the mantra of “composition over inheritance” - you’ve extended JPanel without actually needing to expose any of its functionality. So you’ve got the same problem…

So then the only real way to avoid “inheritance” is to add each widget in your main window individually to a JFrame’s content pane in the main method. Which to me seems like a bad idea, especially if there are several components in this window. You’ve eliminated what code reuse you’d have in the JPanel (or to a lesser extent the JFrame) scenarios above.

If you extend JPanel, you have one added benefit over extending JFrame - you can add that JPanel to both an JApplet and a JFrame, thus having two different means of deploying your application with minimal fuss.

But me - I’ve always extended JFrame, probably because that’s what they do in the Java tutorials where I learned Swing. I’ve also only written relatively small Swing apps too, for what that’s worth.

moreover it is half, JPanel doesn’t contain a glasspane or menu so you’d still have to add those in the main method so your still loosing on reuse.

[quote]So what do you do instead? You could extend JPanel and drop all your app’s main frame’s widgets into it. Then in your main method, add that JPanel to the JFrame. But then you’re not really following the mantra of “composition over inheritance” - you’ve extended JPanel without actually needing to expose any of its functionality. So you’ve got the same problem…
[/quote]
I don’t see why you’d extend the JPanel. I very rarely extend JComponent - only when creating a new component, making modification to existing components (that includes drawing on them), or just when I allow myself to write messy to due to time/money constraints.

No way I’m a composition purist

The general approach for me when it comes to inheritence:

  1. do it when it makes logical sense
  2. do it when it is easier to code / saves time

Extending JFrame/JPanel when just using it, does neither, you write more code and it makes no sense.

It it just that every body is doing it, because everybodies first tutorial did it - so we probably have to blame some pretty old guy that tricked us in doing it.

One reason to extend JFrame is if you purposefully are exposing that class’ methods to clients of your class. For example, you may want to allow clients to setVisible, setDefaultCloseOperation, etc., as well as doSomethingSpecificForYourClass. I’m not saying that extending JFrame is always right, but there’s a case where using composition instead of inheritance would just be pedantic. (That is, you could use composition, but then you’d have to rewrite all the JFrame methods you want to expose and have each one delegate to a private JFrame instance. Good golly, that would be an obnoxious typing task.)

For the record, I am something of a composition zealot, but I also believe that working with the API makes more sense than working against it.