I am using Windchill 10.0 M030. I have created a windchill service that captures some actions. I am done with capturing the delete, checkin, and state change events, but I don't know how to capture the revision event of an object. Can someone help me out?
Some example code snippets would be helpful. The events that are working fine are the following:
public void notifyEvent(KeyedEvent event) throws RemoteException,
WTException {
if (event instanceof PersistenceManagerEvent) {
notifyEvent((PersistenceManagerEvent) event);
}
if (event instanceof WorkInProgressServiceEvent) {
notifyEvent((WorkInProgressServiceEvent) event);
}
if (event instanceof EPMWorkspaceManagerEvent) {
notifyEvent((EPMWorkspaceManagerEvent) event);
}
if (event instanceof LifeCycleServiceEvent) {
notifyEvent((LifeCycleServiceEvent) event);
}
}
Is there any separate event like Revise event to be captured in this way? How can I do that?
Thank you.
Here is the code for your ListenerAdapter :
public class VersionEventListenerAdapter extends ServiceEventListenerAdapter {
public VersionEventListenerAdapter(String serviceId) {
super(serviceId);
}
public void notifyVetoableEvent(Object event) throws WTException, WTPropertyVetoException {
if (!(event instanceof KeyedEvent)) {
return;
}
Object target = ((KeyedEvent) event).getEventTarget();
Object eventType = ((KeyedEvent) event).getEventType();
if (eventType.equals(VersionControlServiceEvent.NEW_VERSION)
{
/** Call your business code here
example : yourMethod(target);
**/
}
}
And then the service to register the listener
public class MyStandardListenerService extends StandardManager implements MyListenerServiceInterface {
private static final long serialVersionUID = 1L;
protected synchronized void performStartupProcess() throws ManagerException {
VersionEventListenerAdapter versionEventListenerAdapter = new VersionEventListenerAdapter(getName());
getManagerService().addEventListener(versionEventListenerAdapter, VersionControlServiceEvent.generateEventKey(VersionControlServiceEvent.NEW_VERSION));
}
public static MyStandardListenerService newMyStandardListenerService() throws WTException {
MyStandardListenerService instance = new MyStandardListenerService();
instance.initialize();
return instance;
}
This new service need to be registered in the wt.properties. See the customizer's guide for more details about how to register it (with xconfmanager command line utility)
Related
I'm working on a game engine, and the last question I had regarding this was what good way I can use to make "observers" or listeners. A user suggested that I should use Java's EventObject class to inherit from and make a Listener interface. However, this didn't provide me with good flexibility.
Here is the Handler annotation to state that a method is an event handler in a listener:
#Retention(RetentionPolicy.CLASS)
#Target(ElementType.METHOD)
public #interface Handler {}
Here is the base class for Event, which is basically the same as EventObject (but I'll add abstract methods sooner or later):
public abstract class Event {
private Object source;
public Event(Object source) {
this.source = source;
}
public Object getSource() {
return source;
}
}
Here is the Listener class, which is empty:
public interface Listener {}
Here is the ListenerHandler class, used to handle all listeners. You register and unregister them here. I'll edit the register/unregister methods later for a better use:
public class ListenerHandler {
private ArrayList<Listener> listeners;
public ListenerHandler() {
this.listeners = new ArrayList<Listener>();
}
public void registerListener(Listener l) {
listeners.add(l);
}
public void unregisterListener(Listener l) {
listeners.remove(l);
}
public void onEvent(Event event) {
for(Listener l : listeners) {
Class<?> c = l.getClass();
Method[] methods = c.getDeclaredMethods();
for(Method m : methods) {
if(m.isAccessible()) {
if(m.isAnnotationPresent(Handler.class)) {
Class<?>[] params = m.getParameterTypes();
if(params.length > 1) {
continue;
}
Class<?> par = params[0];
if(par.getSuperclass().equals(Event.class)) {
try {
m.invoke(this, event);
}catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
}
}
}
From what I heard, it's a use of a lot of memory in order to get all methods of a class. I'm not going to assume this is the case, but I'm sure there is a better way as this will be a game engine with many components and such.
I'd like to know the best way to implement this, or if I'm doing it right. I'd also like to know if anyone can help me improve this in any way without hogging memory usage by the game (as of now it's not a big deal -- the "game engine" is not even close to rendering anything yet)
I tried to keep it a very simple example and will comment with different ideas to it:
First meet the Achievement class:
import java.util.Observable;
public class Achievement extends Observable {
public static class AchievementDetails {}
public Achievement() {
addObserver(EventsListener.getInstance());
}
public void achievementReached() {
AchievementDetails achievemetDetails = null;
setChanged();
notifyObservers(achievemetDetails);
}
}
And then the events listener class:
import com.test.Achievement.AchievementDetails;
public class EventsListener implements Observer {
private static EventsListener instance = new EventsListener();
public static EventsListener getInstance() {
return instance;
}
#Override
public void update(Observable o, Object arg) {
if(o instanceof Achievement) {
AchievementDetails achievemetDetails = (AchievementDetails) arg;
//do some logic here
}
}
}
The only one thing that is missing is to create an instance of your achievement (which register the EventsListener to itself) and handle the life cycle of it.
I'm trying to make an annotation-based event system where like you would register a class implementing an interface and then you can use the events that have an #interface above the methods that are called. Like so:
Wherever.java
EventManager.callEvent(new HelloEvent);
EventManager.register(new ClassThatImplementsListeenr);
#EventHandler
public void onHello(HelloEvent event) {
event.sayHello();
}
Ok I understand a lot of this like registering (adds them to arraylist) and making a listener interface plus Event interface. New Events will implement Event, and an #Interface called EventHandler that will only work with methods. THE MAIN part is what I don't get. How to invoke and check for the annotation.
EDIT I JUST MADE THIS, WOULD IT WORK?
Public class EventManager {
private static List<Listener> registered = new ArrayList<Listener>();
public static void register(Listener listener) {
if (!registered.contains(listener)) {
registered.add(listener);
}
}
public static void unregister(Listener listener) {
if (registered.contains(listener)) {
registered.remove(listener);
}
}
public static List<Listener> getRegistered() {
return registered;
}
public static void callEvent(final Event event) {
new Thread() {
public void run() {
call(event);
}
}.start();
}
private static void call(final Event event) {
for (Listener listener : registered) {
Method[] methods = listener.getClass().getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(EventHandler.class)) {
try {
method.invoke(listener.getClass().newInstance(), event);
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
}
}
}
You can check for annotations that have been added to a method by
Retrieving all the methods that are available on a class:
public void registerListeners(T handler){
Method[] allMethods = handler.getClass().getMethods();
}
Check all the methods that have your desired annotation (although I would imagine only one method in any given class should be designated with an event listener-type annotation)
List<Method> listenerMethods = new ArrayList<Method>();
for (Method aMethod: allMethods){
if(aMethod.isAnnotationPresent(EventHandler.class)){
listenerMethods.add(aMethod);
}
}
Given the specific methods that have the annotation, you could call Method#invoke on the shortlist of methods to execute the listener.
I'm using GWT 2.4 by using the MVP pattern
I have this situation:
In one presenter (let's call it a TreePresenter since it shows a tree) i have the following code:
display.getSelectedItem().addSelectionHandler(new SelectionHandler<TreeItem>() {
#Override
public void onSelection(SelectionEvent<TreeItem> event) {
....
evtBus.fireEvent(new SelectCategoryEvent(item.getText()));
.....
}
});
And in my AppController class I have this situation:
eventBus.addHandler(SelectCategoryEvent.TYPE, new SelectCategoryEventHandler() {
#Override
public void onSelectCategory(SelectCategoryEvent event) {
saveHistoryEvent(event);
}
});
When i select one itm in the three the event is correctly fired by the instruction
evtBus.fireEvent(new SelectCategoryEvent(item.getText()));
But in my AppController the event is not propagated and I can't handle it in the code
eventBus.addHandler(SelectCategoryEvent.TYPE, new SelectCategoryEventHandler() {
#Override
public void onSelectCategory(SelectCategoryEvent event) {
saveHistoryEvent(event);
}
});
Can anybody tell me the reason?
Thank
Angelo
I'll give you some detail; I built a class for my own history management; I built this class:
public class GwtHistoryEventsMgr {
private Map<String, List<GwtEvent>> tknEvts;
private HandlerManager eventBus;
public GwtHistoryEventsMgr(HandlerManager evtBus){
tknEvts = new HashMap<String, List<GwtEvent>>();
this.eventBus = evtBus;
}
private void saveHistoryEvent( GwtEvent event ){
List<GwtEvent> eventi = null;
if( tknEvts.containsKey(History.getToken()) ){
eventi = tknEvts.get(History.getToken());
}else{
eventi = new ArrayList<GwtEvent>();
}
eventi.add(event);
tknEvts.put(History.getToken(), eventi);
}
public void addEvtHandlers(){
//Aggiungo gli handler
eventBus.addHandler(CustomEvent.TYPE, new CustomEventHandler() {
#Override
public void onEvent(CustomEvent event) {
saveHistoryEvent(event);
}
});
}
public List<GwtEvent> getTokenTransWidgetEvents(String token){
if( tknEvts.containsKey(token) ){
return tknEvts.remove(token);
}else{
return null;
}
}
}
Then in my AppController constructor I wrote this code:
public AppController(HandlerManager eventBus, StandardDispatchAsync dispatcher){
super(null);
this.eventBus = eventBus;
this.dispatcher = dispatcher;
//Gestione history
histMgr = new GwtHistoryEventsMgr(eventBus);
histMgr.addEvtHandlers();
}
This means that I should be pretty sure that the AppController registers itself to the events I want (note: I strongly reduced the code...but all the code is in the way I wrote)
Then, since I use client-side reflection, I did, where I use the client side reflection, this code (after that all widgets have been initialized):
#SuppressWarnings("rawtypes")
private void generateHistoricalEvents(){
List<GwtEvent> eventi = hisMgr.getTokenTransWidgetEvents(History.getToken());
//Ci sono eventi....vuol dire back del browser cliccato
if( eventi != null ){
for (GwtEvent gwtEvent : eventi) {
this.eventBus.fireEvent(gwtEvent);
}
}
}
According to me it's all OK; may you tell me where the problem is?
Thank you
Angelo
I cannot seem to find an answer anywhere to my question. Is there any event listener which can detect the changing of a boolean or other variable and then act on it. Or is it possible to create a custom event listener to detect this?
Please I cannot seem to find a solution to this anywhere and I found this website explaining how to create custom events
Use PropertyChangeSupport. You wont have to implement as much and it is thread safe.
public class MyClassWithText {
protected PropertyChangeSupport propertyChangeSupport;
private String text;
public MyClassWithText () {
propertyChangeSupport = new PropertyChangeSupport(this);
}
public void setText(String text) {
String oldText = this.text;
this.text = text;
propertyChangeSupport.firePropertyChange("MyTextProperty",oldText, text);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
}
public class MyTextListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent event) {
if (event.getPropertyName().equals("MyTextProperty")) {
System.out.println(event.getNewValue().toString());
}
}
}
public class MyTextTest {
public static void main(String[] args) {
MyClassWithText interestingText = new MyClassWithText();
MyTextListener listener = new MyTextListener();
interestingText.addPropertyChangeListener(listener);
interestingText.setText("FRIST!");
interestingText.setText("it's more like when you take a car, and you...");
}
}
Just like you need to create an event listener, you will also need to create the event firer -- since there is nothing automatic that will do this for you. I've provided sample code that shows you how to implement such a firer.
This test implementation isn't perfect. It only includes a way to add listeners. You may wish to include a way to remove listeners who are no longer interested in receiving events. Also note that this class is not thread-safe.
import java.util.List;
import java.util.ArrayList;
import java.util.EventListener;
import java.util.EventObject;
import java.awt.EventQueue;
/**
* This class uses the EventQueue to process its events, but you should only
* really do this if the changes you make have an impact on part of a GUI
* eg. adding a button to a JFrame.
*
* Otherwise, you should create your own event dispatch thread that can handle
* change events
*/
public class BooleanChangeTest implements BooleanChangeDispatcher {
public static void main(String[] args) {
BooleanChangeListener listener = new BooleanChangeListener() {
#Override
public void stateChanged(BooleanChangeEvent event) {
System.out.println("Detected change to: "
+ event.getDispatcher().getFlag()
+ " -- event: " + event);
}
};
BooleanChangeTest test = new BooleanChangeTest(false);
test.addBooleanChangeListener(listener);
test.setFlag(false); // no change, no event dispatch
test.setFlag(true); // changed to true -- event dispatched
}
private boolean flag;
private List<BooleanChangeListener> listeners;
public BooleanChangeTest(boolean initialFlagState) {
flag = initialFlagState;
listeners = new ArrayList<BooleanChangeListener>();
}
#Override
public void addBooleanChangeListener(BooleanChangeListener listener) {
listeners.add(listener);
}
#Override
public void setFlag(boolean flag) {
if (this.flag != flag) {
this.flag = flag;
dispatchEvent();
}
}
#Override
public boolean getFlag() {
return flag;
}
private void dispatchEvent() {
final BooleanChangeEvent event = new BooleanChangeEvent(this);
for (BooleanChangeListener l : listeners) {
dispatchRunnableOnEventQueue(l, event);
}
}
private void dispatchRunnableOnEventQueue(
final BooleanChangeListener listener,
final BooleanChangeEvent event) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
listener.stateChanged(event);
}
});
}
}
interface BooleanChangeDispatcher {
public void addBooleanChangeListener(BooleanChangeListener listener);
public boolean getFlag();
public void setFlag(boolean flag);
}
/**
* Listener interface for classes interested in knowing about a boolean
* flag change.
*/
interface BooleanChangeListener extends EventListener {
public void stateChanged(BooleanChangeEvent event);
}
/**
* This class lets the listener know when the change occured and what
* object was changed.
*/
class BooleanChangeEvent extends EventObject {
private final BooleanChangeDispatcher dispatcher;
public BooleanChangeEvent(BooleanChangeDispatcher dispatcher) {
super(dispatcher);
this.dispatcher = dispatcher;
}
// type safe way to get source (as opposed to getSource of EventObject
public BooleanChangeDispatcher getDispatcher() {
return dispatcher;
}
}
you can also try to implement an Observer.
First create the observable object:
import java.util.Observable;
public class StringObservable extends Observable {
private String name;
public StringObservable(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
setChanged();
notifyObservers(name);
}
}
Then the observer:
import java.util.Observable;
import java.util.Observer;
public class NameObserver implements Observer {
private String name;
public NameObserver() {
name = null;
}
public void update(Observable obj, Object arg) {
if (arg instanceof String) {
name = (String) arg;
System.out.println("NameObserver: Name changed to " + name);
} else {
System.out.println("NameObserver: Some other change to subject!");
}
}
}
And in your main (or wherever else):
public class TestObservers {
public static void main(String args[]) {
// Create the Subject and Observers.
StringObservable s = new StringObservable("Test");
NameObserver nameObs = new NameObserver();
// Add the Observer
s.addObserver(nameObs);
// Make changes to the Subject.
s.setName("Test1");
s.setName("Test2");
}
}
Mostly found here
Very late to answer, but this is a problem that can be solved with Observer/Observable. Example
The boolean you are setting should be allowed to do only through a setter method like:
public void setFlag(boolean flag){
//Method code goes here
}
Now in now set method, you can decide based on what value comes in, what event needs to be fired. I am explaining in simple terms without introducing complex terms so you can understand better, so code snippet would look like:
public void setFlag(boolean flag){
//if flag is TRUE do something
//If flag is FALSE then do something
//And finally do what you needed to do with flag
}
Ask questions if you need more info
you create a listener when you want to listen for I/O changes. mostly on graphics.
the answer to your question is to keep state of the running program, then check if variables change from the state inside the infinite loop of your program.
You can use AOP for that, perhaps AspectJ? Check a few examples here (if you use Eclipse, then using AspectJ is really simple with their plugin).
For you, you would have a pointcut similar to the one used in the SampleAspect, but one that will only be used when someone makes a new SET to a boolean variable (this doesn't mean that the value has changed, just that someone loaded a value to the variable).
Is there any way to detect change in an integer? Such as creating a listener to listen to the integer to detect and change in value it has. I know this is possible with booleans with a few tricks but I cannot seem to adapt this to an int value. Does anyone have any idea how this could be done? I need to know how to do this in the Java language. Below is code that I found online that allows for a boolean listener. How can I convert this to an integer listener?
import java.util.List;
import java.util.ArrayList;
import java.util.EventListener;
import java.util.EventObject;
import java.awt.EventQueue;
//can u see this austin? can u see this i typed this at 9:33 my time
/**
* This class uses the EventQueue to process its events, but you should only
* really do this if the changes you make have an impact on part of a GUI
* eg. adding a button to a JFrame.
*
* Otherwise, you should create your own event dispatch thread that can handle
* change events
*/
public class test1 implements BooleanChangeDispatcher {
public static void main(String[] args) {
BooleanChangeListener listener = new BooleanChangeListener() { // add this to the class
#Override
public void stateChanged(BooleanChangeEvent event) {
System.out.println("Detected change to: "
+ event.getDispatcher().getFlag()
+ " -- event: " + event);
}
};
test1 test = new test1(false);
test.addBooleanChangeListener(listener);
// test.setFlag(false); // no change, no event dispatch
// test.setFlag(true); // changed to true -- event dispatched
}
private boolean flag;
private List<BooleanChangeListener> listeners;
public test1(boolean initialFlagState) {
flag = initialFlagState;
listeners = new ArrayList<BooleanChangeListener>();
}
#Override
public void addBooleanChangeListener(BooleanChangeListener listener) {
listeners.add(listener);
}
#Override
public void setFlag(boolean flag) {
if (this.flag != flag) {
this.flag = flag;
dispatchEvent();
}
}
#Override
public boolean getFlag() {
return flag;
}
private void dispatchEvent() {
final BooleanChangeEvent event = new BooleanChangeEvent(this);
for (BooleanChangeListener l : listeners) {
dispatchRunnableOnEventQueue(l, event);
}
}
private void dispatchRunnableOnEventQueue(
final BooleanChangeListener listener,
final BooleanChangeEvent event) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
listener.stateChanged(event);
}
});
}
}
interface BooleanChangeDispatcher {
public void addBooleanChangeListener(BooleanChangeListener listener);
public boolean getFlag();
public void setFlag(boolean flag);
}
/**
* Listener interface for classes interested in knowing about a boolean
* flag change.
*/
interface BooleanChangeListener extends EventListener {
public void stateChanged(BooleanChangeEvent event);
}
/**
* This class lets the listener know when the change occured and what
* object was changed.
*/
class BooleanChangeEvent extends EventObject {
private final BooleanChangeDispatcher dispatcher;
public BooleanChangeEvent(BooleanChangeDispatcher dispatcher) {
super(dispatcher);
this.dispatcher = dispatcher;
}
// type safe way to get source (as opposed to getSource of EventObject
public BooleanChangeDispatcher getDispatcher() {
return dispatcher;
}
}
I would create a class capable of registering listeners. Below is a mocked up example. It might even compile as is (assuming you write the corresponding VocalIntegerListener interface exists and is implemented somehow... it's pretty simple).
class VocalInteger {
private int value;
private final Object lock = new Object();
Set<VocalIntegerListener> listeners; // assume interface exists - it's easy
public VocalInteger() {
this(0);
}
public VocalInteger(int value) {
this.value = value;
listeners = new HashSet<VocalIntegerListener>();
}
public int getValue() {
return value;
}
public void setValue(int value) {
synchronized(lock) {
int oldValue = this.value;
this.value = value;
for(VocalIntegerListener listener : listeners) {
listener.fireChangedEvent(oldvalue, value); // assume exists
}
}
}
public void registerListener(VocalIntegerListener listener) {
synchronized(lock) {
listeners.add(listener);
}
}
}
Have a look at "Java Beans" and "bound properties" for the standard approach how to listen for property changed events:
http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html
http://docs.oracle.com/javase/tutorial/javabeans/