I have been looking over past exam papers for revision for an upcoming uni exam for Java and one of the questions was, asking for code to add to a given abacus program to make the grid display 3 counters in each column of a 10x6. e.g. as soon as the JPanel opens.

So far the current program enables the user to click in each column and add counters to each column, so you can do this manually but it is not the way to do it as when its run there are no counters present in the abacus grid. I am unsure as to how i can complete this correctly although i am sure it would likely be a for loop?? I know nothing about the program itself or even what everything does??

The program is in 3 classes: Test2Model, Test2Frame and Test2Panel but the panel class is the one i believe i need to add code to? Please can anybody help me understand this? This is merely revision but would be hugely helpful for me. Thanks, the Test2Panel class is included below....

class Test2Panel extends JPanel implements MouseListener
{
    Test2Model model;

    public Test2Panel()
    {
        addMouseListener(this);
        int test_num_pegs = 10;
        int test_max_counters = 6;
        model = new Test2Model(test_num_pegs, test_max_counters);

    }



    Rectangle getRect(int i,int j)
    {
        if(i<0 || j<0 || i>=model.getNumPegs() || j >=model.getMaxCounters())
            return null;

        int w = getWidth()/model.getNumPegs();
        int h = getHeight()/model.getMaxCounters();

        System.out.println("getRect: w is " + w + " and h is " + h);

        int x = i*w;
        int y = j*h;

        Rectangle r = new Rectangle(x,y,w,h);
        return r;
    }
    int getColumn(int x)
    {
        return x*model.getNumPegs()/getWidth();
    }


    public void mouseReleased(MouseEvent event)
    {
    }
    public void mousePressed(MouseEvent event)
    {
    }
    public void mouseClicked(MouseEvent event)
    {
        int b = event.getButton();
        int col = getColumn(event.getX());

        if(b==1)
        {
            model.addCounter(col);
        }
        if (b==3)
        {
            model.removeCounter(col);
        }
        repaint();
    }
    public void mouseEntered(MouseEvent event)
    {
    }
    public void mouseExited(MouseEvent event)
    {
    }



    public void paint(Graphics g)
    {
        g.setColor(Color.white);
        int w = getWidth();
        int h = getHeight();
        g.fillRect(0,0,w,h);


        Graphics2D g2 = (Graphics2D)g;

        g2.setColor(Color.black);
        for(int j = 0;j<model.getMaxCounters();j++)
        {
            for(int i = 0;i<model.getNumPegs();i++)
            {
                Rectangle r = getRect(i,j);
                g.drawRect(r.x,r.y,r.width, r.height);
            }
        }

        int max_counters = model.getMaxCounters();
        for(int i = 0;i<model.getNumPegs();i++)
        {
            int num_pegs = model.getNumCounters(i);
            for(int j = 0;j<num_pegs;j++)
            {
                Rectangle r = getRect(i,max_counters-j-1);
                g2.setColor(Color.red);
                g2.fillOval(r.x,r.y,r.width,r.height);
                g2.setColor(Color.black);
                g2.drawOval(r.x,r.y,r.width,r.height);
            }

        }


    }


    // copied from the W2MouseEvents for convenience
    // (so we can run the program from Test2Panel class too!)
    public static void main(String[] args)
    {
        Test2Frame w = new Test2Frame();
        w.setVisible(true);
    }


}

If you look at the mouseClicked method you will see how that adds a counter - there's a simple method it calls. You jiust need to call that same method 3 times for each column in your initialisation.

Edited 3 Years Ago by JamesCherrill

I was thinking that maybe there would be some way to create a method in the Model class called e.g. "addCountersToAllPegs()" then call this 3 times from the constructor of the panel class?? Although i understand that would work, I am clueless as to how to set that up??

But as you were saying i can indeed see how the addCounter method works given the X position, which then determines which column to put counters in. But calling this 3 times would only add 3 counters to one column right?

This is the expected outcome to be shown once the program is initialised. Each of the columns were clicked three times to get this image but, on a normal start up the whole grid would be empty.

9c97b9b1704a18928ea81c6efabcf81c

Yes, you could put that into a method, eg addCountersToAllPegs() - maybe addCountersToAllPegs(int numberOfCountersPerPeg) would be even cleaner becuase you can call that just once and pass in the number of pegs.
You know how many pegs there are, so you can just have a simple nested loop

// pseudo code
for peg = 0 to model.getNumPegs()-1
  for n = 1 to numberOfCountersPerPeg
     model.addCounter(peg);

Edited 3 Years Ago by JamesCherrill

This article has been dead for over six months. Start a new discussion instead.