user3466354
user3466354

Reputation: 23

Passing functions to classes

I have a java form implemented using swing on which I want to place a number of panels in which I can draw on using the graphics2D package.

To do this, I implement the panels using an extension of JPanel thus:

public class GraphicsPanel  extends JPanel
{

    public void paintComponent(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g;
        super.paintComponent(g2d);

        // Need to specify a function from the calling class here
        MethodFromCallingClass();
    }
}

In the calling class I have

public GraphicsPanel Graphics1= new GraphicsPanel() ;

public void Graphics1_Paint()
{
   // Code to draw stuff on the Graphics1 panel
}

So question is how do I pass the function (Graphics1_Paint) from the calling class to the GraphicsPanel class?

I've tried reading about interfaces and lambdas but so far they make no sense.

Can anyone enlighten me please.

Upvotes: 1

Views: 81

Answers (3)

user3466354
user3466354

Reputation: 23

I seem to have solved the problem, but I'd like comments on usability and good practice

 public class CallingClass
  {
   public JPanel Graphics1 ;

   public CallingClass()
    {

       Graphics1 = new Graphics1_Paint();
    }

  public class Graphics1_Paint extends JPanel
   {
    public Graphics2D g2d;

    public void paintComponent (Graphics g)
    {
        g2d = (Graphics2D) g;
        super.paintComponent(g2d);
        g2d.drawString("From Calling Class",10,10);
    }

  }

public static void main(String[] args){
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            new CallingClass();}
    });
}

Seems I don't need my GraphicsPanel class after all.

Upvotes: 0

NESPowerGlove
NESPowerGlove

Reputation: 5496

So it sounds like you want to define what is drawn outside of the custom JPanel class, where you can pass what you want drawn to the JPanel instance at anytime. This is possible.

First, define an interface that contains one method that draws with a Graphics2D instance:

public interface DrawGraphics()
{
    public void draw(Graphics2D g);
}

Next you'll want to extend your GraphicsPanel a bit to have the ability to change an underlying instance of DrawGraphics.

So your constructor should now be:

public GraphicsPanel(DrawGraphics graphicsToDraw) { ...

You should also have a set method for the DrawGraphics stored so you can change it at anytime:

public void setDrawGraphics(DrawGraphics newDrawGraphics) { ...

Make sure you add some synchronization somewhere here, or create all DrawGraphics on the EDT because the paintComponents method will execute on the EDT.

Next the paintComponents method can simply draw the graphics:

public void paintComponent(Graphics g)   
{
    Graphics2D g2d = (Graphics2D) g;
    super.paintComponent(g2d);

    // Need to specify a function from the calling class here
    graphicsToDraw(g2d);
}

And when you need to change the DrawGraphics:

// Calling from the EDT
myGraphicsPanel.setDrawGraphics(g -> g.drawString("Hello World!", 50, 50);

Upvotes: 0

Elliott Frisch
Elliott Frisch

Reputation: 201447

I think the easiest way is to pass the calling class (or some other interface) to the constructor of your GraphicsPanel like

public class GraphicsPanel extends JPanel {
    private CallingClass cc;
    public GraphicsPanel(CallingClass cc) {
        this.cc = cc;
    }
    public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        super.paintComponent(g2d);    
        cc.MethodFromCallingClass(); // <-- invoke a call-back.
    }
}

Upvotes: 1

Related Questions