GUIFramework (GFW) is the basic module for developing Swing GUIs at SLAC.
Developer's Guide
This guide describes in detail how to use the GFW in a Swing application. In general, you create your own Swing components (either programmatically, or with a GUI builder) and add them to the appropriate GFW frame.
Overview
We recommend the following steps:
- #Check out GFW from CVS into Eclipse.
- #Read and run the example code.
- #Create custom components for the desired GFW frame
- #Customize GFW.
- #Test the application.
- Optional features.
- #Tips.
Check out GFW from CVS into Eclipse
GFW is located in $CVSROOT/physics/GUIFramework
Read and run the example code
An example can be found in the class edu.stanford.slac.gfw.example.GfwExample
When running the example, please observe:
- the different GFW frames
- the various areas in which the custom components end up
- how the GUI behaves when it is resized
Create custom components for the desired GFW frame
For a quick development (e.g. GUI mock ups), we recommend the Netbeans GUI Builder (sometimes called "Matisse").
A nice overview of all Swing components is at http://java.sun.com/docs/books/tutorial/ui/features/components.html
Using GFW to build a GUI Application
- If you have not already done so, create a Java Project (File -> New -> Java Project). TODO: Add naming guidelines.
- Add GFW and SwingUtil to your Eclipse project buildpath. You can do this either by including the
GUIFramework
andSwingUtil
projects to your workspace, and then importing them into your new project (File -> Import -> Project from Workspace), or File -> Import... -> CVS -> Projects from CVS, or by including their jar files from the production distribution location. E.g. GUIFramework.jar is in/usr/local/lcls/physics/GUIFramework/jar/GUIFramework.jar
. - Instantiate the custom components. For instance, if you have not yet created the main class, now you would do so. Note, that this class is likely to be in a different package to the User Interface package if you are separating UI components from application code.
- Create a BasicFrame or a ModelFrame instance of the GFW, e.g
or
final BasicFrame myFrame = new BasicFrame("My Frame");
final ModelFrame myFrame = new ModelFrame("My Model Frame");
- Add custom components to various areas of the GFW frame, such as
- Title Bar
myFrame.addToTitleBar(myComponent);
- Tab 1
myFrame.addTopTab1(myComponent);
- Tab 2
myFrame.addTopTab2(myComponent);
- New Tab
myFrame.addTopTab(myComponent, "My Label");
- Bottom ScrollPane
myFrame.addToBottomScrollPane(myComponent);
- Title Bar
- Set application version
BasicFrame myFrame = ...; // see above JLabel appVersionLabel = myFrame.getBasicPanel().getStatusPanel().getAppVersionLabel(); appVersionLabel.setText("my version"); //run in the GUI thread, of before displaying the frame
- #Add event listeners to the appropriate widgets
- Display the GFW frame
SwingUtilities.invokeLater(new Runnable() { public void run() { myFrame.setVisible(true); } });
Add event listeners to the appropriate widgets
Below we describe the recommended way, but nothing prevents you from using any other technique.
First define the methods which will be called by ??? in response to an event on your components. In this example we define the methods that will be called in response to changing the active tab of the tab panel (topTabChanged) and define the method that will be called in response to some component being activated. Note that the names of these methods is up to you. You will connect the method to the event later.
- Extend BasicFrameListener by overriding the default behavior and/or adding your own methods, e.g.
public class MyFrameListener extends BasicFrameListener { @Override public void topTabChanged(ChangeEvent e) { System.out.println("Tab changed"); } public void myComponentActivated(EventObject e){ System.out.println("My component activated"); } }
- Override registerAsDelegateForSwingListeners method of the BasicFrameController class (find out more about Swing listeners), e.g.
public class MyFrameController extends BasicFrameController { protected void registerAsDelegateForSwingListeners( final MyFrameListener myFrameListener) { super.registerAsDelegateForSwingListeners(myFrameListener); //don't forget this! Component myComponent = ...; //get your component, e.g. by using SwingUtil, or through methods of your GUI class myComponent.addComponentListener(new ComponentListener(){ public void componentActivated(EventObject e){ myFrameListener.myComponentActivated(e); } }); } public MyFrameController(BasicFrame myFrame) { super(myFrame); } }
- Add your BasicFrameListener to your BasicFrameController.
Q: To which method of your BasicFrameController do you add it.
- it seems to me also that BasicFrameController is ambiguous - it's not clear whether the "basic" refers to the BasicFrame of Sergei's GFW, or one's own application's frame controller. It's hard to tell what's in the GFW, and what one is suppose to write.
BasicFrameListener myFrameListener = new MyFrameListener(); BasicFrameController myFrameController = new MyFrameController(myFrame); myFrameController.addBasicFrameListener(myFrameListener);
Set web help URL
If you want to provide help via the default GFW way, set the URL of your help website.
BasicFrameListener myFrameListener = ...; myFrameListener.setHelpUrl("http://www.google.com");
Test the application
Optional features
Info Text Pane
Located in the status panel, the info text pane can be used to display some info beyond messaging.
JTextPane infoTextPane = bf.getBasicPanel().getStatusPanel().getInfoTextPane(); infoTextPane.setText("my info"); //run in the GUI thread, of before displaying the frame
Progress Bar
Located in the status panel, the progress bar could be used to display the progress of your program.
- Determinate
JProgressBar progressBar = bf.getBasicPanel().getStatusPanel().getProgressBar(); progressBar.setMinimum(0); progressBar.setMaximum(10); progressBar.setValue(6);
- Indeterminate
To stop:
JProgressBar progressBar = bf.getBasicPanel().getStatusPanel().getProgressBar(); progressBar.setIndeterminate(true);
progressBar.setValue(progressBar.getMinimum()); progressBar.setIndeterminate(false);
SwingUtil
Tips
- When adding to the GUI some long text that doesn't fit, update the frame, e.g.
BasicFrame myFrame = ...; myFrame.validate(); //run in the GUI thread