package ce.ass2;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import ce.board.Board;
import ce.board.MoveData;
import java.awt.Color;
import javax.swing.JButton;


public class TickerBean extends JButton implements java.io.Serializable{

    int timeDelay=500;
    private LifeBean lb=new LifeBean();
    private Board tickerBoard;
    private javax.swing.Timer t = new javax.swing.Timer(timeDelay, new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            try {
                
                tickerBoard=lb.getBoard(); // <==========>

                System.out.println("tickerBoard is " + tickerBoard);
                //lb.setBoard(boardRef);
                
                if (tickerBoard!=null) {
                    lb.step();
                }
                else
                    System.out.println("ticker is null");
            } catch (Exception ex) {
                System.out.println("ticker bean step failed!");
                System.out.println(ex);
            }
          }
       });
    public TickerBean() {
        super("TickerBean");	// Setting the bean's label
		setEnabled(false);	// Can't be clicked
		setBorderPainted(false);	// Make it look less like a button


    }

    public void start() {
       
        t.start();
        

    }

    public void stop() {
        t.stop();

    }

    public void setBoard(Board board) {
        tickerBoard=board;
    }

}
package ce.ass2;

import ce.board.Board;
import ce.board.MoveData;
import java.awt.Color;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;




public class LifeBean extends JButton implements Cloneable,Serializable
 {


	private Board boardRef;
	private int boardSize = 21;	// 21x21 cells
	private int cellSize = 16;  // 16x16 pixels
	private boolean gameInited = false;
	private Color[][] clearBoardColours;	// Colours for a clear board
    private Color[][] currentBoardColours = new Color[boardSize][boardSize];
    private Color[][] tempBoardColours = new Color[boardSize][boardSize];
    private int counter=0;
    private final PropertyChangeSupport property = new PropertyChangeSupport( this );


	/**
	 * No-argument constructor.  Every bean must have a no-argument constructor.
	 */
	public LifeBean() {
		super("LifeBean");	// Setting the bean's label
		setEnabled(false);	// Can't be clicked
		setBorderPainted(false);	// Make it look less like a button
	}

	/**	Set the board bean with which this LifeBean bean is interacting.
	 *	This method initialises the board, calling its setBoard() method.
	 *
	 * @param boardRef the board
	 */
	public void setBoard(Board boardRef) {
		this.boardRef = boardRef;
		clearBoardColours = new Color[boardSize][boardSize];
		for (int i = 0; i < boardSize; i++) {
			for (int j = 0; j < boardSize; j++) {
				clearBoardColours[i][j] = Color.white;
                currentBoardColours[i][j]=Color.white;
                               
			}
		}
        System.out.append("==== >> reset");
		boardRef.initBoard(boardSize, cellSize, clearBoardColours);
		gameInited = true;
        System.out.println("board set" + boardRef + gameInited);
	}

	/** Return a reference to the board bean.
	 *
	 */
	public Board getBoard() {
		return this.boardRef;
	}

	/** Process one move.	 Called as a result of the player making a move on the
	 * board.	This method first determines whether the move is valid.	 If the move
	 * is invalid, it calls the board's update() method indicating an invalid
	 * move.	If the move is valid, the update() call indicates a valid move and
	 * sends one or more updates to the board for display.
	 *
	 *
	 * @param md the move
	 */
	public void move(MoveData md) throws Exception {
        
		if (!gameInited) {
			return;
		}
		boolean valid = valid(md);
		if (!valid) {
			boardRef.invalidMove();
		} else {
            

//            System.out.println("@@@@@@@@@ update tempboard @@@@@@@@@@@ ");
			boardRef.update(md.sourceRow, md.sourceCol, Color.gray);
            currentBoardColours[md.sourceRow][md.sourceCol]= Color.gray;
            //tempBoardColours[md.sourceRow][md.sourceCol]= Color.gray;
		// For this example, just colour the square
		}
       
        tempBoardColours=(Color[][]) ObjectCloner.deepCopy(currentBoardColours);
	}

	/**	Step board one cycle according to the rules of the game */
	public void step() throws Exception {
		if (!gameInited) {
			return;
		} else {
			/* Apply the rules of the game and update the board.  You can update the
			 * board using a series of calls to updateBoard() or a call to initBoard().
			 */
            

            for (int r=0 ; r<boardSize ; r++)	{                
                for (int c=0 ; c<boardSize ; c++)	{                    
                    if (currentBoardColours[r][c]==Color.gray) {
[c]==Color.gray);
                        if (isSurvive(r,c)) { // remain alive
                            tempBoardColours[r][c]=Color.gray;
                        } else { // is dead
                            tempBoardColours[r][c]=Color.white;
                            currentBoardColours[r][c]=Color.gray;

                        }
                    }

                    else {
                        if (isBorn(r,c)) {                            
                            tempBoardColours[r][c]=Color.gray;                        
                        }

                }


            }
         }
            clear();
            for (int r=0 ; r<boardSize ; r++)	{
                for (int c=0 ; c<boardSize ; c++)	{
                    if (tempBoardColours[r][c]==Color.gray) {
                        currentBoardColours[r][c]=Color.gray;
//                        System.out.println("r=" + r + " c=" + c);
                    }
                }
            }
            boardRef.initBoard(boardSize, cellSize, tempBoardColours);
//            System.out.println("######### update currentboard ########3 ");

		}
        
      
	}

     private boolean isBorn(int r, int c) {
        counter =0;
        check(r-1,c-1);
        check(r-1,c);
        check(r-1,c+1);
        check(r,c-1);
        check(r,c+1);
        check(r+1,c-1);
        check(r+1,c);
        check(r+1,c+1);
//        System.out.println(r + " " + c + "is born ==> " + (counter==3) + counter );
        return (counter==3);
         // dead cell has 3 neighburing cells alive, born new cell
    }


    private boolean isSurvive(int r, int c) {
        counter =0;
        check(r-1,c-1);
        check(r-1,c);
        check(r-1,c+1);
        check(r,c-1);
        check(r,c+1);
        check(r+1,c-1);
        check(r+1,c);
        check(r+1,c+1);
//        System.out.println(r + " " + c + "is surve ==> "
//                + (counter==3 || counter ==2) + counter );
        return counter==3 || counter ==2;
       // alive cell has 2 or 3 neighbouring cells alive, surive
    }

    private void check(int row, int col) {
        if ((row >= 0 && col >= 0) && (row < boardSize && col < boardSize)) {
             if(currentBoardColours[row][col]==Color.gray ) {
                counter++;
             }
             

        }

         
    }


	/** Determine whether the proposed move is valid.
	 */
	private boolean valid(MoveData md) {
		return true;	// For Life, no move (click) on the board is invalid
	}


    /**
    * Clearing the color from the cells which on the board.
    */
      public void clear()	{
          System.out.println("clear()" + boardRef);
         setBoard(boardRef);

         /*for (int i=0;i<boardSize;i++)	{
            for (int j=0;j<boardSize;j++)	{
               clearBoardColours[i][j] = Color.white;
            }
         } */
      }

      public void Save() {
        try
        {
            ObjectOutputStream outputStream =
                 new ObjectOutputStream(new FileOutputStream("arrayfile"));
                 Color[][] boardColours=new Color[boardSize][boardSize];
             for (int r=0 ; r<boardSize ; r++)	{
                for (int c=0 ; c<boardSize ; c++)	{
                    if (currentBoardColours[r][c]==Color.gray) {
                        boardColours[r][c]=Color.blue;
                        System.out.println(" board r=" + r + " c=" + c);
                    }
                }
            }
            outputStream.writeObject(boardColours);
            System.out.println("start printing");

           
            outputStream.close( );
        }
        catch(IOException e)
        {
            System.out.println("Error writing to file.");
            System.exit(0);
        }

         System.out.println(
                   "Array written to file arrayfile.");
      }


      public void load() throws Exception  {
        try
        {
            ObjectInputStream inputStream =
                 new ObjectInputStream(new FileInputStream("arrayfile"));
            Color[][] boardColours =
                    (Color[][])inputStream.readObject( );
                    
           for (int r=0 ; r<boardSize ; r++)	{
                for (int c=0 ; c<boardSize ; c++)	{
                    if (boardColours[r][c]!=null) {
                        currentBoardColours[r][c]=Color.gray;
                        System.out.println("current board r=" + r + " c=" + c);
                    }
                }
            }
                   
                      
          
            boardRef.initBoard(boardSize, cellSize, currentBoardColours);

            

             
            inputStream.close( );
        }
        catch(FileNotFoundException e)
        {
            System.out.println("Cannot find file arrayfile.");
            System.exit(0);
        }
        catch(ClassNotFoundException e)
        {
            System.out.println("Problems with file input.");
            System.exit(0);
        }
        catch(IOException e)
        {
            System.out.println("Problems with file input.");
            System.exit(0);
        }
      }


      public int getBoardSize() {
          return boardSize;

      }




}	 // LifeBean
import java.util.logging.Level;
import java.util.logging.Logger;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * LifeGameJFrame.java
 *
 * Created on May 5, 2009, 4:48:31 PM
 */


public class LifeGameJFrame extends javax.swing.JFrame {

    /** Creates new form LifeGameJFrame */
    public LifeGameJFrame() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        board1 = new ce.board.Board();
        lifeBean1 = new ce.ass2.LifeBean();
        tickerBean1 = new ce.ass2.TickerBean();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        try {
            board1.addMoveListener(new ce.board.MoveListener() {
                public void move(ce.board.MoveEvent evt) {
                    board1Move(evt);
                }
            });
        } catch (java.util.TooManyListenersException e1) {
            e1.printStackTrace();
        }

        lifeBean1.setBoard(board1);

        jButton1.setText("Start");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jButton2.setText("Stop");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        jButton3.setText("Step");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(52, 52, 52)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jButton1)
                            .addComponent(jButton2)
                            .addComponent(jButton3))
                        .addGap(47, 47, 47)
                        .addComponent(board1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(206, 206, 206)
                        .addComponent(lifeBean1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(69, 69, 69)
                        .addComponent(tickerBean1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(39, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(24, 24, 24)
                        .addComponent(board1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(85, 85, 85)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(lifeBean1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(tickerBean1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(42, 42, 42)
                        .addComponent(jButton1)
                        .addGap(18, 18, 18)
                        .addComponent(jButton2)
                        .addGap(18, 18, 18)
                        .addComponent(jButton3)))
                .addContainerGap(21, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>

    private void board1Move(ce.board.MoveEvent evt) {
        try {
            lifeBean1.move(board1.getMove());
        } catch (java.lang.Exception e1) {
            e1.printStackTrace();
        }
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
        tickerBean1.start();
    }

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
        tickerBean1.stop();
    }

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
        try {
            lifeBean1.step();
        } catch (java.lang.Exception e1) {
            e1.printStackTrace();
        }
    }

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new LifeGameJFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    private ce.board.Board board1;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private ce.ass2.LifeBean lifeBean1;
    private ce.ass2.TickerBean tickerBean1;
    // End of variables declaration

}

LifeGameJFrame is a container which link these beans to build an application

LifeBean is a implement the rule of life in this game

TickerBean is handling start and stop from the game with 500 miliseconds


problem:
***********************

tickerBoard=lb.getBoard(); // <==========>

***********************
my problem is why these line return me null ? can somebody explain to me ? i have tried used print out method to figure it out, but it didn't help me, is there anyway to get object from LifeBean's getBoard() in TickerBean?

Because when you call private LifeBean lb=new LifeBean(); in TickerBean only LifeBean default constructor is executed which is effectively this section

public LifeBean() {
		super("LifeBean");	// Setting the bean's label
		setEnabled(false);	// Can't be clicked
		setBorderPainted(false);	// Make it look less like a button
	}

you never actually set your board with setBoard(Board boardRef) method of LifeBoard class

ic, no wonder i keep get null from getBoard() method, is there any way to get object from getBoard() inside tickerBean ? my setBoard method will only call in container which is LifeGameJFrame

tickerBoard=lb.getBoard(); // <==========>

                System.out.println("tickerBoard is " + tickerBoard);
                //lb.setBoard(boardRef);

Many thing depends on the whole flow of application, but I guess it is safe assume that setBoard() method could be placed before tickerBoard=lb.getBoard();

i tried, it gave me null pointer exception, setBoard() required an non-null object of Board class, which is tickerBoard, my tickerBoard is null.
my initial intention was try to run LifeBean's step(), and it has failed because step() found the board is not being set up, that is why im trying to get built board which already has done by LifeGameJFrame to set up the board again. (felt a bit weird by using this way )

try {
            board1.addMoveListener(new ce.board.MoveListener() {
                public void move(ce.board.MoveEvent evt) {
                    board1Move(evt);
                }
            });
        } catch (java.util.TooManyListenersException e1) {
            e1.printStackTrace();
        }

        lifeBean1.setBoard(board1);

when runing step() in LifeBean, it worked great, but when called by TickerBean, it failed.
is there any way to run step() in TickerBean where the board that will be processed is the original board from LifeGameJFrame?


my design
======================
my tickerBean want to run step() every 500 miliseconds from LifeBean when the user click start, and it will stop when user click stop
======================

sure, no problem, after a day of figuring these issue, i used an insufficient and messy way to get the board from LifeBean to TickerBean to be processed. Would you mind to give comment on this application and it would be best if you show me your method to solve it as well, i want to see how poor my knowledge and experience on Java are. Thanks in advanced.

i missed some info to state, this application is developed by netBean IDE 6.5, it will much more easier to open them by using netBean IDE, any needed information, please let me know

Sorry I was little busy. I had look at the files you attached, but I struggling to understand your concept. When I open main directory I find two folders (LifeBean and LifeGame) plus Board.jar file.There some referencing from LifeGame to lifeBean and from LifeBean to Board.jar.

  1. Is Board.jar archive produced by you or someone else? If someone else do you have access to documentation?
  2. If you wish to use archives you should add them to project properly not just randomly attach to your improvised project structure. To do so, look for some quick notes here
  3. Why LifeGame and LifeBean are separated projects? Why the files under LifeBean are not just sub-package of LifeGame?

If you can provide me with some answers we may proceed further...

Some of varibles are not initialized

public class LifeGameJFrame extends javax.swing.JFrame {
//..
  private void initComponents() {
          board1 = new ce.board.Board();
          lifeBean1 = new ce.ass2.LifeBean();
          lifeBean1.setBoard(board1);
          tickerBean1 = new ce.ass2.TickerBean();
          tickerBean1.setLifeBean(lifeBean1);//j3c
          jButton1 = new javax.swing.JButton();
          jButton2 = new javax.swing.JButton();
          jButton3 = new javax.swing.JButton();
//...
  }
}

and throws NullPointerException.
If beans need constructors without parameters, you must apply additional methods set...(...) to fully initialize classes.
TickerBean is composite of LifeBean+Timer
Then

package ce.ass2;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;

public class TickerBean extends JButton implements java.io.Serializable {

    int timeDelay = 500;
    private LifeBean lb;
    private javax.swing.Timer t;

    public TickerBean() {
        super("TickerBean");	// Setting the bean's label
        setEnabled(false);	// Can't be clicked
        setBorderPainted(false);	// Make it look less like a button
        System.out.println("new TickerBean()");
    }

    public void start() {
        t.start();
    }

    public void stop() {
        t.stop();
    }

    private void setTimer() {
        t = new javax.swing.Timer(timeDelay, new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                lb.step();
                System.out.println("updated ~");
            }
        });
    }

    void setLifeBean(LifeBean lifeBean1) {
        lb = lifeBean1;
        setTimer();
    }
}
Attachments

quuba nice of you to finish coding, but once again you missed point of original poster working out issues rather then receiving full answer...

Here are the requirements that i need to fulfill:

Life Bean
The Life bean implements the rules of Life. It does not have any user interface: that is supplied by the
Board bean and by standard beans such as button beans. When a user clicks on a square, this will
cause the Board bean to send a move event to the Life bean. The Life bean will react by toggling the
state of the bean from dead to alive or vice-versa, and change the colour of the square to show this to
the user. This allows the user to set up an initial configuration for the simulation.
The Life bean must also implement the logic to make one step in the game – ie to go from one
generation to the next according to the rules of the game. This should be done in a step() method; the
Life bean does not provide any user interface for this, as step() will be called from another bean that is
linked to it, for example a button bean.
You should provide three further features to be eligible for full marks (not shown in the picture
above):
• Ability to save the state of the game (which squares are occupied) to a disk file, and to reload the
state from a disk file
• Ability to clear the board (all squares empty)
• Ability to configure the size of the board to anywhere from 3x3 upwards. Set a default board size
of 21x21 cells. The behaviour of Life is much more interesting with large boards, but during
development and testing it is easier to work with small boards.
The first two of these are most easily done using save(), load() and clear() methods in the Life bean,
linking in additional buttons. The last can be done easily using a property in the Life bean. However,
feel free to consider different approaches.

Ticker Bean
We want the game run by itself without having to keep clicking a button. You could of course build
this into the Life bean, but instead you are asked to produce a separate Ticker bean, which emits an
event periodically – eg once every 500 milliseconds. This can then be linked to the step() method to
achieve automatic running. This illustrates that you can develop a component for a specific
application in such a way that it can be reused elsewhere. There must be a way to configure the time
between ticks, and to start and stop it ticking.
This can be done in a similar way as for the Life bean, using a property for the delay, and methods
linked from additional buttons. A nice alternative is to let the delay be changed at run time, for
example using a JTextField bean whose value is linked to the Ticker bean.


Container Project (LifeGame)
The container project contains and links together all the beans. It is built in the NetBeans design
window for a JFrame. You should not write any code in the container project: it exists purely as an
environment to build the assembly of beans that is your application.

*note no coding is required in container


-the board.jar is given by someone else, i will upload the api of the board.jar, hopefully it helps.
-LifeBeans and TickerBeans are now with the proper jar files
-because LifeBeans and TickerBean have to be generic, it has to be designed as reused component in the future

i re-upload the files, hopefully it helps.
im still working on it until now, not much improvement on my assignment :(, i have being told that my application was designed incorrectly
i am thinking, maybe i should use addActionListener to run the LifeBean's step() from Tickerbean for my start button, not too sure on it, im still trying to understand how does addActionListener work.

Some of varibles are not initialized

public class LifeGameJFrame extends javax.swing.JFrame {
//..
  private void initComponents() {
          board1 = new ce.board.Board();
          lifeBean1 = new ce.ass2.LifeBean();
          lifeBean1.setBoard(board1);
          tickerBean1 = new ce.ass2.TickerBean();
          tickerBean1.setLifeBean(lifeBean1);//j3c
          jButton1 = new javax.swing.JButton();
          jButton2 = new javax.swing.JButton();
          jButton3 = new javax.swing.JButton();
//...



  }
}

and throws NullPointerException.
If beans need constructors without parameters, you must apply additional methods set...(...) to fully initialize classes.
TickerBean is composite of LifeBean+Timer
Then

package ce.ass2;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;

public class TickerBean extends JButton implements java.io.Serializable {

    int timeDelay = 500;
    private LifeBean lb;
    private javax.swing.Timer t;

    public TickerBean() {
        super("TickerBean");	// Setting the bean's label
        setEnabled(false);	// Can't be clicked
        setBorderPainted(false);	// Make it look less like a button
        System.out.println("new TickerBean()");
    }

    public void start() {
        t.start();
    }

    public void stop() {
        t.stop();
    }

    private void setTimer() {
        t = new javax.swing.Timer(timeDelay, new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                lb.step();
                System.out.println("updated ~");
            }
        });
    }

    void setLifeBean(LifeBean lifeBean1) {
        lb = lifeBean1;
        setTimer();
    }
}

thanks for replied, quuba, i appreciated it, but im not allow to write code LifeGame, because LifeGame is only for linking multiples beans to become an application in netbean.

Hello C41R0.
In my reply I totally lost nature of Beans. I have read carefully Ass2.pdf.
Make first in NetBeans separate TickerBean as NetBeanModule (JavaBeanComponent, generate BeanInfo). You made this.
Make TickerBean only!! as a timer.
Interesting way to recive single pulse.

javax.swing.Timer t;
t.setRepeats(false) ;
This article has been dead for over six months. Start a new discussion instead.