Вы можете использовать другой столбец, например id
, в качестве pk.
Вы можете сделать это уже сегодня с помощью EventBus.
Следующий пример взят из EventBus Руководства по началу работы с шиной . Строка состояния, которая обновляется на основе опубликованных событий, и нет необходимости регистрировать управление/ширину строки состояния как слушателя издателя (издателей). Без EventBus панель состояния должна быть добавлена в качестве слушателя многих классов. Панель состояния также может быть создана и уничтожена в любое время.
public StatusBar extends JLabel {
public StatusBar() {
AnnotationProcessor.process(this);
}
@EventSubscriber(eventClass=StatusEvent.class)
public void updateStatus(StatusEvent statusEvent) {
this.setText(statusEvent.getStatusText();
}
}
Похожим проектом является ELF (Event Listener Framework), но он кажется менее зрелым.
В настоящее время я исследую фреймворк уведомлений о событиях на Publish-Subscribe Event Driven Programming | Kev's Spring vs Java EE Dev и последующие статьи.
.Не путайте сложный для умного. Мне кажется, что это было бы:
if (event instanceof NodeCreatedEvent)
как код. Почему это лучше, чем разделение на подклассы adapter
Понятия не имею!Основной проблемой, которую я вижу здесь, являются параметры метода, которые ограничивают, какие методы могут на самом деле использоваться для который события, и нет никакой справки времени компиляции для этого.
Это - то, что делает интерфейсы привлекательными для меня для реализаций шаблона "наблюдатель" как модель событий Java. Инструменты как затмение могут autogen тупики метода, таким образом, Вы не можете понять подписи превратно. В Вашем примере это очень просто в использовании неправильный тип параметра, и никогда не знайте это, пока событие не имеет место (который мог бы быть ошибочным случаем несколько месяцев по линии),
Одной вещью, которую Вы могли бы попробовать, являются мои аннотации и процессор для реализации реализации несуществующего объекта и наблюдатели. Предположим, что Вы имеете
package a.b.c;
public interface SomeListener {
void fee();
void fie();
void fo();
void fum();
}
и требуемый для создания экземпляра слушателя. Вы могли записать
package x.y.z;
import a.b.c.SomeListener;
import com.javadude.annotation.Bean;
import com.javadude.annotation.NullObject;
@Bean(nullObjectImplementations = {@NullObject(type = SomeListener.class) })
public class Foo extends FooGen implements SomeListener {
@Override
public void fie() {
// whatever code you need here
}
}
Для создания источника для этих событий можно записать
package a.b.c;
import com.javadude.annotation.Bean;
import com.javadude.annotation.Observer;
@Bean(observers = {@Observer(type = SomeListener.class)})
public class Source extends SourceGen {
// SourceGen will have add/remove listener and fire methods
// for each method in SomeListener
}
См. http://code.google.com/p/javadude/wiki/Annotations, если Вам интересно. Мог бы дать Вам некоторые другие идеи также.
Я также думал об общей структуре событий, управляемой аннотациями. Мне нравятся преимущества статической типизации, но текущую модель событий, управляемую интерфейсом, болезненно использовать (уродливый код). Можно ли было бы использовать специальный процессор аннотаций для проверки во время компиляции? Это может помочь добавить некоторую недостающую «безопасность», к которой мы все привыкли.
Многие проверки ошибок также могут выполняться в то время, когда слушатели «зарегистрированы» в производителях событий. Таким образом, приложение выйдет из строя раньше (когда будут зарегистрированы слушатели), возможно, даже во время запуска.
Вот пример того, как может выглядеть общая структура, с которой я играл:
public class ExampleProducer {
private EventSupport<ActionEvent> eventSupport;
public ExampleProducer() {
eventSupport = new EventSupport<ActionEvent>(this);
}
@AddListenersFor(ActionEvent.class)
public void addActionListener(Object listener)
{
eventSupport.addListener(listener);
}
@RemoveListenersFor(ActionEvent.class)
public void removeActionListener(Object listener)
{
eventSupport.removeListener(listener);
}
public void buttonClicked() {
eventSupport.fire(new ActionEvent(this,
ActionEvent.ACTION_PERFORMED, "Click"));
}
}
Производитель использует EventSupport
, который использует отражение для вызова событий. Как упоминалось ранее, EventSupport
может выполнять некоторые начальные проверки при регистрации слушателей событий.
public class ExampleListener
{
private ExampleProducer submitButton;
public ExampleListener()
{
submitButton = new ExampleProducer();
EventSupport.autoRegisterEvents(this);
}
@HandlesEventFor("submitButton")
public void handleSubmitButtonClick(ActionEvent event)
{
//...some code to handle the event here
}
}
Здесь EventSupport
имеет статический метод, который использует отражение для автоматической регистрации слушателя с помощью продюсер мероприятия. Это устраняет необходимость вручную регистрироваться в источнике событий. Пользовательский процессор аннотаций может быть использован для проверки того, что аннотация @HandlesEventFor
относится к фактическому полю ExampleListener
. Процессор аннотации может также выполнять другие проверки, например, обеспечивать соответствие сигнатуры метода обработчика событий одному из методов регистрации в ExampleProducer
(в основном, та же проверка, которая может выполняться во время регистрации ).
Что вы думаете? Стоит ли тратить время на полную разработку?
Я сделал http://neoevents.googlecode.com , чтобы обработать этот вид обработчика событий на основе аннотации.
@actionPerformed
private void onClick() {
//do something
}
protected void initComponents() {
JButton button = new JButton("Click me!!!");
button.addActionListener(new ActionListener(this) );
}
Это выглядит так же просто, как я ожидал, что это будет. Аннотации доступны для каждого слушателя в J2SE.
Вот похожий проект под названием SJES.
public class SomeController {
private Calculator c1 = new Calculator();
private Calculator c2 = new Calculator();
public SomeController() {
c1.registerReceiver(this);
c2.registerReceiver(this);
c1.add(10, 10);
c2.add(20, 20);
}
@EventReceiver(handleFor="c1")
public void onResultC1(Calculator.Event e) {
System.out.println("Calculator 1 got: " + e.result);
}
@EventReceiver(handleFor="c2")
public void onResultC2(Calculator.Event e) {
System.out.println("Calculator 2 got: " + e.result);
}
@EventReceiver
public void onResultAll(Calculator.Event e) {
System.out.println("Calculator got: " + e.result);
}
}
public class Calculator {
private EventHelper eventHelper = new EventHelper(this);
public class Event {
long result;
public Event(long result) {
this.result = result;
}
}
public class AddEvent extends Event {
public AddEvent(long result) {
super(result);
}
}
public class SubEvent extends Event {
public SubEvent(long result) {
super(result);
}
}
public void unregisterReceiver(Object o) {
eventHelper.unregisterReceiver(o);
}
public void registerReceiver(Object o) {
eventHelper.registerReceiver(o);
}
public void add(long a, long b) {
eventHelper.fireEvent(new AddEvent(a + b));
}
public void sub(long a, long b) {
eventHelper.fireEvent(new SubEvent(a - b));
}
public void pass(long a) {
eventHelper.fireEvent(new Event(a));
}
}
Я думаю, что это очень просто в использовании.