I’m working on an assignment for CS124 (Software Development) where we have to create a 2D Animation Suite in Java. The basic outline is fairly simple and was pretty easy to figure out and build up. So, I went on to add additional features.
Most of these have been added quite quickly or not needed much thought. Notably, extra tools, a bunch of functionality in the menu for the Suite and some crafty stuff with flicking through the frames. I have a few more plans of what I want to add before I can call this ‘finished’ just yet though.
One of the main things I wanted to get to doing was creating a larger colour palette.
I started with 3 colours, then moved up to 7. I was originally just showing the user some colours on JButtons that corresponded to chars in the Model that would be set in a 2D char array to serve as a ‘grid’. As effective as this was, the code looked like it needed a lot of refactoring and I wanted to expand my colour palette much further. I played around with JColorChooser. It’s a great feature! However, I didn’t want that much functionality and so my quest began to find my own way..!
Firstly, I created my own class (MyColor) that inherited Java’s Color class and added a constructor to it that took r, g, b, char and then I added a method to return said char. After this I made another class (ColorHolder) to hold 36 of these colours (r 0-255, r 0-255 + b 0-255, etc) and handle any operations of iterating through the collection of them and getting whatever colour the user wished to use/the application required.
In the previous design I had each JButton for the char colours set separately (i.e. redButton = new JButton(“red”), yellowButton = new JButton(“yellow”), etc), with each assigned with ActionListener(this). This made the code feel very clunky and I knew it could be cut down a lot.
To save code, in the new system each colour is an instance of a single JButton, colorButton, and with each created they are stored in an ArrayList<JButton> and then added to the JPanel. A normal ActionListener assignment doesn’t work for this (it only gets set for the last element) and so I had to hunt down how best to get this method to work.
To overcome the problem, I wrote my own Inner class called ColorListener, inheriting from MouseAdapter. In this I wrote a constructor to take the ‘index’ location of the JButtons/colours as they were added. When the user clicks on a JButton, the ColorListener gets the source (left/right button for correct assignment) and gets the colour that is stored in the ArrayList at the index of the JButton in the list from ColorListener.
From there it was simply a case of calling the ‘getChar()‘ method I made in the MyColor class to use with the assignment specifications of using chars in a 2D array for the grid of colours and passing it to my Model.
The re-writing on my code took some time in order to get everything to settle back to how it was but converting the old system to the new was not too difficult. The tricky part was dealing with black/white.
When a user calls to use ‘White’, what the program actually needs to do is use ‘Black’ with a drawRectangle method as opposed to fillRectangle like every other colour. Due to the way I have created MyColor, White is actually ‘White’ (0, 0, 0). When the Model read the char for White, it was then creating a completely blank grid (in truth, the grid was there, just White lines for the drawing!). This lead to a number of S.o.P.s to find out if there really was a color there before I realized what I needed to do.
Solution: setColor(Color.black). Rather than using my own MyColor for this one method, the simplest solution was to go back to using Color and pretend black is the new white! It felt a bit like cheating, but it works and is functional and so, that is that!
I have a number of other extra bits I want to add yet and I’m pretty sure I’ll be breaking another thing or two before I get done. The upside to this? It’s fun!