Search code examples
javajframeactionlistenermouselistenerimplements

Using a listener class to handle all listening


I completed my Java Homework, but it was all mushed into one main class (with a couple of private classes). I'm trying to make my code more elegant by having separate classes to handle things. I'm having trouble having the listener interact with the existing panels.

The main parts I'm looking at are in the Listener.java. The mouse click and action listener. I am able to get the name of the button that was clicked to trigger the listener, which is helpful, but I can't get it to interact with the "DrawBoard" panel that was added to the Panel panel.

I'm wondering what the best way to work this interaction is:

Window.java:

import javax.swing.JFrame;
import javax.swing.JPanel;


public class Window extends JFrame {

    /**
     * 
     */
    private static final long serialVersionUID = -8255319694373975038L;

    public static void main(String[] args){

        new Window();
    }


    public Window(){


        // Adds the custom panel
        Panel Panel = new Panel();
        this.add(Panel);


        // Basic Window Features
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(800,800);
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }


}

Panel.java:

public class Panel extends JPanel{

    public Panel(){
        Button testButton = new Button("Test");
        DrawBoard drawBoard = new DrawBoard();
        Listener listener = new Listener();



        this.add(testButton);
        this.add(drawBoard);


    }
}

Button.java

import java.awt.Dimension;

import javax.swing.JButton;

public class Button extends JButton{


    public Button(String name) {
        this.setText(name);
        this.setName((String) name);
        buttonSettings();
    }

    private void buttonSettings(){
        Listener listener = new Listener();
        this.addActionListener(listener);

        int width = 200;
        int height = 50;
        Dimension dim = new Dimension(width,height);
        this.setPreferredSize(dim);
    }

}

DrawBoard.java

import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JPanel;

public class DrawBoard extends JPanel{

    public DrawBoard(){
        DrawBoardSettings();
    }

    private void DrawBoardSettings(){
        int width = 600;
        int height = 600;
        Dimension dim = new Dimension(width,height);
        this.setPreferredSize(dim);
        this.setBackground(Color.WHITE);
    }
}

Listener.java

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JComponent;

public class Listener implements ActionListener, MouseListener {

    @Override
    public void mouseClicked(MouseEvent e) {
        **// Draw a dot at the mouse location of the DrawBoard JPanel that was added by the Panel JPanel that was added by the Window JFrame**

    }

    @Override
    public void mousePressed(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String name = ((JComponent) e.getSource()).getName();
        **// Draw a rectangle on the DrawBoard JPanel that was added by the Panel JPanel that was added by the Window JFrame**
    }

}

Solution

  • Some thoughts here:

    • Currently you have several instances of that Listener class. That is probably not what you want.
    • Related to that: your code indicates that your Listener class should draw on some panel. If so ... that Listener somehow needs access to that panel.

    One way to get there: you change your constructor to

    private final Panel drawingBoard;
    public Listener(Panel drawingBoard) { 
      this.drawingBoard = drawingBoard;
    )
    

    and then your actionPerformed() method has something to draw on.

    The core thing to understand: you have to create a clear model (in your mind) about which components you have; and how they depend on each other. Because that drives your implementation; for example regarding the order in which you have to create your different objects. Given my example, you would need to first create a Panel object; so that you can then create a Listener for that Panel.