Monday, December 12, 2011

Semester is almost over!

DOWNLOAD: Observable Sort Project

It has been a LONG semester. 32 hour work weeks + 12 units = BUSY. But, I came out of it a much stronger developer! Work in C#, PHP, Javascript, and of course, JAVA.

Here is a small sample from the "Observable Sort" program a partner and I wrote this semester. The program has a full GUI interface and allows users to watch sorting algorithms side by side and compare what each "looks" like.

 Main Class -- ObservableSortTest.java:

//Javadoc COMPLETE -- 12/3/2011

/**
 * @Author Jason Campos
 */


import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

import cs151.project1.ObservableSortDriver;
import cs151.project1.gui.MenuGUI;
import cs151.project1.quantifiable.InventoryItem;
import cs151.project1.quantifiable.qInteger;
import cs151.project1.quantifiable.qString;
import cs151.project1.sorters.bubblesort.BubbleSort;
import cs151.project1.sorters.cocktailsort.CocktailSort;
import cs151.project1.sorters.heapsort.HeapSort;
import cs151.project1.sorters.insertionsort.InsertionSort;
import cs151.project1.sorters.mergesort.MergeSort;
import cs151.project1.sorters.quicksort.Quicksort;
import cs151.project1.sorters.ripplesort.RippleSort;
import cs151.project1.sorters.selectionsort.SelectionSort;
import cs151.project1.views.GraphView;
import cs151.project1.views.LineView;
import cs151.project1.views.PointView;
import cs151.project1.views.TowerView;
import cs151.project1.views.WebView;

public class ObservableSortTest {
    public static ArrayList<Class<?>> sorters;
    public static ArrayList<Class<?>> graphs;
    public static ArrayList<Class<?>> quantifiables;
   
    /**
     * Main method. Displays the GUI menu for the values initialized in init() and the driver that powers the visualizations.
     *
     * @param args
     * @throws InterruptedException
     * @throws SecurityException
     * @throws IllegalArgumentException
     * @throws NoSuchMethodException
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public static void main (String args[]) throws InterruptedException, SecurityException, IllegalArgumentException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException{
        System.out.println("Intializing...");
        init();
        while (ObservableSortDriver.IS_READY == false ){ // restart if ObservableSortDriver is reset
            MenuGUI menu = new MenuGUI(sorters, graphs, quantifiables);
            Thread t = new Thread(menu, "Observable Sort Menu");
            t.start();
            ObservableSortDriver d = new ObservableSortDriver();
            d.run();
            while(ObservableSortDriver.IS_READY == true) { Thread.sleep(1000); } // pause
        }
    }

    /**
     * This method initializes all necessary classes for ObservableSort. To add a new item to
     * the menu (sort, data, or graph), enter the class name in to the appropriate array below.
     * @throws SecurityException
     * @throws IllegalArgumentException
     * @throws NoSuchMethodException
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws InterruptedException
     */
    public static void init() throws SecurityException, IllegalArgumentException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException, InterruptedException {
        sorters       = new ArrayList<Class<?>>();
        graphs           = new ArrayList<Class<?>>();
        quantifiables = new ArrayList<Class<?>>();
       
        /* ADD SORTING CLASSES TO THE LIST */
        System.out.println("Creating sorter classes");
        sorters.add(Quicksort.class);
        sorters.add(SelectionSort.class);
        sorters.add(InsertionSort.class);
        sorters.add(CocktailSort.class);
        sorters.add(RippleSort.class);
        sorters.add(BubbleSort.class);
        sorters.add(MergeSort.class);
        sorters.add(HeapSort.class);
       
        /* ADD GRAPHS TO THE LIST */
        graphs.add(TowerView.class);
        graphs.add(GraphView.class);
        graphs.add(PointView.class);
        graphs.add(LineView.class);
        graphs.add(WebView.class);
       
        /* ADD QUANTIFIABLE CLASSES TO THE LIST */
        quantifiables.add(InventoryItem.class);
        quantifiables.add(qString.class);
        quantifiables.add(qInteger.class);
    }
}

ObservableSortDriver.java

// JAVADOC COMPLETE 12/3/2011
package cs151.project1;
/**
 * @Author Jason Campos
 */

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.JTableHeader;

import cs151.project1.views.ObserverGraph;

/**
 * This class creates the JFrame which holds all animations, creates the SortVisualizations based on input from
 * the MenuGUI, manages threads which contain those animations. Invoking this class' run() method sends the class into
 * a state of waiting which is terminated when the IS_READY flag is flipped to true (in this case, done by MenuGUI when
 * the "run" button is clicked).
 *
 * @author Jason Campos, Vuong Scott Tran
 *
 */
@SuppressWarnings("rawtypes")
public class ObservableSortDriver{
    /** Sort classes selected for visualization */
    public static ArrayList<Class> chosenSorts = new ArrayList<Class>();
    /** Graph class selected for visualization */
    public static Class chosenGraph;
    /** Comparable data to sort */
    public static Comparable<?>[] chosenData;
    /** Flag inidacting whether or not chosenSorts, chosenGraph, and chosenData are ready to be processed */
    public static boolean IS_READY = false ;
   
    /**
     * Creates a JFrame which holds all animations and a set of threads to place
     * SortVisualizations in.
     *
     * @throws InterruptedException
     */
    public ObservableSortDriver() throws InterruptedException{
        appFrame = new JFrame();
        threads  = new ArrayList<Thread>();
        sorters = new ArrayList<ObservableSort<?>>();
    }
   
    /**
     * Sets visibility of the application frame.
     * @param b - true/false flag for visibility of the application frame
     */
    public void setVisible(boolean b){
        appFrame.setVisible(b);
    }
   
    /**
     * Waits for the IS_READY flag to be changed by an external thread. Upon this flag being flipped,
     * the application frame is constructed, SortVisualizations are built, and their threads are executed.
     */
    @SuppressWarnings("unchecked")
    public void run() {
        while (!IS_READY)
        {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
       
        initializeDimensions(chosenSorts.size());
       
        for (Class<?> s: chosenSorts)
        {
            SortVisualization visualization = null;
            try {
                if (DATA_FORMAT == DATA_COLLECTION_TYPE.ARRAY){
                    visualization = new SortVisualization(
                            (ObservableSort) s.getConstructor(new Class[] { }).newInstance(),
                            (ObserverGraph) chosenGraph.getConstructor(new Class[] { }).newInstance()
                            , chosenData.clone()
                        );
                }
                else if (DATA_FORMAT == DATA_COLLECTION_TYPE.LIST){
                    List<Comparable<?>> dataAsList = Arrays.asList(chosenData);
                    visualization = new SortVisualization(
                            (ObservableSort) s.getConstructor(new Class[] { }).newInstance(),
                            (ObserverGraph) chosenGraph.getConstructor(new Class[] { }).newInstance()
                            , dataAsList
                        );
                }
                sorters.add(visualization.getSorter());
                appFrame.add(visualization.getGraph(WINDOW_WIDTH, WINDOW_HEIGHT));
                threads.add(new Thread(visualization, s.getSimpleName()));
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }

        setVisible(true);   
       
        for (Thread t: threads){
            t.setPriority(Thread.MAX_PRIORITY);
            t.start();
        }
       
        for (Thread t: threads){
            try {
                t.join();
            } catch (InterruptedException e) {
                completedSort = false;
                System.out.println(e.getMessage());
            }   
        }
       
        appFrame.dispose();
        displayResults(getResultsTable(chosenSorts));
    }

    /**
     * Returns a JTable
     * @param chosenSorts the chosen sorts by user
     */
    public JTable getResultsTable(ArrayList<Class> chosenSorts)
    {
        if (!completedSort)
            return null;
       
        // Now perform a quick insertion sort on the list
        // Sort by specified index
        for (int i = 1; i < sorters.size(); i++){
            ObservableSort<?> subject = sorters.get(i);
            for (int j = 0; j < i; j++)
            {
                ObservableSort<?> comparison = sorters.get(j);
                boolean toSwap = false;

                if (sortResultsBy == SORT_RESULTS_BY.COMPARISONS)
                    toSwap = subject.getComparisons() < comparison.getComparisons();
                else if (sortResultsBy == SORT_RESULTS_BY.SWAPS)
                    toSwap = subject.getSwaps() < comparison.getSwaps();
                else //sort by time
                    toSwap = subject.getElapsedTime() < comparison.getElapsedTime();
               
                if (toSwap){
                    sorters.set(i,comparison);
                    sorters.set(j,subject);
                    subject = comparison;
                }
            }
        }
       
        // Create results table values
        int i = 0;
        final String[] columnNames = {"Name", "Elapsed Time", "Swaps", "Comparisons"};
        final Object[][] data = new Object[sorters.size()][];
        for (ObservableSort s: sorters)
            data[i++] = new Object[] { s.getName(), s.getElapsedTime(), s.getSwaps(), s.getComparisons() };
       
        final JTable resultsTable = new JTable(data, columnNames); // keep handle so we can sort
       
        resultsTable.setPreferredScrollableViewportSize(new Dimension(450, 16 * sorters.size()));
        resultsTable.setFillsViewportHeight(true);
        resultsTable.setEnabled(false);
       
        resultsTable.getColumnModel().getColumn(0).setPreferredWidth(150);
        resultsTable.getColumnModel().getColumn(1).setPreferredWidth(100);
        resultsTable.getColumnModel().getColumn(2).setPreferredWidth(100);
        resultsTable.getColumnModel().getColumn(3).setPreferredWidth(100);
       
        return resultsTable;
    }
   
    /**
     * Displays the results of the sorting algorithms in a JFrame
     * This method was developed by Vuong Scott Tran
     */
    public void displayResults(JTable resultsTable)
    {       
        final Font titleFont = new Font("sansserif", Font.BOLD, 18);
           
        // Construct components
        final JFrame frame = new JFrame("Sorting Algorithm Results");
        final JMenuBar menuBar = new JMenuBar();
        final JMenu fileMenu = new JMenu("File");
        final JMenuItem exitItem = new JMenuItem("Exit");
        final JButton runAgain = new JButton();
       
        // Format components
        frame.setAlwaysOnTop(true);
        frame.setLayout(new BorderLayout());
        frame.setJMenuBar(menuBar);
       
        // Set text/labels
        runAgain.setText("Return to Menu");
       
        // Build components
        menuBar.add(fileMenu);
        fileMenu.add(exitItem);
        final JScrollPane results = new JScrollPane(resultsTable);
        results.setBorder(BorderFactory.createTitledBorder(null, "Results", 0, 0, titleFont));
        frame.add(results, BorderLayout.NORTH);
        frame.add(runAgain, BorderLayout.SOUTH);
       
        final JTableHeader header = resultsTable.getTableHeader();
        header.setReorderingAllowed(false);
        header.addMouseListener(new MouseAdapter()
        {
            public void mouseClicked(MouseEvent e)
            {
                int column = header.columnAtPoint(e.getPoint());
                if (column == 1)
                    sortResultsBy = SORT_RESULTS_BY.TIME;
                else if (column == 2)
                    sortResultsBy = SORT_RESULTS_BY.SWAPS;
                else if (column == 3)
                    sortResultsBy = SORT_RESULTS_BY.COMPARISONS;
               
                displayResults(getResultsTable(chosenSorts));
                frame.dispose();
            }
        });
   
        // Display
        frame.pack();
        frame.setLocationRelativeTo(null); 
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       
        // Set listeners
        exitItem.addActionListener(new
           ActionListener()
           {
              public void actionPerformed(ActionEvent event)
              {
                 System.exit(0);
              }
           });
      
        runAgain.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent arg0) {
                try {
                    ObservableSortDriver.RESET();
                    frame.dispose();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
   
    /**
     * Sets the size of the Comparable[] data array
     * @see DATA_SIZE
     * @param i
     */
    public static void setDataSize(int i){
        SIZE = i;
    }
   
    /**
     * Gets the size of the Comparable[] data array
     * @return @see DATA_SIZE
     */
    public static int getDataSize(){
        return SIZE;
    }

    public static int getDataCollectionType(){
        return DATA_FORMAT;
    }

    public static void setDataCollectionType(int format){
        DATA_FORMAT = format;
    }
   
    /**
     * Specifies constant values for data size.
     * @author Jason Campos
     */
    public static final class DATA_SIZE {
        /** Sort 25 items */
        public static final int SMALL = 25;
        /** Sort 50 items */
        public static final int MEDIUM = 50;
        /** Sort 100 items */
        public static final int LARGE = 100;
        /** Do not allow class instantiation */
        private DATA_SIZE(){
            throw new AssertionError("DATA_SIZE");
        }
    }
   
    /**
     * Specifies constant values for result sorting
     * @author Jason Campos
     */
    public static final class SORT_RESULTS_BY {
        /** Sort by fastest completion time */
        public static final int TIME = 0;
        /** Sort by least number of swaps */
        public static final int SWAPS = 1;
        /** Sort by least number of comparisons */
        public static final int COMPARISONS = 2;
        /** Do not allow class instantiation */
        private SORT_RESULTS_BY(){
            throw new AssertionError("Cannot instantiate class SORT_RESULTS_BY");
        }
    }
   
    /** Specifies what type of data is being sorted */
    public static final class DATA_COLLECTION_TYPE {
        /** Sort an array */
        public static final int ARRAY = 0;
        /** Sort a {@link java.util.List} */
        public static final int LIST = 1;
        /** Do not allow class instantiation */
        private DATA_COLLECTION_TYPE(){
            throw new AssertionError("Cannot instantiate class DATA_COLLECTION_TYPE");
        }
    }

    /**
     * Establishes the number of columns and rows to display based on the number of desired windows to display.
     * @param windows -- number of disired windows to display
     */
    private void initializeDimensions(int windows){
        System.out.println("Setting graph dimensions");
        // Adjust window size based on # of sorters
        // First just add a column. If there is still not enough room, add another row also
        while (windows > ROWS * COLUMNS){
            COLUMNS++;
            if (windows > ROWS * COLUMNS)
                ROWS++;
        }       
        WINDOW_WIDTH  = (int) SCREEN_WIDTH / COLUMNS;
        WINDOW_HEIGHT = (int) SCREEN_HEIGHT / ROWS;
        appFrame = new JFrame();
        appFrame.setSize((int) SCREEN_WIDTH, (int) SCREEN_HEIGHT);
        GridLayout l = new GridLayout(ROWS, COLUMNS);
        l.preferredLayoutSize(appFrame);
        l.setHgap(3);
        appFrame.setLayout(l);
        appFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    /**
     * Resets all static variables to their default state.
     */
    private static void RESET(){
        ObservableSortDriver.IS_READY = false;
        ObservableSortDriver.chosenData = null;
        ObservableSortDriver.chosenGraph = null;
        ObservableSortDriver.chosenSorts = new ArrayList<Class>();
        COLUMNS = 1;
        ROWS = 1;
    }

    private JFrame appFrame;
    private ArrayList<Thread> threads;
    private ArrayList<ObservableSort<?>> sorters;
    private boolean completedSort = true;
   
    private static int COLUMNS = 1;
    private static int ROWS = 1;
    private static int WINDOW_WIDTH;
    private static int WINDOW_HEIGHT;
    private static int SIZE = DATA_SIZE.MEDIUM;
    private static int sortResultsBy = SORT_RESULTS_BY.TIME;
    private static int DATA_FORMAT = DATA_COLLECTION_TYPE.ARRAY;
    private static final double SCREEN_WIDTH = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
    private static final double SCREEN_HEIGHT = Toolkit.getDefaultToolkit().getScreenSize().getHeight();
}


Needless to say, there is quite a bit more to it, but I will get around to posting that soon!

Sunday, July 24, 2011

Class Definition - Queue

Now we get into something a bit more interesting. It is time to create the queue class that will be used to store the Category and Question objects that will comprise the parsed XML file (or SQLite DB entries).


This will also serve as a quick tutorial on how to use Java generic types. A generic type is basically like having a variable Object type for your class. This may sound a bit confusing, but they are fairly simple to use. The code for this class will illustrate this. Namely, you will see this:


public class Queue

This says, "this is a Queue which stores items T which extends (or implements) Comparable." To create an instance of this class, you would do as was done in the Category class.


Queue questions = new Queue();

This ensures that every Object in "questions" is a Question Object. To see how to build the rest of the class using the variable T, see the code below.

Since this class is going to be used as a queue, we will build it as a FIFO structure (first item in is the first item out). It will have a enqueue(x) method which adds new items to the back of the queue and a dequeue() method which returns the item from the front of the queue (think of it as, "next please!"). We will also add some other methods for retrieving data from the queue such as a get() method which will return the item from the front of the queue without removing it, a getLast() method which will do the same for the last, a getByIndex(i) method, and a getByString(s) method. Finally, a getLength() method will tell how many items are in the queue. The class also contains a private class called TNode which will simply store an Object of type T and a link to the next item in the queue (think of it as holding hands and looking backwards (can't see whats in front)).




@SuppressWarnings("rawtypes")
public class Queue <T extends Comparable>
{
/*** Description ***
* FIFO list of items of type T. 
* Held together by private class TNode
* Items are added to the back of the list and pulled from the front

***  Variables ***
* #root - The first item in the list
* #end - The last item in the list
* #length - The number of items in the list

*** Methods *** 

* #Constructor - No argument. Initializes all variables to default values. 
* #push - add item of type T to the end of the list.
* #pop  - remove item of type T from the front of the list.
* #get  - get item of type T from the front of the list (without removing)
* #getFromIndex - get the nth item from the list
* #getByValue - find a node which matches the passed argument of type T.

*** Classes ***
*
* TNode
*/
protected TNode root;
protected TNode end; 

int length;

public Queue()
{
this.root = null;
this.end = null;
this.length = 0;
}

public void enqueue(T item)
{
TNode newNode = new TNode(item);
if (root == null)
{
root = newNode;
}
else
{
end.next = newNode;
}
end = newNode;
length++;
}

public T dequeue()
{
T returnVal;

if (root == null)
return null;

returnVal = root.get();
root = root.next;

length --;
return returnVal;
}

public T get()
{
if (root == null)
return null;

return root.get();
}

public T getByIndex(int i)
{
TNode currNode = root;
if (root == null)
return null;

for (int j = 0; j < i; j++)
{
currNode = currNode.next;

if (currNode == null)
return null;
}

return currNode.get();
}

public T getByString (String str)
{
TNode currNode = root;


while (currNode != null)
{
if (currNode.get().toString().equalsIgnoreCase(str))
{
return currNode.get();
}
currNode = currNode.next;
}

return null;
}

public T getLast()
{
if (end == null)
return null;

return end.item;
}

public int getLength()
{
return length;
}

public void join(Queue<T> queue)
{
end.next = queue.root;
}

public void remove(int i)
{
if (i == 0)
root = root.next;
else
{
TNode t = getNodeByIndex(i-1);

if (i == length)
{
end = t;
t.next = null;
}
else // just skip the next node to remove it
{   
t.next = t.next.next;
}
}
length --;
}

protected TNode getNodeByIndex(int i)
{
TNode currNode = root;
if (root == null)
return null;

if (i < 0)
return root;

for (int j = 0; j < i; j++)
{
currNode = currNode.next;

if (currNode == null)
return null;
}

return currNode;


protected class TNode
/*** Description ***
* This class represents a single node in a one directional list of type T. 

*** Methods ***
* #Constructor: expects an item of type T
* #get: returns item of type T from the node

*** Variables ***
* #item: item of type T held by the node
* #next: next node in the list
****
*/
{
protected T item;
protected TNode next;


public TNode (T item)
{
this.item = item;
this.next = null;
}

public T get()
{
return item; 
}
}
}




< Back to Question class definition

Saturday, July 23, 2011

Class Definition - Question

Another straightforward class definition. A question has its text, a set of answers and "knows" which is the correct answer, an associated level of difficulty, and it may or may not have an image as part of the question. The setter and getter methods are very straightforward except for the image setter which must first check whether the passed argument has a valid image associated with it located in the drawable resources. 


Again, if there is something here you do not follow just ask and I will respond. 


import android.content.Context;
import android.graphics.drawable.Drawable;


@SuppressWarnings("rawtypes")
public class Question implements Comparable
{
/*** Description *** 
* This class represents a single question and set of answers.

*** Attributes *** 
* cAnswer  - Index (in answers[]) of correct answer to question
* answers  - Array of strings representing a set of possible answers
* question - String representing the question text
* image - Drawable image created from imageSrc passed in constructor
* level - Integer level number representing the minimum level this question is available at
* c - context
* answerIndex - used to add answers to array

*** Methods ***
* Constructor - intitializes all items to default values

* checkAnswer - returns true when submitted integer representing an array index
* matches cAnswer

* setQuestion, setCAnswer, setImage, addAnswer - setter methods

* getAnswers  - Accessor method which returns answers
* getQuestion - Accessor method which returns question
* getImage    - Accessor method which returns image
* getCAnswer  - Accessor method which returns cAnswer

* compareTo   - Returns true only when comparing to same object
*/
private int cAnswer;  
private int answerIndex;
private int level;
private String [] answers; 
private String question;
private Drawable image;
private Context c;

public Question (Context c)
{
this.cAnswer = -1; 
this.question = null;
this.image = null;
this.answers = new String[c.getResources().getInteger(R.integer.max_answers)];
this.answerIndex = 0;
this.level = -1;
this.c = c;
}

public void setQuestion(String q)
{
this.question = q;
}

public void setCAnswer(int i)
{
this.cAnswer = i;
}

public void setLevel(int l)
{
this.level = l;
}

public void setImage (String imageName)
{


int id = c.getResources().getIdentifier(imageName, "drawable", c.getPackageName());
if (id != 0)
{
this.image = c.getResources().getDrawable(id);
}
else
this.image = null;

}

public void addAnswer (String a)
{
this.answers[answerIndex++] = a;
}

public String [] getAnswers()
{
return answers;
}

public String getQuestion()
{
return question;
}

public Drawable getImage()
{
return image;
}

public int getCAnswer()
{
return cAnswer;
}

public int getLevel()
{
return level;
}


public int compareTo(Object another) 
{
// TODO Auto-generated method stub


if (this.equals(another))
return 0;
else 
return -1;
}
}


Continue to Queue class definition >
< Back to Class Definition - Category 

Class Definition - Category

This section will define the Category class. I don't believe anything in this section is  particularly challenging if you have read my previous post about this project, so I will simply post the code. If you have questions, please ask and I will respond.  Remember, this is being written for Android so we need to include a Context and we fetch resources from XML files using the Context.getResources() method. If you aren't familar with Android or want to do this project for console, you can omit anything to do with Context and replace the getResources() call with a variable or integer value. 


import android.content.Context;


@SuppressWarnings("rawtypes")
public class Category implements Comparable
/***
 *** Description ***
 *
 * This class defines a Category object. Each Category contains a name, a list of questions, 
 * and an array of integers representing the number of questions at each difficulty level. 
 * 
 *** Attributes ***
 *
 * String name     - The name of the category
 * int [] levels   - The number of questions at each difficulty level
 * Queue<Question> - A Queue<T> of Question objects 
 * 
 *** Methods ***
 *
 * Constructor: Requires a context and a name. Initializes all attributes. 
 * 
 * addQuestion: Increments the appropriate levels[] index and enqueues the passed Question. 
 * getName: Returns the name
 * getQuestionsAtLevel: returns the number of questions available at the passed integer difficult level
 * getQuestions: Returns the Queue<Question> object
 * toString: returns name
 * compareTo: returns -1 if passed object is not a category, 1 if it is a different Category, or 0 if the same
 * 
 */
{
private String name;
private int [] levels; // levels[0] = easy; levels[1] = normal; levels[2] = genius
private Queue<Question> questions;

public Category (Context c, String name)
{
this.name = name;
this.levels = new int[c.getResources().getInteger(R.integer.number_of_levels)];
this.questions = new Queue<Question>();
}

public void addQuestion (Question q)
{
levels[q.getLevel()]++;
questions.enqueue(q);
}

public String getName()
{
return name;
}

public int getQuestionsAtLevel(int j)
{
int numQs = 0;
for (int i = 0; i <= j; i++)
numQs+= levels[i];
return numQs;
}

public Queue<Question> getQuestions()
{
return questions;
}


public int compareTo(Object another) {
if (another instanceof Category)
{


if (this.toString().equals(another.toString()))
{
return 0;
}
else
return 1;
}
return -1;
}

public String toString()
{
return name;
}
}

Continue to Class Definition - Question >
< Back to Q and A System Take 2