Welcome to the new FlexRadio Community! Please review the new Community Rules and other important new Community information on the Message Board.
If you are having a problem, please check the Help Center for known solutions.
Need technical support from FlexRadio? It's as simple as Creating a HelpDesk ticket.

Question for Java Developers - Multiplatform GUI classes

IW7DMH, Enzo
IW7DMH, Enzo Member ✭✭
edited February 2017 in SmartSDR API
Hello,

I would like to know if someone is aware of a "true" multiplaform GUI library for Java applications.
I am struggling using SWT framework but it seems it is tightly coupled with os libraries, even if you try to use the deployment swt.jar archive released for each specific O.S.
I am in a kind of paradox as at the moment I am having success getting rid of TX/RX libraries. For interfacing with RS232 ports I am using the Java Simple Connector Library https://code.google.com/p/java-simple-serial-connector/ and it works flawlessly with Windows, Linux and Mac. Up today I have no need to recompile the project going from one os to the other.
I decided to open this post because the same information/hint could be helpful to other friends.

73' Enzo
iw7dmh


«1

Answers

  • Mike KD2CJJ
    Mike KD2CJJ Mr Member ✭✭
    edited February 2017
    Enzo,  There really isnt any.  The moment you need to interface with hardware acceleration you precluded portability.  SWT is your best bet and even then like you said there is tight coupling... However, that coupling should be abstracted from you for the most part.  I am no expert in SWT however - and particularly hate it! 

    To get to true multi platform your best bet is to use HTML5 and leverage the browsers engine to perform the rendering.  That will give you hardware acceleration with enough portability across various OS as its relying on the browser acceration engine that have the hooks into the GPU.    As an example video players today rendered in HTML5 have the ability to stream 4K video with high fidelity audio when using lossless codecs.

    So, an idea could be to develop the entire user interface rendering in HTML5, develop your application/networking objects that deal with interfacing with the radio in Java as you are.  To serve the pages and bridge the UI layer with the application / networking object layer you can use something like NodeJS that is lightweight and requires no APP server to serve all the HTTP requests.    It also has the benefits of very little IO due to its event base efficient thread handling nature.

    In theory you could create a self contained app that can run locally or even remotely via any web browser.

    It may behoove you to do the application / networking layers all in .Net get it working as  POC since the native libraries are there already to access the radio.  Abstract those layers using NodeJS and focus on the UI layers using HTML5. - then port the application /networking layers later to Java since you would have already built the scaffolding needed. 


    This is a concept that I have had since I saw the FlexAPI... Just no time  to execute. LOL!






  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    I'd have to disagree. JavaFX8 is such a platform. I have what I believe to be a 100% compatible replacement for flexlib which in the testing I've done is 100% compatible. Javafx8 provides a graphical environment that rivals WPF.


    SWT got its foothold as a replacement for AWT which, in its infancy, was buggy in the wora model, so SWT became the graphics engine for eclipe and IBM's productized version of Eclipse.


    Further java8 supports lambda expression which makes mimicking the .NET event model incredibly easy.


    On the cross platform experience, it runs flawlessly everyplace I've tried it, Linux, Windows, and Android. And I've run it at over 60 fps. When I say, "what I believe to be" that is because I haven't driven every last method in every last class. If one doesn't work properly its a bug not a limitation.
  • Mike KD2CJJ
    Mike KD2CJJ Mr Member ✭✭
    edited February 2017
    Wow!  I havent followed JavaFX in a while.  I see it does provide with 8 and above HW Accerlation.

    I stand corrected!

    Nice to see this..  

    I have been out of it too long!
  • IW7DMH, Enzo
    IW7DMH, Enzo Member ✭✭
    edited January 2017
    Hello Walt,

    thank you very much for this great hint.

    I followed JavaFX for a while, some years ago, but I never had opportunity to use it.

    So, now I have some questions:

    - as I have to start from scratch con you suggest me a ready-set-go study program? Your preferred links and books, or something like, are welcome.

    - Can you anticipate the reference patterns that a JFX developer should follow?
     
    - Probably you already talked about it but when are you planning to release your libraries? And what will be the license type?

    Just to close the SWT experience, I have to say that the only solution I found was recompiling the same source code on each Operating System ...

    Thank you again and 73'
    Enzo
    iw7dmh
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited February 2017
    Actually, the predecessor to javafx8 would have worked as well. It just would have required more finese.. I guess I had better luck with swt than your experiences. Most people think of Eclipse as an IDE, which it is. However, it has always been marketed as "a container for anything or nothing at all". It is and was fantastic as a framework for RIA (Rich Internet Applications) and comes with very impressive graphic containers. In the very early days of java, AWT, was pretty pathetic and that gave rise to the," write once, debug everywhere' snip. That hasn't been the case in a very long time. Javafx8 has its own graphics engine, quantum, which in turn calls into Prism which in turn drive java2d, opengl, or D3D, depending on what's required and available hardware. It can also do native HTML 5. Opengl being the industry standard for high speed graphics. One thing I did do in XPSLib is add a data access object to all the classes such that all the backing data would be decoupled from the actual xpslib methods.. In the case of javafx8 UI the actual desktop controls are directly coupled to the backing data such that once the TCP status message is parsed the data value(s) is immediately reflected on the control surface. Frankly, I suspect this is how WPF also works but being barely able to spell WPF, I can't say with certainty. So, how do you get there? That depends largely on where you are starting from. If you know Java, which I thought you (Enzo) did then you are 85-90% there. If you also know SWT you are now 95% there. There is this really good book that just recently went to print I highly recommend, on its technical merits. I pan it mercilessly on its copy editing, "Learn Javafx8" by Kishori Sharan. It might be Shiran, if one doesn't work, try the other. XPSLib is current as of 1.4.16. I've been, frankly, less than motivated in continuing to play catch-up. There are several reasons for this, none of which I am willing to discuss in this forum. Will all that effort die with me? Highly unlikely. I will,at least, make it available in jar form, with copious examples of discovery, panadapter creation, slice creation, text to cw, etc.
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    Mike, I wasn't ignoring you. From you comments I took you to be already at least at the 95% there mark. Javafx8 graphics capability are crazy impressive. And on a very old Q6600 based processor with a very old video card in their graphics sample program it easily performs very aggressive graphics at over 60 fps.
  • IW7DMH, Enzo
    IW7DMH, Enzo Member ✭✭
    edited December 2016
    Hello Mike,

    I am sorry if I didn't answered, but with my small smartphone I didn't read your first answer.
    I appreciate a lot your help of course, but as you already read, Walt has answered and clarified lots aspect of the Java FX technology.
    I am going to spend some of my time in learning this other Java "block".

    Thank you very much and 73'
    Enzo
    iw7dmh

  • Mike KD2CJJ
    Mike KD2CJJ Mr Member ✭✭
    edited October 2015
    Walt,  I did some reading and its been many years since I took the time to build a complete application out.  I dont think I will have the patience anymore . I used JavaFX very early on after stints of AWT and SWT in Eclipse none of which were very mature at the time for heavy graphical work.  Stuck with what ever was native to the platform at the time.  

    However, I am super impressed with how mature JavaFX in my short readings - it may jiggle my creative side!

    Thanks for the great info!  


  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    Mike, there is an app I downloaded to my Nexus9 tablet. As I recall it is JavaFX Ensemble and it has copious examples of javafx graphic controls running natively under Android 5,at the point I got it, and 6 now. There is another app called DemoFX or DemoFX-master that runs on, I'll say, any platform that can be started to go through a series of animated graphic operations, transforms, sheers, rotates, enlarge, shrink, etc. I've run it on windows and linux just fine and that can be started to use a gpu if found or, what Prisim will do in the absence, do the graphics itself. It's faster with and under the covers is using OpenGl without you knowing native OpenGL api. As I implied, the stuff I've done on top of XPSLib (XPS is cross platform SDR) runs just fine under Windows or Linux. I know of a lot of people who use it (JavaFX) on MAC. One of the books I have goes into detail of moving a desktop JavaFX app to Raspberry Pi and Ardino or whatever that platform Enzo is working with.

    I retired at the beginning of the year, February to be precise, after about 45 years in software development. I wrote PMNOS and OSNOS in the 80's and ended up supporting them far beyond what suited my purposes. I have little desire to revisit that model,esp for free. 
  • IW7DMH, Enzo
    IW7DMH, Enzo Member ✭✭
    edited December 2016
    Thank you for your answer Walt.
    I bought the book and while I am waiting for it, I spent some time to install Java 8 in my Ubuntu 14.04 workstation and to install the e(fx)clipse plugin into my Eclipse IDE.
    I can say I have good Java knowledge as I have SJCP and SJCD certifications, but I never seriously developed applications using SWT. That's the reason I need to read.
    Also I hope you can go on with your work as I think that your choice is surely the most difficult but also the most farsighted (I hope my translation is correct).

    73' Enzo
    iw7dmh
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    Also, for both of you, be sure to look at JavaFX SceneBuilder. You'll have to make the 2.1 executable but, it's worth it. In that book I referenced it goes into that. So what happens is you, drag and drop the visual objects you want and add in the css pointer (yes CSS is used in other than html) and other information on the objects and it builds an xml object (controller) that you instantiate at run time. So basically much of the nuts and bolts and 'slime' of doing the graphics is completely abstracted away. It's great!! It gets high marks as far as separation of concerns, which at the end of the day, object oriented is all about...well...if it is implemented right.
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    Enzo, I was never impressed with how NetBeans worked under Java8v45 so I ended up running NetBeans under Java7 and everything else under Java8 and issuing copious bug reports for Oracle to keep their employees paid with. However, MANY people urge those using JavaFX to use Netbeans rather than Eclipse so if you should run into endlessly chasing your tail with Eclipse bag it in favor of NetBeans. The last version of Java 8 I was aware of was 65 so that may cure the ills I saw running NetBeans under it.  My motherboard in the XPS720 with the Q6600 processor apparently died so I never got to upgrade the version of Java8. And it's replacement, Inspiron 3857 or some such I5 with an AMD video card runs SSDR just fine with very good video performance. It runs Linux even better.
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    Also, it's very straight forward to have each panadapter be 'pinnable' or, hey, what the heck, have each instantiated panadapter be a separate window from the start.  That, if you're wondering about the DAO rationale, makes no sense on a tablet where it, best case, would be in a rolodex control and one just thumbs from one panadapter to another, the one on top gets the focus.

    DAO, if one wanted a native Android version of XPSSDR (cross platform SSDR), Android 6 does it's data binding differently so in that case the requisite DAO for any class is dynamically loaded at startup. Android has exploitable features that a desktop system doesn't which is why I left the trapdoor to at runtime switch binding models.
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    I should probably add this for those that know C# but have yet to experience the joy which is writing apps that run anywhere. If you already know object oriented design and C# you, too, are 85 - 90% there. If you know WPF, you are even further along. At the end of the day, they do pretty much precisely the identical thing. In fact C# uses "using", a through back to C, but it also understands import, which is what Java uses.
  • James Whiteway
    edited November 2016
    Walt, I just downloaded the book you mentioned earlier. I was wondering what OS and development enviroment you would suggest to use with it? I have Visual Studio 2015 with Win10 and it supports Java development now. I'm guessing some flavor of Linux for the OS. But, otherwise would like your input. Thanks. James WD5GWY
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    Absolutely not James. You totally can use Windows 10. Both netbeans and Eclipse run perfectly fine under Windows. I would, personally, not use visual studio. Microsoft products tend to work best with Microsoft's products. The difference is, unlike the Microsoft development tools, Netbeans, Eclipse, and Java in general, are absolutely free. I should also point out something I hadn't mentioned so far, JavaFX is now part and parcel of the java software development environment as well as runtime. For development, you want to download the Oracle Java 8 JDK. The JDK includes a Java runtime.
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    BTW, I also use the Kindle version of that book.$37 is WAY better than $58. You'll enjoy the book. Again though, the copyediting left much to be desired. It's still readable.
  • IW7DMH, Enzo
    IW7DMH, Enzo Member ✭✭
    edited January 2017
    My first attempt to deploy a trivial form on Windows, Linux and Mac OS-X was 100% ok.
    Really great!
    My first non trivial project will be porting on JFX the small program that drive my remote cw key.

    image

    There are one million of questions I would like to do, and of course it is better I read before, but I am wondering if data-binding is as simple as declaring somewhere my model objects or I have to use some additional IOC system.
    I am also curious to know what is the implemented thread model and (as I suppose) if it can handle synchronous and asynchrounous events coming from non GUI objects.
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    SpringFrameworks? No. Everything you need comes in the box, so to speak. There is a very rich threading facility. That is precisely how events flow, non application thread. By that I mean UI drawing must occur in, what's called, the application thread. In XPSSDR, for instance, in the onRadioAdded method, which is an asynchronously invoked thread, you register interest in those events that the radio owns, e.g. the panadapter. It's very similar to how you would do that in C#. Also in the onRadioAdded method you'd set up the control surface components that are radio objects. Jumping ahead to the panadapte's onDataReady invocation, from a worker thread, you do all the setup and when you are ready to actually draw you place the drawing logic in a run later() block and logic is then scheduled to run on the application thread. It's all very transparent. Your sample app will be very straight forward. The basic presentation model follows a theatre/play. The main area is the stage. This is the abstraction of the window. Each stage has at least one scene. You can have multiple stages and multiple scenes. On your first nontrivial app, just remember com[D+] only has relevance in Windows so you might want to ask what system its running on and call it ttys[D+] on other systems. Likely that's not a top concern now. I mention it only because its a relevant topic now.
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    Oh, you're going to need something from me. Where you have the two named group boxes for local and remote, I have a typedGroup widget I'll send you the code for.
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    James and Enzo, are you guys basking in JavaFX8 goodness yet? I remember Enzo ordered the book but James got the Kindle version. Hopefully you're both through the fist three or so chapters.
  • IW7DMH, Enzo
    IW7DMH, Enzo Member ✭✭
    edited December 2016
    Yes Walt,

    I received the book and started with it. I use to read a bit and (mostly in the weekend) try to implement the code.
    At the moment I am fascinated from invalidation/change notification support in the ObservableList and I am going to get the most from it.
    It is sure I was going to loose one of the best pieces of the Java world and it is sure I'll ask for your help when things will be harder.

    Thank you very much
    73' Enzo
       
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    I am reasonable sure you will very much enjoy it. Absolutely, feel free to ask any questions you have. You as well James.
  • James Whiteway
    edited November 2016
    Thanks Walt. I'm out on the road right now and have only read part of the first chapter. 750 + miles a day wears me out to the point that when I shut down for the day, all I want to do is sleep! But, I will keep reading! James WD5GWY
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    I completely understand James no pressure from me. One thing I wanted to say to both of you is when I first started this path there were three books that I bought because each of the three seem to focus more on a different area so between the three I get a bigger picture. this book that I recommended seems to cover all the areas fairly well but a book you might want to consider which is from Oracle itself is mastering JavaFX 8 controls. it strictly covers the controls, the graphical user interface widgets. But go through the one you have first.

    The other thing I failled to mention is you can control the packaging, for Windows it will create a complete .msi file, for Linux a complete .deb file, not sure about ios.
  • IW7DMH, Enzo
    IW7DMH, Enzo Member ✭✭
    edited December 2016
    You were right, Walt.
    It is an amazing way to develop multiplatform applications.
    At the moment I have implemented the underlying code that runs two threads: UdpReader and ComPortReader.
    Now I am going to implement the Model layer and the question is actually very simple: before I was used to develop simple Pojo objects but now I think it is better to implement the model using properties and native binding support offered by JavaFX.
    I suppose in this way I'll tightly couple the underlining level with the GUI level but I'll get best support from the embedded invalidation/notification system already implemented in JavaFX.
    In the future the model will have additional properties like eight relay status and three serial ports.
    Is this the proper way to go on?

    Thank you very much
    73' Enzo
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    I would not advise that. What I did, mid stream....well, actually late stream is to rewire property bindings into a data access object. In this way I loosely copy the model, be it Radio, Panadapter, Slice, etc from their underlying data. In the in the model code itself I have accessors to return the property object, that which one binds to so whatever view object isn't really knowledgable of the underlying data. For instance how one does that natively in JavaFX8 is different than how one does that natively in Android. So I bought myself the flexibility to write native Android and simply swap out the instance of the particular DAO backing object.

    One thing I've discovered is there is ample opportunity to have race conditions. For instance,
        private void onPanAdded(Panadapter pan, Waterfall fall) {
            activePan = pan;
            assert (activeRadio.findPanadapterByStreamID(activePan.getStreamID()) != null);
            int fps = activePan.getFPS();
            Platform.runLater(() -> {
                activeStage.setTitle(activePan.getBand() + " Meters");
            });
            activePan.addObserver(this);
            log.debug("Entering processPanAdded" + activePan.toString() + " " + fall.toString());
            PanDataReadyEventHandler tempVar1 = (Panadapter panx, short[] data) -> onPanDataReady(panx, data);
            activePan.addDataReadyEventListeners(tempVar1);
            WaterfallDataReadyEventHandler onWaterfallDataReady = (Waterfall waterfall, WaterfallTile tile) -> onWaterfallDataReady(fall, tile);
            fall.addWaterfallDataReadyEventListener(onWaterfallDataReady);
            activePan.setSize(new Size((int) spectrumCanvas.getWidth(), (int) spectrumCanvas.getHeight()));
            fall.setSize(new Size((int) waterfallCanvas.getWidth(), (int) waterfallCanvas.getHeight()));I
    The addObserver() is superfluous now as interested parties can bind directly as in activeStage,title.bind(activePan.getBandProperty().

    It doesn't matter whether one triggers the property change events or binds to the active panadapter properties, by the time this event notification occurs, much of the  setup has already occurred.

    So take care about that. Also, cross platform can be achieved post class file creation by running the jar through a post processor which will take JavaFX8 code and convert to be Android...or IOS etc. Take a look at http://docs.gluonhq.com/javafxports/

    Gradle is your friend!
    So I really didn't have to do a separate  DAO but it is more flexible and loosely coupled rather than hardwired.

    What I intially did was redo the model classes as portable so XPSLib mirrors +/- flexlib. The videos I had put up on YouTube pretty much showed the stuff I had done running on Linux as well as Windows. The window decorators were different. That was the only clue. Decorators being the max, min, restore and close buttons on the frame. Java handles all that for you. Oh, and Netbeans will produce an MSI file for Windows, whatever  Mac wants, d-something, a deb file for Debian based Linuxes, an rpm for Redhat based Linuxes.
  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    The other thing I would suggest is using Netty for your UDP and TCP I/O. It handles much of the communications housekeeping for you and makes it easy to write specialized encoders and decoders for the various Vita-49 packet types as well as String date. So what gets presented are fully formed objects representing the various data types and fully formed strings for the command/reply text. It saves having to reconstruct each object type yourself.

    For instance:
    package org.cornova.portablesdr.util;

    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelPipeline;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.handler.codec.DelimiterBasedFrameDecoder;
    import io.netty.handler.codec.Delimiters;
    import io.netty.handler.codec.string.StringDecoder;
    import io.netty.handler.codec.string.StringEncoder;
    import io.netty.handler.ssl.SslContext;
    import org.cornova.portablesdr.flex.Radio;

    /**
     *
     * @author walt
     */
    public class TCPClientInitializer extends ChannelInitializer<SocketChannel> {

        private static final StringDecoder DECODER = new StringDecoder();
        private static final StringEncoder ENCODER = new StringEncoder();

        private  final TCPClientHandler clientHandler;

        private final Radio radio;
        public TCPClientInitializer(Radio radio) {
            this.radio = radio;
            clientHandler =  new TCPClientHandler(radio);
           
        }

        @Override
        public void initChannel(SocketChannel ch) {
            ChannelPipeline pipeline = ch.pipeline();


            // Add the text line codec combination first,
            pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
            pipeline.addLast(DECODER);
            pipeline.addLast(ENCODER);

            // and then business logic.
            pipeline.addLast(clientHandler);
        }
       
    }
    When the clientHandler gets invoked, it is presented with a properly formed data object as opposed to byte array.

    This has huge benefit in the Linux world as Netty provides a native direct I/O infrastructure there so data comm is incredibly efficient.
  • IW7DMH, Enzo
    IW7DMH, Enzo Member ✭✭
    edited December 2016
    Again thank you very much for all the advices you gave me.
    I am just in time for Netty coding, while I need more time for build/deployment tools like Gradle.
    I think I'll use the canonical Dao layer and then I'll add an additional dedicated layer for JavaFX GUI.
    I would be glad, also, you you could send me some links of your videos. I had no luck with YouTube search.
    73'

  • Walt - KZ1F
    Walt - KZ1F Member ✭✭
    edited November 2016
    done!

Leave a Comment

Rich Text Editor. To edit a paragraph's style, hit tab to get to the paragraph menu. From there you will be able to pick one style. Nothing defaults to paragraph. An inline formatting menu will show up when you select text. Hit tab to get into that menu. Some elements, such as rich link embeds, images, loading indicators, and error messages may get inserted into the editor. You may navigate to these using the arrow keys inside of the editor and delete them with the delete or backspace key.