Java - 可重用按钮动作处理程序概念问题

时间:2011-07-24 07:34:07

标签: java swing jbutton extend jcomponent

首先 - 抱歉代码墙,但它不是太可怕,只是我试图解释的框架。它运行没有错误。

目标

我正在为我的GUI创建一个可重复使用的按钮类,每个按钮对象在单击时需要有一个不同的处理程序。我想为每个新按钮分配一个ClickHandler对象。然后,按钮将在处理程序上调用init(),然后继续运行。不幸的是,存在打字问题,因为每个处理程序类都有不同的名称。

当前进度

现在,处理程序被输入为HandlerA,但我想让它处理任何名称,例如“SettingsHandler”或“GoToTheWahWah”等。

我试过搞乱泛型类型,但由于我是新手,并且从webdev背景来看,似乎存在一个概念上的障碍,我一直在敲门。这是解决问题的正确方法吗?

代码

ReuseableButton.java是一个可重复使用的类,唯一改变的是点击它时的动作:

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根据需要激活框架并组装按钮(目前只有一个按钮)。

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是按钮点击的随机处理程序示例。之后,可能会有HandlerBHandlerC

package gui;

// A random handler
public class HandlerA {
  public void init() {
    System.out.println("Button clicked.");
  }
}

非常感谢!

3 个答案:

答案 0 :(得分:4)

所有处理程序都应该实现Clickable之类的界面。这样接口指定了init函数的存在:

public interface Clickable 
{
    public void init();
}

制作HandlerA定义:

public class HandlerA implements Clickable {
    public void init() {
       System.out.println("Button clicked.");
    }
}

答案 1 :(得分:3)

我建议在这种情况下使用继承:

public abstract class AbstractHandler {

    public abstract void init();
}

然后:

public class ConcreteHandlerA extends AbstractHandler {

    @Override
    public void init() {
        // do stuff...
    }

}

<强>控制器

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);

        // ...
    }
}

不确定这是否是您正在寻找的......

BTW:您也可以将AbstractHandler定义为interface,但您也可以在此处实现一些通用逻辑 - 跨处理程序共享。

答案 2 :(得分:3)

您应该使用处理程序的接口。

public interface ClickHandler() {
    void init();
}

ReuseableButton b = new ReuseableButton(pane,"Reuseable Button A");
b.SetClickHandler(object which implements the ClickHandler interface);

这与普通JButton的概念相同。你有ActionListener接口和actionPerformed方法。

P.S。如果我不明白你的问题,请纠正我。