So, I am designing a small Interface for an application with the netbeans GUI-Builder,
and my problem is, that the position of the Swing-Elements - declarations is not changeable? Or at least I don't know how.
My ScrollPane needs the Textarea "inside" it as parameter for construction, but in the generated code the TextArea is declared below the Scrollpane.
I tried changing it with N++ and it worked, but everytime I change the custom code section it replaces the declaration again.
Is there any way to accomplish a custom positioning?
AFAIK, there is unfortunately no way to re-position auto generated code in NetBeans. Have you considered perhaps moving the constructors functionality to another method and calling that after the auto-generated code is finished? Something like scrollPane.setTextArea(textArea);?
There is a similar question concerning moving code on the Oracle forums here.
Related
Well I have a problem with one of my classes in Eclipse. In there I define an inner Enum type.
In the picture you can see one of the enum-Constants:https: //www.dropbox.com/s/z9shh52au35mkzy/Pict1.JPG
Now I wanted to add some code to the "setup()" method. Sadly the syntax coloring for the new code doens't show up and even if I create a syntax error inside, it doesn't recognize it. (it works at other places)
https://www.dropbox.com/s/0t6que0pg1hr1tw/Pict2.JPG (can't put pictures in the question yet, I hope you don't mind if I put links there)
Finally, when I save the file and reopen it, the error behaviour is the same, but my pour code looks like this: https://www.dropbox.com/s/9lqzchv4xrnpau6/Pict3.JPG
As you can see, even in the other enum constants, there is just color at keywords and things outside of methods. (If I remove the added code and reopen, it works as if nothing hab happened)
So my question is, how can I fix this?
Thanks in advance.
I'm trying to get a grasp on a couple concepts. Lets imagine you have a JFrame and in that JFrame there are two panels, we'll say left_half and right_half. If I click a button in right_half, I want something to change in left_half. The issue is that the right half doesn't know the left half exists. So, you could tell the Frame, but technically neither panel knows the Frame exists either, right? The Frame can change the panels, but panels can't change the Frame, or so it seems to me.
So, I pass a reference to the Frame into the panels. Now the right_half can call Frame.setVariable(data) and the Frame can, from that same method, say left_half.setStuff(data). That just seems wrong to me and I have been looking for a way to do it without passing references up and down the hierarchy.
Next, someone says "That's why Observable exists!!" Cool, I think to myself. I then found many confusing examples of how to use Observable that didn't help at all. Finally I see this one, which makes sense.
http://www.javaquizplayer.com/blogposts/blogpost7.html
However, it has this: "observable.addObserver(mainWindow);" mainWindow is the equivalent of Frame in my example above, and it had to pass a reference to attach the Obserable to! So even with Observable, I have to pass references down the hierarchy?
It just seems wrong. If it's not wrong, that's fine... I can do it this way. However, my question once all that back-story is finished is simply this: how are you supposed to pass data between two panels? I'm okay with abstract answers if they're in plain language, I'm okay with code samples if they're short and easy to follow. I'm not a pro Java coder, I can't just search through 29 API pages and 1400 lines of code and just suddenly understand how it works... yet. I'll get there.
The observable pattern (in the form of event listeners) is OK and is good practice. You see, even though RightPanel knows someone might be listening to all its events, it does not know who is listening. Well, technically, it could go through all its listeners and use reflection to find out who they are; now, that would be bad practice.
As it is, RightPanel knows someone might be listening to it, and that's all. Components are always aware someone might be listening, since the whole Swing is based on it. What matters is that RightPanel compiles without LeftPanel (or frame), and is completely decoupled from it, except via the listener interface. Not only cool, but standard.
As a side note, your class structure does not have to mirror your nesting panel hierarchy. Depending on what you are doing, it may be entirely fine to control behavior of both left and right panels from inner classes within Frame. (Personally, I'd use a JPanel, not a JFrame, since it allows for more flexibility, but this can be easily refactored). Otherwise, you risk splitting your View/Controller into too many closely coupled classes, and that would violate encapsulation and cause a lot of boilerplate code. Normally, I don't code big fat classes and try to refactor them into smaller ones; Swing is usually an exception. Better one big fat class than a maze of densely coupled classes. Unless of course you have a reusable component or some piece of functionality that can be clearly and intuitively decoupled; not just a couple of buttons or checkboxes that have no meaning in and of themselves. The simple fact that some subcomponents are situated within a certain panel in a component tree should not be a major factor IMHO.
For that matter, I usually don't nest JPanels; I use MigLayout and make all components into siblings. Matter of taste! I'd just encourage you to check out MiGLayout first and see whether you like it.
I have a Canvas subclass object that I'm trying to add, along with some other Canvas subclasses, to a JLayeredPane. In the documentation for JLayeredPane, the layer is given as an Integer, e.g.
layeredPane.add(child, new Integer(0));
However, when I use an Integer for the layer, I get some kind of runtime error. (I can't really tell what this error is because my IDE keeps complaining about the lack source for the Swing libraries.) Oddly, when I use the following form:
layeredPane.add(child, 0);
the line actually executes error-free. I'm very new to Java and still haven't figured out how autoboxing works other than to form the opinion that it doesn't work very well. I'm not sure if the bare 0 would be autoboxed in this case.
I wish I could add more detail about this error, but I'm not even seeing an exception. I will work on trimming my code down to a simple example, but I was hoping someone with experience with JLayeredPane has seen this before.
Unfortunately I can't add comment so I will leave reply.
If you work with IDE then you can use design form to create your GUI easily, just drag-&-drop thing....
I have worked with JLayeredPane and if you add component to it you can use add method manually like layeredPane.add(Component, javax.swing.JLayeredPane.PALETTE_LAYER); or layeredPane.add(Component, javax.swing.JLayeredPane.DEFAULT_LAYER);
Use static constant Integer field and read the JLayeredPane API, or some examples of using it on oracle. Its a good feature to learn.
This error had something to do with the fact that I was using BorderLayout on the JLayeredPane. The error went away when I changed to another layout.
Create a project in NetBeans and create a new JFrame.
Use the GUI Builder to drag some components like a button or label onto the frame and look and the source. You'll see by default that the member variables are private in the frame class.
Now go to Tools -> Options -> Misc -> GUI Builder and change something like the variables modifier to protected instead of private.
Now how do you apply those changes to the already generated code? I've tried several things like format code, fix code, etc. I've even tried cutting all the components off of the frame and then repasting them hoping to fix the issue, but it still uses the old settings.
When I create a new JFrame in the project and perform step 2 again, the changes have taken effect. Any new code generated on a new frame or file works as expected, but not the original.
This is very strange behavior, and I have to imagine there's an easy straight forward way to regenerate this code. Am I missing something?
I'm using NetBeans 7.1 and Java 7u2. Thanks in advance!
As you have already alluded to, the GUI Builder options are defaults only, for the creation of the form.
You can change most things about already-generated GUI elements.
To change the GUI components 'access' from private to protected, right-click the component in the GUI designer and select "Customize Code". At the bottom of the "Code Customizer" dialog you can change just about any aspect of the declaration of the GUI element. That dialog also lets you customise things like the constructor used for the element.
I would recommend you leave the access default at private, and only change the elements that you really need to be protected or even public.
And don't listen to the doom-sayers. We have over 600 GUI-designed forms in our application, we use the GUI designer every day, with multiple developers, and we very rarely have any issues at all.
By the way, we are using version 6.9.1 of NetBeans with Java6, so YMMV.
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
}
});