COMP 310 |
Using WindowBuilder |
WindowBuilder comes automatically with the default Eclipse "Indigo" installation, so no additional installation is necessary.
If you are using an earlier version of Eclipse, e.g. "Helios", please see the Eclipse and plugins installation page.
WindowBuilder's automatic code generator sometimes creates code that is incompatible with the architectural design principles taught in Comp310. While the auto-generated code will certainly run, they will present unnecessary difficulties when scaling the programs up into larger systems. In such, it is important that certain auto-generated codes be modified after they are created, before proceeding onward with any further programming. Please pay close attention to notes below concerning changes that should be made to WindowBuilder's auto-generated code to insure design compatibility with Comp310-taught principles. Setting the preferences as detailed below, will reduce some of the incompatible code generated so change those preferences right away.
Forcibly Opening a Class with WindowBuilder
Sometimes Eclipse forgets that it should open a GUI class using WindowBuilder. To force Eclipse to open the class with WindowBuilder, do the following:
Make sure that the class has no compile errors and is saved, then close the editor tab for that class.
Right-click the class in the Package Explorer and select "Open with..."
If WindowBuilder appears on the list, click on it, otherwise, click on "Other..." to find it.
WindowBuilder Designer will not open
If presented with the option, try clicking the "Reparse" button. It may take several attempts. Also try cleaning the project: on the main Eclipse menu, select "Project/Clean..."
KNOWN BUG (as of 9/18): WindowBuilder Designer does not understand lambda function syntax
Do not use lambda function syntax to write things like ActionListener
implementations for buttons. Doing so will result in WindowBuilder crashing when you double-click the button to try to go to the ActionListener
code. ("Reparsing" will restore the designer view.)
WindowBuilder always wants the implementation to be written using anonymous inner classes, not lambda functions.
Bottom line: Always let WindowBuilder write the initial ActionListener implementation by double-clicking the button in the designer view. Then fill in the actionPerformed
method. Don't use lambda functions.
Reference: WindowBuilder bug report.
While the default preferences in WindowBuilder are perfectly usable, for Comp310, life is a lot easier and more convenient is the WindowBuilder preferences are slightly adjusted.
In Eclipse, go to Window/Preferences and then expand the WindowBuilder link to Swing/Code Generation and make the following changes:
Set the drop-list choice for "Method name for new statements" to "initGUI".
Under "Variable Generation", check the box at the top of the "Init. Field" tab.
The WindowBuilder Swing Code Generation preference dialog should look like the following when you are finished:
Even after making the above preference settings, when a frame or panel is first created, WindowBuilder does not put the GUI initialization code into a separate method, e.g. into initGUI(), instead, putting all the code into the frame or panel's constructor.
However, this bug is essentially benign because as soon as a component is dragged and dropped from WindowBuilder's component palette onto the frame or panel, WindowBuilder will then correctly move all the initialization code, including the code it initially generated, into the separate initGUI() method.
Work-araound: Either manually move the initialization code into the initGUI() method or simply drop a component into the frame or panel and WindowBuilder will fix the problem automatically.
Graphical View of Design -- This is a "what-you-see-is-what-you-get" ("WYSIWYG" or "wizzy wig") interface that shows you exactly how your GUI will look as you create it. You can drag and drop components from the top bar onto this design canvas. The placement and size, within the constraints of the container's layout manager, of the component can be manipulated. Once the auto-generated code has been moved to a dedicated initGUI() method, WindowBuilder will subsequently and automatically generate the Java code to create the desired GUI in initGUI(). It is highly recommeneded that only GUI initialization code be written in this method.
Select Between Graphical and Textual Views of GUI -- Clicking these tabs will switch back and forth between the graphical design view of the GUI vs. the textual code representation. Any change in one view will automatically be reflected in the other.
Palette of GUI Components -- This is a gallery of available components, such as panels, buttons, text fields, etc. that can be dragged onto the graphical design. Simply click on the the desired component in the gallery and then mouse will start to carry that component to wherever you want it -- no need to hold the mouse key down. Left-clicking will deposit the component wherever the mouse is. WindowBuilder will light up placement targets corresponding to the current layout of the target component to aid you in properly locating the new component. Hint: Sometimes it is difficult to drop a component exactly where you want it on the graphical design view. In that case, on the tree-view of the GUI components in use on the left side of the screen, locate the container (panel or frame) that you wish to hold the component and drop it over there, onto the container's name.
Hierarchal List of All GUI Components in Use -- This is a tree-like representation of all the GUI elements that are currently being used in the design. Containers such as panels and frames are shown as parent nodes to the components that they contain.
Properties of the Selected GUI Component -- When a component is selected, either in the graphical or tree (textual) view, it's properties will be displayed in a pane on the lower portion of the screen. Filling out the values for the properties here will cause WindowBuilder to auto-generate the corresponding code. Likewise, code added to the initGUI() method will show up here.
Click Here to See Events Tied to the Selected Component -- Clicking on this icon will display the events to which the selected component listens. Double-clicking an event will cause WindowBuilder to auto-generate an anonymous inner class listener for that event for that component.
public MyFrame() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 450, 300); ... }becomes
/** * Constructor for the frame */ public MyFrame() { initGUI(); // Call the initialization method. } /** * Initialize the GUI components but do not start the frame. * This method could be public if desired. */ private void initGUI() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 450, 300); ... }
main()
:
frame.setVisible(true);becomes
frame.start(); // Start the frame up, i.e. make it visible and operational.Add the following method:
/** * Starts the already initialized frame, making it * visible and ready to interact with the user. */ public void start() { setVisible(true); }
The current version of WindowBuilder by default, still
uses anonymous inner classes to create ActionListeners
for buttons and the like.
This form is perfectly acceptible though when coding by hand, one might prefer
to use lambda functions. For example:
// WindowBuilder auto-generated code: btnChgLabelTxt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { lblDisplayLabel.setText("Howdy!"); // changes the text of the lblDisplayLabel to "Howdy" when btnChgLabelTxt is clicked. } }); // Hand-coded listener using a lambda function that does the same thing: btnChgLabelTxt.addActionListener((arg0) -> lblDisplayLabel.setText("Howdy!"));
© 2017 by Stephen Wong