patternjavaMinor
Initializing JTree
Viewed 0 times
initializingjtreestackoverflow
Problem
I have a class called
My initial approach to this was "Hey, let's just use reflection or something to find out all of the classes under the package
As always, miscellaneous comments on my code are very welcome.
```
private DefaultMutableTreeNode createTree(){
//create the root node
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
//create the child nodes
DefaultMutableTreeNode gatesNode = new DefaultMutableTreeNode("Gates");
DefaultMutableTreeNode arithmeticNode = new DefaultMutableTreeNode("Arithmetic"
Piece, and many many subclasses of Piece. I want to add an instance of every single subclass of Piece (under the pieces package) to my JTree. Currently, I have this class with a huge function (well, 57 lines, but still) that increases in size every time I add functionality to my program. My initial approach to this was "Hey, let's just use reflection or something to find out all of the classes under the package
pieces and add them to the tree!" but this SO question shot that down. My second, working approach is to add them all manually by hand. This seems like too much work though and it seems like there would be a better way to do this.As always, miscellaneous comments on my code are very welcome.
initTree() private void initTree(final UserInterface userInterface) {
tree = new JTree(createTree());
tree.setRootVisible(false);
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
tree.addTreeSelectionListener(new TreeSelectionListener(){
@Override
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)
tree.getLastSelectedPathComponent();
if (node == null){
return;
}
if (node.isLeaf() && node.getUserObject() instanceof Piece) {
Piece pieceCreated = (Piece) ((Piece)node.getUserObject()).getInstance();
userInterface.space.addPiece(pieceCreated);
}
}
});
add( new JScrollPane(tree), BorderLayout.CENTER );
}createTree()```
private DefaultMutableTreeNode createTree(){
//create the root node
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
//create the child nodes
DefaultMutableTreeNode gatesNode = new DefaultMutableTreeNode("Gates");
DefaultMutableTreeNode arithmeticNode = new DefaultMutableTreeNode("Arithmetic"
Solution
public enum PieceGroups{
BITWISE(BitwiseAnd.class, BitwiseNand.class, BitwiseNor.class, BitwiseNot.class,
BitwiseOr.class, BitwiseXor.class, BitwiseXnor.class, BitwiseLeftshift.class,
BitwiseRightshift.class),
ARITHMETIC(Add.class, Substract.class, Multiply.class, Divide.class, Modulo.class, Random.class);
private Set classSet = new HashSet();
private PieceGroups(Class... classes) {
for (Class theClass : classes) {
try {
Constructor construtor = theClass.getDeclaredConstructor(int.class, int.class);
classSet.add((Piece) construtor.newInstance(0, 0));
} catch (NoSuchMethodException ex) {
processException();
} catch (SecurityException ex) {
processException();
} catch (InstantiationException ex) {
processException();
} catch (IllegalAccessException ex) {
processException();
} catch (IllegalArgumentException ex) {
processException();
} catch (InvocationTargetException ex) {
processException();
}
}
}
public Set getClasses () {
return classSet;
}
private void processException () {
throw new IllegalArgumentException("Something went wrong with the init of the Enum");
}
}Explication :
We create an enum, still the best singleton what there is.
Then the states of the enum are grouping where the
Piece (sub)class can have, like the Bitwise and Arithmetic you showed.Constructor of the enum is vararg, so you can give up as many classes as you want with one group.
We create an instance of the class in the constructor with reflection.
At the moment I saw that all your classes have an constructor with 2 ints, so I rely that is for all the implementations of like that.
An IllegalArgumentException is thrown when your enum can't be created by an fault (class not found, constructor not present,...)
You can also just skip that class at instanciation but then you never know when something went wrong.
At last, just ask
PieceGroups.BITWISE.getClasses() and you will have a set of the corresponding group.Code Snippets
public enum PieceGroups{
BITWISE(BitwiseAnd.class, BitwiseNand.class, BitwiseNor.class, BitwiseNot.class,
BitwiseOr.class, BitwiseXor.class, BitwiseXnor.class, BitwiseLeftshift.class,
BitwiseRightshift.class),
ARITHMETIC(Add.class, Substract.class, Multiply.class, Divide.class, Modulo.class, Random.class);
private Set<Piece> classSet = new HashSet<Piece>();
private PieceGroups(Class... classes) {
for (Class theClass : classes) {
try {
Constructor construtor = theClass.getDeclaredConstructor(int.class, int.class);
classSet.add((Piece) construtor.newInstance(0, 0));
} catch (NoSuchMethodException ex) {
processException();
} catch (SecurityException ex) {
processException();
} catch (InstantiationException ex) {
processException();
} catch (IllegalAccessException ex) {
processException();
} catch (IllegalArgumentException ex) {
processException();
} catch (InvocationTargetException ex) {
processException();
}
}
}
public Set<Piece> getClasses () {
return classSet;
}
private void processException () {
throw new IllegalArgumentException("Something went wrong with the init of the Enum");
}
}Context
StackExchange Code Review Q#48541, answer score: 5
Revisions (0)
No revisions yet.