So I'm learning JavaFX programming and MVC. The control is also its own class and isn't integrated into the view (Which I've heard is one way to go at it). I want it to be separated from the view but because I'm trying to encapsulate everything and leave everything private with limited access to the controls/nodes, I find myself using methods to do almost anything inside of my object almost entirely when using event handlers in the control.
Example (Not an actual program, just wrote it here because I have no short examples.):
View:
public class SamplePane extends BorderPane {
private TextField tfScoreOne;
private Button btnScore, btnPenalty;
private int scoreOne;
public SamplePane() {
// Some constructor
}
public void giveScore() {
scoreOne++;
tfScoreOne.textProperty().setValue("Score: " + Integer.toString(scoreOne);
}
public void takeScore() {
scoreOne--;
tfScoreOne.textProperty().setValue("Score: " + Integer.toString(scoreOne);
}
}
public void btnScoreAddHandler(EventHandler<ActionEvent> handler) {
btnOneAdd.setOnAction(handler);
}
public void btnPenaltyAddHandler(EventHandler<ActionEvent> handler) {
btnOneAdd.setOnAction(handler);
}
Control:
public class SampleController {
public ModuleSelectionController() {
// Some contorller stuff again
samplePaneObj.btnScoreAddHandler(btnScoreHandler);
samplePaneObj.btnPenaltyAddHandler(btnScoreHandler);
}
private class btnScoreHandler implements EventHandler<ActionEvent> {
public void handle(ActionEvent arg0) {
samplePaneObj.giveScore();
}
}
private class btnPenaltyHandler implements EventHandler<ActionEvent> {
public void handle(ActionEvent arg0) {
samplePaneObj.takeScore();
}
}
}
This is mostly pseudocode so forgive me if there are any errors but do you get the point? It seems very arbitrary to just be calling methods but without passing the TextField in the example its hard to not do everything without a method doing all the work.
But is that decoupled enough for MVC? I don't really wanna break encapsulation is the main issue so I can't make the controls public and operate on them directly in the controller.
Is this all just normal? I want to make sure I'm grasping it right.
There is too much that could be said about this here. I'd advise you to have a look at a JavaFX application framework and read its documentation. I learned a lot from it. E.g., have a look here: https://github.com/sialcasa/mvvmFX
Don't make the mistake and try to derive some implementation patterns yourself from all the hello world examples out there on the internet. They all don't teach you how things should be done so that they scale well for real-world projects.
I need to visualize how a project develops over time.
I have used this: https://docs.oracle.com/javase/tutorial/essential/io/notification.html#overview
as basis for detecting when any project file has been modified locally.
The current setup is Android Studio on windows 7. And my problem is that the java.nio.file.StandardWatchEventKinds from the example only gets fired when the programmer manually does a "ctrl-s".
How do I detect Android Studios file modifications realtime?.
My fallback approach is to to set a timer an traverse all files. But i'd rather if I could just catch the appropriate file.
EDIT: solved with an IntelliJ plugin, took me 1/2 day.
first the tutorial from: https://confluence.jetbrains.com/display/IDEADEV/Getting+Started+with+Plugin+Development#GettingStartedwithPluginDevelopment-anchor3
and using the menuaction to start/stop a BulkFileListener:
public class Watcher implements BulkFileListener {
private final MessageBusConnection connection;
public Watcher() {
connection = ApplicationManager.getApplication().getMessageBus().connect();
}
public void initComponent() {
connection.subscribe(VirtualFileManager.VFS_CHANGES, this);
}
public void disposeComponent() {
connection.disconnect();
}
#Override
public void before(List<? extends VFileEvent> events) {
//logging done
}
#Override
public void after(List<? extends VFileEvent> events) {
//logging done
}
}
placed the . jar in ...\JetBrains\IntelliJ IDEA Community Edition 14.1.3\plugins
and imported as instructed in the tutorial.
After a whole night spent in test (without any luck) I need some support with my interface.
I'm working directly on the Android frameworks and I created a class that works as a Binder with a WeakHashMap to control the callbacks.
Here is the code:
MyCallback:
public interface MyCallback {
public void fire();
}
MyBinder:
public static WeakHashMap<String, MyCallback> mCallbacks =
new WeakHashMap<String, MyCallback>();
public static void setup(MyCallback callback) {
if(mCallbacks.get(callback.getClass().getName()) == null) {
mCallbacks.put(callback.getClass().getName(), callback);
}
}
public static void letsgo() {
Log.d("size", " " + mCallbacks.size()); // IMPORTANT
for (MyCallback cb : mCallbacks.values()) {
cb.fire();
}
}
These 2 classes are written into frameworks so I created 2 test applications with a simple class that implements my interface:
public class FirstApp implements MyCallback {
public FirstApp() {
MyBinder.setup(this);
}
#Override
public void fire() {
Log.d("app1", "fired");
}
}
public class SecondApp implements MyCallback {
public SecondApp() {
MyBinder.setup(this);
}
#Override
public void fire() {
Log.d("app2", "fired");
}
}
Ok at this point I made another class (all these 3 classes, so the 2 that implements the interface and the following one are written into different packages)
In this third class i just call: MyBinder.letsgo();
The issue I'm facing, and that I'm trying to solve since... 8/9 hours is that: If i run letsgo() on the third pack the logs shown 0 for the callbacks WeakHashMap size. if i run letsgo() on the second package it works but it only fires the callback in the same package. the same if i run it on the first package.
I tried also with HashMap instead of WeakHashMap since i red that objects must be referenced but without any luck. I wonder if someone can help me and let me go sleep :D Thanks!
I'm trying to run a gwt project. This project has 3 modules.
1-StudentSystem2
2-EnterStudent
3-GetStudent.
I want to enter student id,name,department in enter class and when i click add button add them to database and change window. But when click add button it gives
No file found for: /com.example.studentsystem2.client.enterStudent.enterStudent/dao
and prints xxx. how can i connect two modules in dao service??
Here is the package structure.(sorry not to load image because of the lack of reputation)
com.example.studentSystem2
-> studentSystem2.gwt.xml
|com.example.studentsystem2.client
-> StudentSystem2.java
||com.example.studentSystem2.client.enterStudent
->enterStudent.gwt.xml
||com.example.studentSystem2.client.enterStudent
->Enter.java
->EnterStudent.java
->Enter.ui.xml
||com.example.studentSystem2.client.getStudent
->getStudent.gwt.xml
||com.example.studentSystem2.client.getStudent
->Get.java
->GetStudent.java
->Get.ui.xml
||com.example.studentSystem2.client.request
->Dao.java
->DaoAsync.java
->EMF.java
->StudentInfo.java
|com.example.studentSystem2.server
->DaoImpl.java
here is the onClick method in Enter.java
#UiHandler("addButton")
void onAddButtonClick(ClickEvent event) {
dao.addStudentInfo(IdTextField.getText(),nameTextField.getText(),departmentTextField.getText(),new AsyncCallback<Void>() {
#Override
public void onFailure(Throwable caught) {
System.out.println("xxx");
}
public void onSuccess(Void ignore) {
Window.Location.replace("http://127.0.0.1:8888/GetStudent.html?gwt.codesvr=127.0.0.1:9997");
}
});
}
and the Dao.java class
#RemoteServiceRelativePath("dao")
public interface Dao extends RemoteService {
public List<StudentInfo> listInfos();
public void addStudentInfo(String SId, String name, String department);
public void remove(String id);
}
You can do it in 'N' ways. One way which I favor is, keep your service and its implementation in a separate module. Then add this module as a dependency to your other modules. Then you are able to access the same service for which you had added the dependency.
While simple, interface-driven event notification frameworks in Java have been around since pre-Cambrian times (e.g. java.beans.PropertyChangeSupport), it is becoming increasingly popular for frameworks to use annotation-driven event notification instead.
For an example, see JBossCache 2.2. The listener class has its listener methods annotated, rather than conforming to a rigid interface. This is rather easier to program to, and easier to read, since you don't have to write empty implementations of listener callbacks that you're not interested in (and yes, I know about listener adapter superclasses).
Here's a sample from the JBossCache docs:
#CacheListener
public class MyListener {
#CacheStarted
#CacheStopped
public void cacheStartStopEvent(Event e) {
switch (e.getType()) {
case Event.Type.CACHE_STARTED:
System.out.println("Cache has started");
break;
case Event.Type.CACHE_STOPPED:
System.out.println("Cache has stopped");
break;
}
}
#NodeCreated
#NodeRemoved
#NodeVisited
#NodeModified
#NodeMoved
public void logNodeEvent(NodeEvent ne) {
log("An event on node " + ne.getFqn() + " has occured");
}
}
The problem with this, is that it's very much more of an involved process writing the framework to support this sort of thing, due to the annotation-reflection nature of it.
So, before I charge off down the road of writing a generic framework, I was hoping someone had done it already. Has anyone come across such a thing?
You can already do this today with EventBus.
Following example is from EventBus Getting Started guide. Statusbar that updates based on published events, and no need to register statusbar control/widget as listener of publisher(s). Without EventBus, statusbar will need to be added as listener to many classes. Statusbar can also be created and destroyed at any time.
public StatusBar extends JLabel {
public StatusBar() {
AnnotationProcessor.process(this);
}
#EventSubscriber(eventClass=StatusEvent.class)
public void updateStatus(StatusEvent statusEvent) {
this.setText(statusEvent.getStatusText();
}
}
A similar project is ELF (Event Listener Framework) but it seems to be less mature.
I'm currently researching about event notification frameworks on Publish-Subscribe Event Driven Programming | Kev's Spring vs Java EE Dev and the followup articles.
I've made http://neoevents.googlecode.com to handle this kind of annotation based event handler.
#actionPerformed
private void onClick() {
//do something
}
protected void initComponents() {
JButton button = new JButton("Click me!!!");
button.addActionListener(new ActionListener(this) );
}
It looks as simple as I was expecting it to be. Annotations are available for every single listener in J2SE.
Don't mistake complicated for clever. It seems to me that this would be:
A nightmare to debug
Difficult to follow (from a maintenance perspective, or someone attempting to change something 6 months down the line)
Full of if (event instanceof NodeCreatedEvent) like code. Why this is better than subclassing an adapter I have no idea!
The main problem I see here are the method parameters, which restrict which methods can actually be used for which events, and there's no compile-time help for that.
This is what makes interfaces attractive to me for observer pattern implementations like the Java event model. Tools like eclipse can autogen method stubs so you can't get the signatures wrong. In your example, it's very easy to use the wrong parameter type and never know it until an event occurs (which might be an error case several months down the line)
One thing you might try are my annotations & processor for implementing observers and null object implementations. Suppose you have
package a.b.c;
public interface SomeListener {
void fee();
void fie();
void fo();
void fum();
}
and wanted to create a listener instance. You could write
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
}
}
To create a source for these events, you can write
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
}
See http://code.google.com/p/javadude/wiki/Annotations if you're interested. Might give you some other ideas as well.
Google Guava v11 has added an EventBus component that uses this style. They also explain why they decided to use annotations rather than interfaces.
I've been thinking about a generic annotation-driven event framework as well. I like the benefits provided by static typing, but the current interface-driven event model is painful to use (ugly code). Would it be possible to use a custom annotation processor to do some compile-time checking? That might help add some of the missing "safety" that we've all grown used to.
A lot of the error checking can also be done at the time that the listeners are "registered" with the event producers. Thus, the application would fail early (when the listeners are registered), possibly even at at startup-time.
Here's an example of what the generic framework I've been toying with might look like:
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"));
}
}
The producer uses EventSupport, which uses reflection to invoke the events. As mentioned before, EventSupport could preform some initial checks when the events listeners are registered.
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
}
}
Here, EventSupport has a static method that uses reflection to auto-register the listener with the event producer. This eliminates the need to manually register with the event source. A custom annotation processor could be used to validate that the #HandlesEventFor annotation refers to an actual field of the ExampleListener. The annotation processor could do other checks as well, such as ensuring that the event handler method signature matches up with one of the registration methods on the ExampleProducer (basically, the same check that could be performed at registration-time).
What do you think? Is this worth putting some time into fully developing?
Here's a similar project called 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));
}
}
I think this is very easy to use.
You can also check out MBassador It is annotation driven, very light-weight and uses weak references (thus easy to integrate in environments where objects lifecycle management is done by a framework like spring or guice or somethign).
It provides an object filtering mechanism (thus you could subscribe to NodeEvent and attach some filters to restrict message handling to a set of specific types only).
You can also define your own annotations to have customized declaration of your handlers.
And it's very fast and resource efficient. Check out this benchmark showing a performance graph for different scenarios using Guava or mbassador.