I have a program that must output the data of a weighting scale. It uses a thread to read continually data from the rs232 source and must output the data graphically. The user can open and close as many Jframes as it wishes and all must show the same data that is read from the rs232 in a JTextArea. How can I approach this? Thank you very much in advance.
-
Have a look at the observer pattern, essentially your thread needs to generate events to which your frame listens to, just beware that swing is not thread safe – MadProgrammer Jan 14 '17 at 01:10
-
What will be a more thread-safe approach? Thank you for your answer. @MadProgrammer – Giovanni Poveda Jan 14 '17 at 01:25
-
You just need to be aware that your "thread" will generate events within it's own context, then use things like `SwingUtilities.invokeLater` or a `SwingWorker` to ensure that any updates you make to your UI are done from within the context of the Event Dispatching Thread – MadProgrammer Jan 14 '17 at 02:02
-
See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) – Andrew Thompson Jan 14 '17 at 02:40
2 Answers
There are a number of ways you might approach this problem
The user can open and close as many Jframes as it wishes and all must show the same data that is read from the rs232
This raises the question if you're only interested in the real time results or the historical results. For argument sake, I'm only going to focus on the real time results.
Basically you need to start with a class which is responsible for actually reading the data from the port. This class should do only two things:
- Read the data
- Generate events when new data is read
Why? Because then any additional functionality you want to implement (like writing the data to a database or caching the results for some reason) can be added later, simply by monitoring the events that are generated.
Next, you need to define a interface
which describes the contract that observers will implement in order to be able to receive events
public interface ScaleDataSourceListener {
public void scaleDataUpdated(ScaleDataSourceEvent evt);
}
You could also add connection events (connect/disconnect) or other events which might be important, but I've kept it simple.
The ScaleDataSourceEvent
would be a simple interface
which described the data of the event
public interface ScaleDataSourceEvent {
public ScaleDataSource getSource();
public double data();
}
for example (I like interfaces, they describe the expected contract, define the responsibility and limit what other people can do when they receive an instance of an object implementing the interface, but that's me)
Your data source would then allow observers to register themselves to be notified about events generated by it...
public interface ScaleDataSource ... {
//...
public void addDataSourceListener(ScaleDataSourceListener listener);
public void removeDataSourceListener(ScaleDataSourceListener listener);
}
(I'm assuming the data source will be able to do other stuff, but I've left that up to you to fill in, again, I prefer interfaces where possible, that's not a design restriction on your part ;))
So, when data is read from the port, it would generate a new event and notify all the registered listeners.
Now, Swing is not thread safe, what this means is, you shouldn't make updates to the UI from any thread other then the Event Dispatching Thread.
In your case, probably the simplest solution would be to simply use SwingUtilities.invokeLater
to move from the data sources thread context to the EDT.
Basically, this is a simple Observer Pattern
There are a lot of other considerations you need to think about as well. Ie, are the frames been opened within the same process as the data source, or does the data source operate within it's own, seperate process. This complicates the process, as you'll need some kind of IPC system, maybe using sockets, but the overriding design is the same.
What happens if the data source is reading data faster then you can generate events? You might need some kind of queue, where the data source simply dumps the data to the queue and you have some kind of dispatcher (on another thread) reading it and dispatching events.
There are number implementations of blocking queues which provide a level of thread safety, have a look through concurrency APIs for more details.
... as some ideas ;)

- 343,457
- 22
- 230
- 366
first, create a frame class extends JFrame, and create a method to receive data from rs232. Then every object of this class can get data using that method. u can create one frame by creating one object of the class.

- 23
- 4
-
Your answer is not correct in that it doesn't answer the basic issues that the OP is having. Please compare your answer to MadProgrammers, and check the quality difference. – Hovercraft Full Of Eels Jan 14 '17 at 03:52