Java - Вопрос о понятиях обработчика действий кнопки многократного использования - PullRequest
2 голосов
/ 24 июля 2011

Прежде всего - извините за стену кода, но это не слишком ужасно, просто рамки для того, что я пытаюсь объяснить. Работает без ошибок.

Цель

Я создаю класс кнопки многократного использования для моего графического интерфейса, и каждый объект кнопки должен иметь свой обработчик при нажатии. Я хочу назначить объект ClickHandler каждой новой кнопке. Затем кнопка вызовет init() на обработчике и будет в пути. К сожалению, существует проблема с типизацией, поскольку у каждого класса обработчика будет свое имя.

Текущий прогресс

Сейчас обработчик набирается как HandlerA, но я бы хотел, чтобы он обрабатывал любое имя, например «SettingsHandler» или «GoToTheWahWah» и т. Д.

Я пытался возиться с универсальными типами, но, поскольку я новичок в этом, и из опыта вебдевов, кажется, есть концептуальное препятствие, которое я продолжаю сбивать. Правильный ли это подход к проблеме?

Код

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 - это пример случайного обработчика для нажатия кнопки. Позже может быть HandlerB, HandlerC и т. Д.

package gui;

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

Заранее большое спасибо!

Ответы [ 3 ]

4 голосов
/ 24 июля 2011

Все вы, обработчики, должны реализовать интерфейс типа Clickable или что-то в этом роде. Таким образом, интерфейс определяет существование функции init:

public interface Clickable 
{
    public void init();
}

Определение HandlerA:

public class HandlerA implements Clickable {
    public void init() {
       System.out.println("Button clicked.");
    }
}
3 голосов
/ 24 июля 2011

Вы должны использовать интерфейс для обработчика.

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

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

Это то же самое понятие, что и обычный JButton.Там у вас есть интерфейс ActionListener и метод actionPerformed.

PS Если я не понимаю ваш вопрос, пожалуйста, поправьте меня.

3 голосов
/ 24 июля 2011

Рекомендую работать с наследованием в этом случае:

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

        // ...
    }
}

Не уверен, что это то, что вы ищете ...

Кстати: вы также можете определить AbstractHandler как interface, но вы можете также реализовать здесь некоторую общую логику - общую для всех обработчиков.

...