How to use WindowBuilder to edit a JPanel in an inner class - java

I would like to use WindowBuilder in Eclipse to construct Swing GUIs. The JPanels I need to build will be inner classes in a non-GUI wrapper, like so:
public class MyWrapper extends MyBaseClass {
...
class MyPanel extends JPanel {
...
}
}
So my question is this: can I construct MyPanel using WindowBuilder? If so, how should I set it up?
If anyone is interested, the wrapper is an abstract base class which the plug-ins I am developing for my app must extend; deployment concerns mean that it's not really practical to put the GUIs in a separate JAR either so I pretty much have to do it this way.
My current workflow, which is awful, is to build the GUI in NetBeans and paste the entire generated class into Eclipse where I connect it up to the methods in my wrapper. I am very hopeful that WindowBuilder will let me work more reliably and efficiently if I can trick it into generating code in MyPanel, not MyWrapper.
Thanks

It isn't clear why the JPanel must be an inner class. In general, that is not a good idea (you will end up with multiple .class files either way). The JPanel should just be its own top-level class and referenced from your wrapper class (all of which can be in the same jar). WindowBuilder can easily be used to create/edit your JPanel subclasses (including ones originally created with NetBeans), but it will only do so for top-level classes. It won't allow you to create/edit an inner class like this (which is entirely intentional).

Related

Editing nested JDialog in Netbeans' Design mode

Say I have the following code:
public class MainDialog extends javax.swing.JFrame
{
static class SubDialog extends javax.swing.JDialog
{
}
}
If I open 'MainDialog.java' in design mode, I can only edit the GUI of the MainDialog class. Is there anyway to edit the SubDialog class in design mode?
Thanks
To even be "close" to been acceptable, the inner dialog would need to be public and static as Netbeans needs a way to create an instance of the dialog.
Most developers will create separate, single based class, based forms which are then configurable in some way (via setters and getters), passing references of what they need backwards and forwards between them.
Personally, I tend to hand code most my UIs and only rely on the form editor when time a is pressure or the layout is especially complex

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: How can I load an external class into a gui

I'm looking for a specific functionality. I want to load a class that extends JPanel for instance and show that JPanel on a separate GUI class.
I'm looking for the ability to switch several of these classes out at will. I have an idea for an educational game software and the classes would be the different games.
I do realize that I can instantiate an instance of each class in my GUI class, but I ran into the issue of them not displaying properly when I try to switch between them. repaint() only works on the last class I added to my content pane. Not sure why as the multiple classes I instantiate are present, it just seems to ignore the preceding classes.
How to swap components?
You can either use CardLayout to switch all the component or add/remove them calling
container.revalidate();
container.repaint();

Java: Creating a GUI. Import or Extend JFrame?

I did a GUI by my own which extends a JFrame. And I saw a program code from advanced programmer who imports the JFrame. I might know the difference between import and extend. But what advantage is given by which sort of implementation?
By "import" i presume you mean that your programmer friend's class uses a JFrame whereas your class is a JFrame. I don't think extending a JFrame is "wrong", but my preferred approach is to create and configure a JFrame rather than extending it. If there's really some protected method that you need access to then you might extend it but i'm sure that, in most cases, simply creating and configuring a standard JFrame is right - i have never found a need to extend it.
In other words, by inheriting JFrame with no real need to do that, you're just complicating your system. This is a same argument you would have when choosing inheritance versus aggregation with any other class. To find out what's right, you need to ask yourself if the class you're writing really is a JFrame which is a window widget. I suspect that in most cases you are writing a Swing application which needs a JFrame but which isn't one itself - it's a Swing application with some other purpose.

How to refactor Netbeans generated GUI code?

I had created a GUI in Netbeans through Netbeans Swing GUI creator. So I just dragged and dropped the Swing Components from the "palette" window and all the code was generated by netbeans.
Now the code is too long to maintain (approx. 10,000 lines). So some experts on SO suggested me to refactor my code.
I can refactor the code that was generated by me but I don't know how to refactor the code generated by the Netbeans as It doesn't allow editing in its generated code.
Any suggestions?
10.000 lines of code sounds like you have everything in that single class.
Start by splitting your source into Model, View and Control (MVC).
You might also be able to extract some JPanels into separate classes. One way to do this is to create a new JPanel (new file), and cut/paste your compoments from one main panel into that new JPanel. Save and compile your new panel.
Then go back to your main frame, select Beans -> Choose Bean from your Palette and choose the newly created class (com.example.YourPanel for example).
Make sure to have a backup of your application before you try this.
Well - if the code is generated, I don't see any advantages in refactoring it as long as the tool which generated it can handle it. The tool (meaning the designer in this case) will "destroy" all your refactoring work as soon as it updates the code.
However, you should split your Control/Window/... into multiple controls - then the code will automatically get shorter and you will be able to maintain your UI more easily.
As a conclusion: Do not refactor the generated code but do refactor your control.
Handcode the GUI code with layoutmanagers.
Using GUI builder tools, makes it nearly impossible to refactor GUI code. I have to use these idiotic Intellij Swing GUI designer forms. I now cannot even rename my packages in Eclipse because it wont be updated in the forms.XML file.
Stay away from GUI builders. If you want to build really complex, maintainable GUIs then do it by hand by using GridBagLayout and all the rest.
If you have to use netbeans, because of project limitations (e.g the rest of the team is, or requirements say to) then use Matisse to break up the huge form into smaller panels, each of which the designer can edit. You can do that by creating a new form, and cutting and pasting panels from the big form into the new form.
But at the same time, make sure all the business logic is moved out of the UI classes.
If you do not have to use matisse / netbeans, you can open the project in Eclipse, and edit the forms using WindowBuilder, it will do it in real java code instead of the uneditable form, so you can then chop and edit it to your heart's content.
You can extract the application logic into a separate subclass. Then, directly use the subclass. I succeeded with the following method.
Members defined by us that are relevant to the application logic moved to the newly created subclass.
Components access modifier made "protected" (they are "private" by
default). To do so: Right click -> Properties -> Code (tab) -> Set
"Variable modifier" to "protected"
Event handling methods moved to the subclass - When you are adding events to a component using properties pane it changes initComponents() function by adding the relevant code like in the following code sample. Here definition of btnNum6ActionPerformed() is added to the class with an empty body. Unfortunately btnNum6ActionPerformed() is private and no way to change the access modifier using NetBeans IDE. Hence, they cannot be overridden. To get rid of this, you can define another intermediary function and call it inside btnNum6ActionPerformed(). It is better to make the base class and its intermediary event handling functions abstract.
btnNum6.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnNum6ActionPerformed(evt);//Definition of this method is added too
}
});

Categories