To create a constraint-based layout manager.
The assignment is in three parts. The first two are due on the 19th, and are designed to help you become familiar with Cassowary and layout managers.
CS6456 students: read the extra credit section. Some of the extra credit is required (and thus not really extra credit) for you.
a) Implement a simple java/swing program that creates a window with a 500x300 custom component. When you click on this component, it adds a square to it that is centered on the mouse point and is 20 units in size. The square should render itself with an identifying number in it (you might use the java class Square.java for your squares). You should set up constraints so that no squares overlap unless they have to, the squares do not move unless they have to, and the squares stay on the screen (see below).
b) Implement a simple java/swing program that creates a window with a JPanel in it that uses a custom layout manager to lay out the components inside it. Please add 20 components of different sizes to the JPanel. Your layout manager should find the maximum width and height of the child components, and divide the panel into equal sized regions equal to these maximums. It should then position the components inside these regions, starting in the upper left of the panel and moving across in the X direction until there is no full region left (i.e. if the max in the X direction is 20, then the first component should be at x=0, the second at x=20, the third at x=40 and so on). It should then move down by the Y maximum, and start a new row (i.e. if the max in the Y direction is 15, the second row should start at Y=15). Do not use extra space (i.e. if the window is 75 wide, only lay out 3 components per row, and if you run out of space in the Y direction before stopping, position the remaining components off screen.)
c) Implement a constraint-based layout manager using Cassowary. We will post a Java file (UPDATED: Monday 9:51pm) the specifies the interface you must implement; this file contains a skeleton of the class you should implement, and shows the minimum set of public methods you should define. You should submit one test program ("A3c.java"), although the TA will use addition test programs. You should define the class LayoutVariable as a subclass of ClVariable, and add any additional information you need per variable to it (you may not actually need extra information if you do not do the visualization extra credit).
Your programs should consist of a set of java files which should be commented with your name (the name you are registered under!) and ID number. The java file should implement a class "A3a", "A3b" and "A3c". The files should be emailed to cs4470@cc.gatech.edu as mime attachments to a single message.
The time the mail is received will be used to determine whether or not the program is late, so be sure to allow a couple of minutes for the mail system to transmit your file if you are working right up to the deadline.
IMPORTANT: If the TA has to edit your files you will lose points. Similarly, the TA should be able to execute the class "A3a" "A3b" and "A3c", so using any other class as your main class will result in lost points.
This programs for part a and b are due on or before Friday, October 19th, and part c is due on or before Wednesday, October 24th. This means they must be received by 11:59pm EDT to not be considered late.
a) Since you cannot create non-linear constraints with Cassowary, you cannot actually keep the rectangles from overlapping in the obvious way (contrary to what was described in class). Therefore, approximate this constraint by looking at the center points of the rectangles you are setting up the constraints for, and keeping them apart based on their initial alignment. So, if rect1 is to the left of rect2, add a constraint to keep it to the left far enough so they do not overlap (and vice versa if it is to the right). Similarly, if it is below, add a constraint to keep it below (and vice versa).
Make sure the rectangles are constrained to remain visible (i.e. in the visible part of your panel). For part a, you do not have to handle window resizing.
Make sure you draw a unique number or other identifying mark inside each rectangle so they can be differentiated.
Make sure the program does not fail, no matter how many rectangles you add. The rectangles should never leave the panel, but when things get crowded, they may overlap. Similarly, they should not move if they do not have to.
b) Your layout manager does not need to handle the alignment points, you should always align the components with the upper left corner of their region on the screen. Components should always be completely visible, or hidden (i.e. they should never be partially visible). That is the purpose of the layout described. It is also intended to be a very simple layout.
For part b, your program should handle window resize (the components should get repositioned as appropriate).
c) Your layout manager must deal with window resizing; indeed, window size changes will typically be the only size changes that the constraint manager must respond to once the layout has been set up. The variables provided by the interface to the programmer allow them to constrain their layout to the window size. You should account for the window insets, and ensure that the variables for the width and height cannot be changed by Cassowary.
Your layout manager should create 6 variables per component that is added to it; the x and y position of the component, the width and height of the component, and the x and y alignment position of the component. You will need to ensure that each time these variables changes (because the constraint system has changed, for example) that the corresponding values (x,y,width,height) are updated in the component. (HINT: Look at the ClVariable methods and see if overriding any in LayoutVariable will help). The alignment variables are there for the convenience of the programmer: if one is requested, you should ensure that its value is constrained to a pixel offset proportional to the width or height of the component (based on the value of the alignment variable in the component) (e.g., if a component has an x alignment of 0.5, you should ensure the alignment LayoutVariable is constrained to x + 0.5 * width).
Programmers will created most of the constraints they want using Cassowary's methods. However, they should not create variables, but should instead request them via the interface functions. This will allow them to be visualized reasonably in the optional parts of the assignment.
There are a few common constraints that you should implement; each of the methods should return a single constraint (even if more than one is required), and if that constraint is removed, all the associated constraints should be removed.
If a component is removed from a layout, you do not need to remove constraints containing variables that refer to that component (the programmer should).
d) Usage of Cassowary requires the cassowary.jar file.
There are some possible extra credit (some of which are required, and thus not extra credit, for the graduate student section of the class):
- In part a), add shift clicking to delete the rectangle clicked on, and control-clicking to drag a rectangle. You should update the constraint system (and thus the layout) as you drag. You must do both for extra credit.
- In part c), right-clicking anywhere in the window will toggle "debugging" mode for a component that has had debugging mode enabled (see the "debug()" method in the provided A3Layout.java file). You should use the glass pane to capture the right-click and to render the graphics. In debugging mode, you should render a representation of the constraints being used in your layout onto the glass-pane. If a constraint involves a component that is no longer in the container, it should be rendered differently (such as in red) so this is obvious. Your representation of the constraints should take into account the fact that the components are still visible. CS6456 students MUST do this as part of the basic assignment. You should visualize all constraints in as reasonable a way as you can. In particular, you should decide on a way of "rendering" each semantically different variable (there are 11: top level width/height, the 6 for each component, the 2 alignment lines, and "any other" one a programmer might create), and then decide on how to represent each constraint (you can pick some simple representation for a constraint created by the programmer, but you should do something reasonable and understandable for each of the constraints created by a method in your interface). You will need to modify the Cassowary Java files to expose enough of the internals of the constraints and expressions so you can figure out what variables are involved in a constraint when it is passed in by the programmer.