• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Liutauras Vilda
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Saloon Keepers:
  • Scott Selikoff
  • Tim Holloway
  • Piet Souris
  • Mikalai Zaikin
  • Frits Walraven
Bartenders:
  • Stephan van Hulst
  • Carey Brown

Help with program structure

 
Ranch Hand
Posts: 265
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am a needing a little help understanding how to construct an application.

I have one file with a table class in it to put a table in a larger dialog
I have another file with a graph class in it to graph the data in the table

I also have an external program that I connect to. I need it to populate one of the columns in the table as the user types the data into the other fields.

I am not sure how to sensibly hook things together.

I have a listener for the table, but it needs to know the reference of the external program I start. Should I pass that in when I make an instance of the table? Should I have a main program that extends my initial table class and defines a listener that knows about the external program? Or is there a cleaner way to organize things.

The graph must also update as the table is changed. Should the table somehow inform the graph to update? Or should the main program be listening to the table and also passing on to the graph the updated data?

Before I make something convoluted, I was hoping to get some advice on what might be a clean way to handle the interaction between the external program, table and graph. At some point, other components may also need to send and receive information from the external program. I can only have one copy of it running.
 
Ranch Hand
Posts: 214
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What do you mean by "external program"? Is it some totally different java program? Running on the same computer, or a different one? or a program in another language that you have no control over?
 
Jon Swanson
Ranch Hand
Posts: 265
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The program is R, which does statistics. On the Java side, I create an instance of an Rengine. That starts the program R. I have no control over R, except to start it. Then I can either send commands to R (in it's language) or retrieve data from R. I can only create one instance of R in my program (limitation of R). The table has a couple of columns in which the user adds data points. The remaining columns are computed statistical values based on the data in the user entered fields. The computed data also needs to be displayed as a scatter plot and in a second summary table. There is a second pane that also will be using R, that computes some of the data that is needed for the plot. It has its own set of tables and graphs.

The requirement is that the changes to the summary table and plot update in real-time as the user changes the data in the first table.

I want to make sure I structure the components and the communication between them in a sensible way and felt it was best to get some advice from experts before committing too much to code.
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jon Swanson wrote:The program is R, which does statistics. On the Java side, I create an instance of an Rengine. That starts the program R. I have no control over R, except to start it...


Are you required to use R? From what I understand, JGraph is quite good, and it's Java, so you won't have any artificial constraints. There's even a new product called JGraphT, although how it dovetails I don't know (fairly easily, according to the website). Even if you do have to use R, you may find it just as easy to use it as a repository and do the GUI stuff with JGraph.

Winston

 
Jon Swanson
Ranch Hand
Posts: 265
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the information. Let me clarify. I am using R for the statistics, for example, to do a weighted multiple linear regression. As you suggest, I was not planning to use R for the scatter plots. I was planning to use JFreeChart, which seems to be able to produce very nice plots. JGraph looked to me to be all graphs and no charts. But R is still my calculation engine (send arrays to R, get regression coefficients back in Java, make scatter plot in Java).

Even without the R bit, I am not experienced enough for it to be obvious how my table class tells my plot class when and what it needs to know to replot itself. Right now everything is in one big java file, so everybody knows about everybody else and everything works. But it seemed smarter to have one file per class and that has got me uncertain about the best way to keep everybody talking to each other.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jon Swanson wrote:Even without the R bit, I am not experienced enough for it to be obvious how my table class tells my plot class when and what it needs to know to replot itself. Right now everything is in one big java file, so everybody knows about everybody else and everything works. But it seemed smarter to have one file per class and that has got me uncertain about the best way to keep everybody talking to each other.


Well, one model you might want to look at is Observable/Observer; although there may be better (or tighter) versions of the same specifically for GUIs; I'm afraid I'm no expert there.

Basically, the idea is that your table class extends the Observable class and notifies "observers" whenever a change is made (if these are likely to be overly busy, you may want to "batch" them somehow). Any class that needs to "see" a change to the table implements the Observer interface and registers itself with the table as an observer, and thus gets notified.

I know that Swing has a similar Event/Listener setup which may work better for GUI components, but it's also less generic and therefore (possibly) less flexible.

Winston
 
Jon Swanson
Ranch Hand
Posts: 265
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think the best thing to do about R is have a class of static methods. Something like this-



Then I will only have one R engine that everyone finds with the static variable and any of my other classes can run the methods. I thought about having the various check if the Rengine was started and start it if it wasn't, but I felt it was better to have the main method try to start the R engine and not allow the GUI to start if there are problems with starting R. It would seem a bit confusing if R could not start and the GUI kept trying to generate data.

Anyone see a problem with this approach?

Next is to think a little more about everything listening to everything else.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jon Swanson wrote:I think the best thing to do about R is have a class of static methods. Something like this-
...
Anyone see a problem with this approach?


A couple:
1. If, in the future, a version of R comes out that does support multiple instances, you've kind of hamstrung yourself by making everything static. One way you might get around that is to use the Singleton pattern, where everyone who wants a copy gets the same copy. Have a Google for it.
2. Is there any reason you can't just fire up your REngine straight away? It would save you having to write all those 'if (REngine)...' statements (which should actually be if (rEngine != null)...; you haven't given your REngine a name).

Alternatively, another little trick is something called an "initialization on demand Holder", which works like this:and uses a guarantee given by the JLS that a class is not loaded until it's actually needed. The same pattern can also be used with a Singleton.

However, if you can just start the engine as soon as it's loaded, it'll probably be clearer.

Winston

Edit: BTW, if you really want this to be a 'static only' class, you should add a private parameterless constructor.
 
Jon Swanson
Ranch Hand
Posts: 265
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I was actually planning to start R before I start the GUI. There are two cases I am concerned about:

REngine does not start. No problem there, I report an error and quit.

REngine crashes while the GUI is running. I have a couple options:
- try and restart it
- report a failure and require the user to quit
I guess my feeling is that if REngine crashes, there are going to be so many problems (data is cached in R) that it is best to get the user out of the interface. Maybe better to throw an exception if REngine is no longer available?

Am I understanding the Holder class correctly in that since REngine is static, it is initialized when the class is loaded. So startR() will only run once? After that it just returns the value to which it was initialized?

I'll Google patterns as well.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jon Swanson wrote:Am I understanding the Holder class correctly in that since REngine is static, it is initialized when the class is loaded. So startR() will only run once? After that it just returns the value to which it was initialized?


Correct, and furthermore the class itself only gets loaded when it is first referenced (ie, by a call to one of the methods that actually uses Holder.rEngine).

I'll Google patterns as well.


I'd Google "Singleton pattern".

Winston
 
Jon Swanson
Ranch Hand
Posts: 265
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Right singleton pattern, thanks.

Here is what I have put together related to the other part of my question. I replaced my table with a button and my graph with another button. Then I made these files-

TestFrameMain.java // just starts my test


TopButton.java // stand-in for my table class, which will process a bunch of events that just relate to the table


BottomButton.java // stand-in for my graph, which will also process a bunch of events that just relate to the graph


TestFrame.java // Puts the GUI components together


This works. The top button background alternates between blue and red when I click the top button and the bottom button foreground also changes. I suppose a better example would have included a get method to get the count from TopButton and use it when setting the bottom button.

Does this structure make sense or is there a better solution for this type of problem (in the real application a scatter plot redraws whenever data in a table is changed)?
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jon Swanson wrote:Does this structure make sense or is there a better solution for this type of problem (in the real application a scatter plot redraws whenever data in a table is changed)?


I'm afraid I'm no GUI expert, so I can't tell you whether it's "the best" or not (I''m sure there are others that can though), but the basic idea seems sound.

If you think about it empirically, you have a table component that needs to be able to inform a few other select components of changes to its contents; an "I have changed" message if you like.
Those components in turn need to be able to react to those changes. From what I understand, an ActionEvent is used specifically for GUI component actions and so may contain spatial and other information that isn't strictly needed in your case, but the mechanism is very familiar and so may be the easiest one to use. I'm sure that others can tell you if there's a lighter-weight alternative available.

Another thing you might want to think about is how you communicate the "changes". If a single value changes, does the Graph component really need to read the entire table again, or can it simply be informed of what changed and where and update itself accordingly? I suspect that will have a lot to do with what you use to draw the Graph and what it needs to know, but a bit of refinement in that area may go a long way to making your "change control" as lightweight as possible.

Another possibility might be to batch changes, so that the Graph isn't constantly reacting to things that aren't likely to make a noticeable difference, but that adds a new layer of complexity.

Sorry I can't be more specific, but I suspect that you're the best one to answer most of those questions. Sounds like a fun problem though. Good luck.

Winston
 
Jon Swanson
Ranch Hand
Posts: 265
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks. I'm not sure that updating the graph everytime there is a change is the best idea, but I'm not the one writing the specs for that. I'm a little worried about race conditions when I have multiple listeners. Not to mention the cost of doing all that work. Do you think I should post something over in the GUI forum? I don't want to be repeating myself in multiple forums and upsetting people.
 
Marshal
Posts: 80097
413
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You ought not to get race conditions with multiple listeners because all Swing components should be accessed from the same thread. Remember listeners respond to user commands, and moving your hand is much slower than just about anything a computer can do.

I think it might be worth transferring this discussion to the GUIs forum.
 
I'm thinking about a new battle cry. Maybe "Not in the face! Not in the face!" Any thoughts tiny ad?
Smokeless wood heat with a rocket mass heater
https://woodheat.net
reply
    Bookmark Topic Watch Topic
  • New Topic