What does a JFrame do? - java

First of all, I would like you to know that I'm new in Java world; so please forgive me if my question is basic.
I'm working with a team, and we are trying to create a browser using Java.
To begin with, we are watching some tutorials, and all of them begin with a class that extends JFrame. What does this JFrame do?

This could easily be answered in a 10 second Google search... But to answer your question anyway, a JFrame is an extension of java.awt.Frame, which displays a graphical window to the user, in which you can house components and graphics on.
These components range from JButton's JLabel's all the way to Menu bars, etc.
Also, extending a JFrame is never a good idea. It works fine, but for the best code readability, and usage, do not do it. There are plenty of reasons why, and they are explained thoroughly here:
Why shouldn't you extend JFrame and other components?
Extract:
Generally speaking, extending the component tends to be done strictly to use the component. This severely limits your options in unnecessary ways in terms of design, so that your classes can't extend different classes, you can't hide the JFrame's methods causing it to be more difficult to maintain and easier to trigger unexpected bugs when using the class.
More can be found below in the links provided:
JavaDoc for JFrame
How to use a JFrame

Related

JFrame vs Container

I read that the window that appears using the JFrame class is a Container with the predefined features (minimize, closing), but I found people who were not using the JFrame class but other classes (one of them the Container) which was far more hard.
Why do they do it that way? Is it because the JFrame class always has a predefined window that you can manipulate some aspects of it but the Container and the other classes give you more freedom of how you can create a window?
For an example to my question (I don't know if its real or not) in the JFrame class the close button always go to right to corner of the window but if I do it the other way you can put it everywhere you like. (If it can be answered with a yes or no).
So my qusetion is why they do it that way
There are two "main" reasons why. First is about overall good programming.
We tend to recommend avoiding extending from classes to which we are not adding any new functionality or repeatable features. If the whole reason for extending from JFrame is just so you can display some components, then it's really not a good choice or starting point.
JFrame is also a complex, compound component. That is, it's actually made up of a number of other layered components which work together to provide an overall experience.
*From How to Use Root Panes
This means that there is a lot of added complexity you'd have to be willing to manage if you extended from this class, a lot of overhead just to display a few components.
In principle, it's better to use composition over inheritance, which leads into the second point.
Extending from any class locks you into that classes use case. In the case of JFrame, you can only ever display what ever is managed by the class via a JFrame, there is no flexibility or entry point for re-usablility.
If, instead, you started with a base class of, say JPanel, you can add that to what ever container you want when ever you want, it increases the flexibility and re-usability of the class over all.
For an exaple to my question(i dont know if its real or not) in the JFrame class the close button always go to right to corner of the window but if i do it the other way you can put it everywhere you like.(If it can be answered with a yes or no)
Yes and no. The frame border is defined by the look and feel delegate, so you're not actually starting at the right place to begin with anyway.
Most look and feel delegates delegate the frame border to the native platform, in the case of Windows, yes, the close button is on the right, on Mac it's on the left.
In any case, it's better to support user expectations, placing the close button in an unusual place might make the UI "pretty", but diminishes the user experience - as a general guide line, don't diminish the user experience, no matter how awesome your program or UI, user's won't like you for it - but that is a (very broad) question for another day

Syntax of establishing JFrame. Which is correct?

I'm fairly new to programming and definitely new to Java. I'm teaching myself before I begin courses this fall in computer science and I have a curiosity about syntax that I have seen from two different authors.
In one book, a JFrame is usually established by making the class an extension of JFrame
public class MyClass extends JFrame {
etc
However, another author, and also questions on this site usually establish a frame inside of the class as such:
public class MyClass {
JFrame frame = new JFrame();
Firstly, what are the advantages of one over the other?
It seems to me, and I'm hardly an expert, that making a class an extension of JFrame would make it easier to set parameters of the frame and also to add components to it.
IE in the extension format, you simply say
add(component);
However, in the other format, on must type:
frame.getContentPane().add(component);
which seems more tedious.
Can someone please explain succinctly the reason behind this or if it is simply a matter of preference. I have looked into this and have been unable to get a straight forward answer.
There are philosophical and practical reasons many (including I) prefer the latter:
Prefer composition over inheritance in general.
Only extend a class if you plan to alter its innate behavior (i.e., override one or more of its methods).
By not extending JFrame, it is easier to create classes that maximize cohesion and minimize coupling, and to write clean MVC-based code. A more important example of this concept is to avoid having your GUI code (your view code) implement any listener interfaces (your control code). It's OK for baby programs, but not for grown-up code that has the potential of getting complex.
By not extending a large and complex class such as JFrame, you reduce the risk of difficult to debug hidden override malbehaviors. Try extending JFrame or JPanel and giving the class a getX() and getY() method to see what I mean!
If you're using an IDE that gives suggestions of methods available to objects of your class, you greatly reduce the number (and complexity) of possible suggested methods if you don't override a huge complex class such as JFrame.
By gearing your Swing GUI's to create JPanels rather than override JFrame, you greatly increase the flexibility of how that GUI can be used. Now it can be placed in a JDialog, JOptionPane, a JApplet, inside of another JPanel as part of a more complex GUI or as part of a CardLayout view swap.... and I can go on and on.
On the same token as above, many of my GUI's do just that, create JPanels, that I can test in isolation by putting them in JFrames in small test programs before adding them to the greater whole of the application.
Traditionally you're not creating a special type of frame, so you shouldn't extend JFrame.
You're creating a JFrame and putting content in it, so the latter method is preferrable.
I.e. it's from an object oriented point of view it's cleaner to USE a JFrame, instead of extending one.

Java graphic as an object/class

I'm sorry this is probably way too basic to be on here, but it's a subject I've been struggling with for about a month now and I don't know where else to go (as far as I know there is no "noob overflow", lol).
I'm trying to create a class that would:
1. put an image on a window (a JFrame, JPanel or other container)
2. be able to support keyboard and mouse listeners
3. could have multiple instances in the same container
So anyway I've tried all the usual places - Google, YouTube, the official Java site (sorry forgot the URL) and of course here on Stack Overflow - but haven't been able to find anything even remotely similar to what I'm trying to do.
Of course, I've also considered the possiblity that maybe it can't be done at all. There doesn't seem to be any kind of standard "JImage" or "JGraphic" that works like JButton or JLabel, and for whatever reason graphics requires a completely different list of (extremely involved) processes and procedures. As an example, in this post: How to "really" draw images in a Java app - it took me 60+ lines of code and 2 classes to just come close. That project didn't work in the end because for some reason it would only let me create one instance (even it you created 2-4 in the main method, it would only display the last one you told it to add).
But anyway, assuming that I'm not trying to "re-invent the wheel" here and it is actually possible (in Java), does anyone have an idea as to how (or at least know of a better site to study it)? Unfortunately most of the sites I've visited tend to assume you know all the inner workings of images (I know what a pixel is but that's about it - Buffers, Rastars etc. are still beyond me). It would be absolutely outstanding if there were a site that would explain it in layman's terms, if such a site exists. Thanks in advance.
Just use a plain old JLabel.
Regarding your requirements:
put an image on a window (a JFrame, JPanel or other container).
You can give a JLabel an ImageIcon of the image of interest and it will display it. This can then be easily placed in any other container such as a JPanel or JFrame.
be able to support keyboard and mouse listeners
Any component that extends JComponent, such as a JLabel allows for use of MouseListener, MouseMotionListener and can listen for keyboard input via Key Bindings.
could have multiple instances in the same container
You can add as many as you'd like to any container. Just be cognizant and respectful of the layout managers in use.

What's so special about CardLayout vs manual adding/removal of JPanels?

There have been many times on StackOverflow where a user asks a question like this...
I have a main JPanel that contains a child JPanel. When the user clicks a
button, the child JPanel should change to a different JPanel. How can I
achieve this.
More often than not, the user has actually tried to implement this problem, but can't get it working.
Whenever I answer this question, I tell them to do something like this (put simply)...
JPanel myFrame = new JPanel();
myFrame.remove(oldPanel);
myFrame.add(newPanel);
I see this as quite a legitimate answer, and I personally have used this in many of my own Java projects without problem. However, I always get downvotes for my answer, and everyone just says "Use a CardLayout".
So my question is, why is everyone so fascinated with CardLayout, to the point where my answer deserves a downvote? Why should I choose to use a CardLayout rather than adding/removing panels using my code above?
As a further question, would you still be suggesting CardLayout for interfaces that have dynamic JPanels. For example, most of my programs implement a custom plugin framework where there could be many hundreds of JPanels, but I only load and display the panels as they are actually required. For the normal use of the program, most of the panels would never actually be loaded or required. For this type of scenario, would my coding approach be the best solution, as I understand that CardLayout would require me to actually create all of the JPanels even though most will never be used?
With CardLayout, it's easier to have loose coupling (though not impossible with roll your own)
With CardLayout, the preferredSize of the card-holder is that of the largest card it holds.
CardLayout is harder to fark-up, and allows almost trivial contiguous component swapping its next() and prev() methods.
You can easily associate the desired component with a constant -- no need to have to create a Map<String, Component> for this purpose as it's already there for you. I've not infrequently used enums for this.
No need to remember to call repaint() and revalidate() when swapping components.
It's built for and allows for easy re-use of components.
CardLayout has been thoroughly tested and proven to work. It correctly acquires the component-tree lock and performs component validation in order to ensure that nothing can go wrong. Your solution, while it may work most of the time, will fail under certain circumstances.
This all boils to reinventing the wheel: Why would you want to when such a time-tested class is already available?

How are Swing components internally created, laid out, repainted, notified of events, ...?

I wonder if there's a good documentation (or a (viewable) ebook) about
the lifecycle of Swing components.
Is "lifecycle" the correct term, anyway?
I hope to find answers to question such as:
How, when, in which order painting methods are called?
How, when, which events are called by whom?
What is the exact sequence of method calls for component creation?
From time to time I encounter strange behavior of my apps, for example:
ComponentListener's resize event is called before setVisible(true)
(so that root pane has negative dimensions!)
Some components are laid out correctly only after resizing the JFrame by hand
Changing a super class from JPanel to JLayeredPane causes my class
to be laid out differently inside an other container.
And lot of other strange things...
I had the same question long ago.
I can't believe how hard is to find a good resource about this topic in the internet.
Fortunately I've found this link and now I have it in my bookmark with golden tag. :)
A Swing Architecture Overview
Once you have a good grasp of how they work conceptually you will be able to fix most of the problems you mention.
I hope it helps.

Categories