Reputation: 57277
First off - sorry for the wall of code but it's not too horrendous, just a framework for what I'm trying to explain. It runs without errors.
The goal
I'm making a reuseable button class for my GUI and each button object needs to have a different handler when it's clicked. I want to to assign a ClickHandler
object to each new button. Then, the button would call init()
on the handler, and be on its way. Unfortunately, there's a typing problem, since each handler class would have a different name.
Current progress
Right now, the handler is typed as HandlerA
, but I'd like to have it handle any name, like "SettingsHandler" or "GoToTheWahWah" etc.
I've tried messing about with generic types, but since I'm new to this, and from a webdev background, there seems to be a conceptual hurdle I keep knocking over. Is this the right way to approach the problem?
The code
ReuseableButton.java
is a reuseable class, the only thing that changes is the action when it's clicked:
package gui;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class ReuseableButton extends JButton implements ActionListener {
private static final long serialVersionUID = 1L;
// I want a generic type here, not just HandlerA!
private HandlerA ClickHandler;
// Assemble generic button
public ReuseableButton(Container c, String s) {
super(s);
addActionListener(this);
c.add(this);
}
// Once again, generic type, not just HandlerA!
public void SetClickHandler(HandlerA ch) {
ClickHandler = ch;
}
// Call init() from whatever class has been defined as click handler.
public void actionPerformed(ActionEvent e) {
ClickHandler.init();
}
}
Controller.java
fires the frame and assembles buttons as needed (right now, only one button).
package gui;
import javax.swing.*;
import java.awt.*;
public class Controller extends JFrame {
private static final long serialVersionUID = 1L;
public Controller() {
JFrame frame = new JFrame("Handler Test GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container pane = frame.getContentPane();
pane.setLayout(new FlowLayout());
ReuseableButton b = new ReuseableButton(pane,"Reuseable Button A");
// THE QUESTION IS HERE: Pass a generic object?
b.SetClickHandler(new HandlerA());
frame.pack();
frame.setSize(200,200);
frame.setVisible(true);
}
public static void main(String args[]) {
new Controller();
}
}
HandlerA.java
is a sample of a random handler for the button click. Later, there could be HandlerB
, HandlerC
, etc.
package gui;
// A random handler
public class HandlerA {
public void init() {
System.out.println("Button clicked.");
}
}
Thanks very much in advance!
Upvotes: 2
Views: 2197
Reputation: 12538
I recommend to work with inheritence in this case:
public abstract class AbstractHandler {
public abstract void init();
}
Then:
public class ConcreteHandlerA extends AbstractHandler {
@Override
public void init() {
// do stuff...
}
}
Controller
public class ReuseableButton extends JButton implements ActionListener {
// I want a generic type here, not just HandlerA!
private AbstractHandler ClickHandler;
public Controller() {
//...
ReuseableButton b = new ReuseableButton(pane,"Reuseable Button A");
AbstractHandler handlerA = new ConcreteHandlerA();
b.SetClickHandler(handlerA);
// ...
}
}
Not sure if this is what you're looking for...
BTW: You can define the AbstractHandler
as an interface
as well, but you may want to implement some common logic here as well - shared across handlers.
Upvotes: 3
Reputation: 11162
All of you handlers should implement an interface like Clickable
or something. That way the interface specifies the existence of the init function:
public interface Clickable
{
public void init();
}
Making the HandlerA definition:
public class HandlerA implements Clickable {
public void init() {
System.out.println("Button clicked.");
}
}
Upvotes: 5
Reputation: 47383
You should use an interface for the handler.
public interface ClickHandler() {
void init();
}
ReuseableButton b = new ReuseableButton(pane,"Reuseable Button A");
b.SetClickHandler(object which implements the ClickHandler interface);
This is the same concept as the normal JButton
. There you have the ActionListener
interface and the actionPerformed
method in it.
P.S. If I don't understand your question, please correct me.
Upvotes: 3