Exercise 3: Create a admin module for Anagram Application
(30 minutes)
Background Information
In the previous exercise we prepared the JavaOne 2009 Anagram Application built on
top of NetBeans Platform. It allows to start new game and store, visualize the best results.
We will create new module Word Scrambler to improve the functionality of this application.
Word Scrambler will serve as admin module for the Anagram Application.
We prepared this module for you as its functionality is very complex to be covered in the HOL.
What does Word Scrambler provide? It can read a text from file, makes pairs of
scrambled and unscrambled words from the read text. And in addition it makes words with fixed length
by a given parameter that express the complexity.
We need to provide some UI for calling this code and then establish a way to exchange
words between Anagram Application and Word Scrambler.
Steps to Follow
Step 1: Add new module into application
- Open project Word Scrambler in <lab_root>/exercises/exercise3/ in NetBeans IDE
- Add Existing Module Word Scrambler to the JavaOne 2009 Anagram Application module.
-
Double click the new module to open it in NetBeans IDE.
Step 2: Run the test in Unit Test packages
-
To run all tests of project just open the popup menu of Word Scrambler
project and choose Test menu item
or use a short cut Alt-F6.
Check the test results. All test should pass.
Step 3: Create a main window of Word Scrambler module
-
Create new Window Component in org.javaone.scrambler package in Word Scrambler module like in
Exercise 1, Step 6.
Component should be docked into editor mode. It should open on application start.
Use prefix AnalyzeText.
-
Open the class
AnalyzeTextTopComponent that was created by the Window Component wizard.
Use Design button and sketch out UI. The UI should like on following picture:
Use following naming and components, please
| Swing Component |
Text |
Variable Name |
| JLable |
File |
lFile |
| JTextField |
<none> |
tfFile |
| JButton |
&Browse |
bBrowse |
| JButton |
&Analyze |
bAnalyze |
| JButton |
&Upload to Anagram Game |
bUpload |
| JLabel |
Word Scrambler has 4 complexity |
lComplexity |
| JList |
<No words> |
lWords |
- Add new private fields to the AnalyzeTextTopComponent class.
private File textFile;
private Scrambler scrambler;
-
Add a handling of
actionPerformed event for the Browse button.
Tip: Invoke a popup over Browse button in UI designer and then choose
Events|Action|actionPerformed. It will create the actionPerform method
and give focus into the right place in editor.
In editor type following code that opens JFileChooser when you press Browse button.
private void bBrowseActionPerformed(java.awt.event.ActionEvent evt) {
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode (JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled (false);
chooser.setFileHidingEnabled (true);
chooser.setDialogTitle ("Select a text file");
if (chooser.showOpenDialog (this) == JFileChooser.APPROVE_OPTION) {
textFile = chooser.getSelectedFile ();
tfFile.setText(textFile.getPath());
bAnalyze.setEnabled(true);
}
}
It also sets the chosen file as content of the File textfield.
-
Fix imports.
-
Using as same way as before now to add a code handling the bAnalyze button.
Analyze button should scramble text of given file.
Tip: You can use
<lab_root>/words.txt file to play with the Analyze functionality.
private void bAnalyzeActionPerformed(java.awt.event.ActionEvent evt) {
File f = new File(tfFile.getText());
if (! f.exists()) {
NotifyDescriptor.Message nd = new NotifyDescriptor.Message
("The file " + f.getPath() + " doesn't exist!", NotifyDescriptor.ERROR_MESSAGE);
DialogDisplayer.getDefault().notify(nd);
bUpload.setEnabled(false);
bAnalyze.setEnabled(false);
return;
}
String text = File2String.file2string(f);
scrambler = new Scrambler(text, pref.getInt(ScramblerComplexityOptionsPanelController.SCRAMBLER_COMPLEXITY, 4));
lWords.setListData(scrambler.getWords());
bUpload.setEnabled(true);
bAnalyze.setEnabled(false);
}
-
Please, do not bother about the error of missing pref variable. We will fix it in next steps.
Step 4: Add new options to NetBeans Options framework
-
Invoke New > Other on org.javaone.scrambler package in WordScrambler module.
Choose Options Panel in Module Development category.

-
Select Create Primary Panel radio button. Use value as on picture bellow. Browse the icon
anagram32.png in <lab_root>/exercise3 directory.

- Class Name Prefix should be ScramblerComplexity.

-
Design the Scrambler Options Panel. Open ScramblerComplexityPanel. Add one label and one combo box to design.
-
Change the model of the combo box in Properties.

-
Implement both effective methods load() and store() of the options panel in source code of ScramblerComplexityPanel class.
These methods store and load the options to be persistent even during several starts of the application.
As you can see from the following code we used NbPreferences functionality that makes it quite simple.
private final Preferences pref = NbPreferences.forModule(ScramblerComplexityPanel.class);
void load() {
int complex = pref.getInt(ScramblerComplexityOptionsPanelController.SCRAMBLER_COMPLEXITY, 4);
jComboBox1.setSelectedItem(Integer.toString(complex));
}
void store() {
String complex = (String) jComboBox1.getSelectedItem();
pref.putInt(ScramblerComplexityOptionsPanelController.SCRAMBLER_COMPLEXITY, new Integer (complex));
AnalyzeTextTopComponent.getDefault().setComplexity(complex);
}
boolean valid() {
return true;
}
-
Add new SCRAMBLER_COMPLEXITY field into the ScramblerComplexityOptionsPanelController class.
public static final String SCRAMBLER_COMPLEXITY = "scrambler_complexity";
- Create new method setComplexity(String complex) in AnalyzeTextTopComponent class.
void setComplexity(String complex) {
lComplexity.setText("Word Scrambler has " + complex + " complexity.");
boolean canAnalyze = new File(tfFile.getText()).exists();
bAnalyze.setEnabled(canAnalyze);
bUpload.setEnabled(false);
}
-
Now we have to modify the constructor of the AnalyzeTextTopComponent class
to setup the complexity according to value selected in Options.
public AnalyzeTextTopComponent() {
initComponents();
setComplexity(pref.get(ScramblerComplexityOptionsPanelController.SCRAMBLER_COMPLEXITY, "4"));
bAnalyze.setEnabled(false);
bUpload.setEnabled(false);
setName(NbBundle.getMessage(AnalyzeTextTopComponent.class, "CTL_AnalyzeTextTopComponent"));
setToolTipText(NbBundle.getMessage(AnalyzeTextTopComponent.class, "HINT_AnalyzeTextTopComponent"));
}
- Add new private field pref for reading the preferences in the AnalyzeTextTopComponent class.
private final Preferences pref = NbPreferences.forModule(ScramblerComplexityPanel.class);
-
To be able to Fix Imports you will have to add new dependency on Dialogs API library first.
-
Delete all other instances from OptionsCategory.createCategory except the one that we created from the layer file.
The one created by us is in bold. In this way you'll mask out the other Options Panels.
Step 5: Make a relation between Anagram Game module and this Word Scrambler admin module
-
NetBeans Platform Module System discriminates between public and private modules and a module can uses only classes from public part of modules.
Only a part of a module is visible to the rest of modules. This public part that is visible to other modules is known
as the public packages.
We have to explicitly indicate that a Java packages of Anagram Game project are visible to Word Scrambler module.
Make org.javaone.anagram.lib package public. It will allow us to use it in other modules.
-
Add Anagram Game JavaOne 2009 as a new dependency of Word Scrambler module. Please, note that Anagram is Non-API module,
don't forget to check the Show Non-API Modules checkbox.
Step 6: Post new words into Anagram Game
-
Create new class AdditionalWordLibrary extending org.javaone.anagram.lib.WordLibrary
in the org.javaone.scrambler package.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.javaone.scrambler;
import org.javaone.anagram.lib.WordLibrary;
/**
*
* @author jirka
*/
public class AdditionalWordLibrary extends WordLibrary {
private final String[] words;
private final String[] scramblers;
private final int size;
public AdditionalWordLibrary (final String [] words, final String [] scramblers) {
this.words = words;
this.scramblers = scramblers;
this.size = words.length;
}
@Override
public String getWord(int idx) {
assert idx < size;
return words[idx];
}
@Override
public String getScrambledWord(int idx) {
assert idx < size;
return scramblers[idx];
}
@Override
public int getSize() {
return size;
}
@Override
public boolean isCorrect(int idx, String userGuess) {
assert idx < size;
return words [idx].equalsIgnoreCase(userGuess);
}
}
-
Now we have to use the dynamic approach of the AdditionalWordLibrary and connect
it with the AnalyzeTextTopComponent. Create action handler for the
Upload to Anagram Game button at
AnalyzeTextTopComponent. Right click the Upload button and choose
Events > Action > actionPerformed.
-
Post scrambler words from Scrambler into Anagram Game. Add following code to AnalyzeTextTopComponent.
private void bUploadActionPerformed(java.awt.event.ActionEvent evt) {
// upload to Anagram Game
WordLibrary wd = new AdditionalWordLibrary (scrambler.getWords(), scrambler.getScrambledWords());
WordLibrary.setDefault(wd);
bUpload.setEnabled(false);
bAnalyze.setEnabled(false);
}
Fix imports.
Step 6: Run the application
-
We removed all the menu items in Exercise 1 therefore we have to delete following line from XML Layer file under Important Files in Anagram JavaOne 2009 project.
<file name="Tools_hidden"/>
Summary
In this exercise we created new module that allows to manage the words in the anagram game.
You learned how to design new top component and how to use a module as library.
You should know how to add new panel to Options and how to store and load their values.
Back to top
Next exercise
|