Win a copy of Five Lines of Code this week in the OO, Patterns, UML and Refactoring forum!

Phil Freihofner

Ranch Hand
+ Follow
since Sep 01, 2010
Working part-time UCSF Med Ctr as database programmer (MS Access).
Learning Java by doing.
Composer & Oboist with SF Composers Chamber Orchestra (sfcco.org)
Albany CA
Cows and Likes
Cows
Total received
4
In last 30 days
0
Total given
0
Likes
Total received
5
Received in last 30 days
0
Total given
11
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Phil Freihofner

I took a look at the API for Class.getResource() from Java 6, and it seems the same rules were in use then as they are now. The description refers to "." being changed to "/".  So maybe "../res" becomes "///res"? But the Eclipse IDE instead handles the "../" in the standard HTML way?

Of course, the compiler doesn't know if the address being specified is going to be called from in a file system context or a jar context. But maybe the Eclipse IDE should enforce that conversion rather than allowing the more lenient "file system" rules to apply, if that is what is happening?

I'm thinking it must be a false memory on my part that I had used "../" with jars in the past.

Relative addressing should be safe for code packed and run as a jar, I would think.
1 month ago
The problem goes away if I move my resources to a subfolder and no longer use ".." as part of the address.

I thought we could use ".." for relative addressing?

Was this at one time possible?
1 month ago
It's been years since I've had trouble with the getResource method, and the code below has been working for a couple of years. But for some unknown reason the code started returning nulls.

What has changed?
Previously, to compile for distribution, I would copy source to a directory and compile and use jlink via the CLI, using Java 11, due to not figuring out how to make a proper Jar with a modular program from within Eclipse. That version works fine. (And, the source, in Eclipse, runs fine.)

Yesterday, I started a new project in Eclipse and set it to use Java 8. Then I copied the source code from the Java 11 version into the Java 8 project. This code also runs fine in Eclipse. Then I exported the Java 8 code to a .jar and tried running it, but got an IOException due to a null URL.

Here is a code fragment. Some diagnostics were added for posting here at CodeRanch.



The idea of getting the various urls came from another coderanch post from 4 years ago. Following is the output from running in Eclipse.


Following is the output from my Windows Command Prompt. I was careful about running the code with the exact same Java version that is used in Eclipse for that project.



I get this output from both a Windows 10 and an Ubuntu 18.04 desktop (two different computers). I looked at the code in JEditorPane(line 415), and the value of the URL is null which throws the IOException. The code "textArea.setPage(ntroURL);" is AboutPanel's line 40 cited in the stack trace.

This isn't a case of the getResource command failing because it cannot find a resource because the path is incorrect, as far as I can tell. The relative path of "." (when assigning helpUrl) should eliminate that idea, yes?

Any thoughts on how to proceed?
1 month ago
Yes! I'm also researching the possibility of going the route of jetty/java/freemarker/webaudioAPI. That should work for some of what I've done and want to do. But the real-time work, e.g., a virtual theremin, and some other tools that are based on real time response, I don't know yet. I need to learn more, including how the computational work of the program is divided between the server and the client. Also, whether one can feed raw data into a WebAudio output similar to the way one can feed data directly to a SourceDataLine for output with javax.sound.sampled.

Back to Chromebooks, though, even better than the GalliumOS, I've learned that Crostini has become standard with Chrome OS 69, and it supports Debian Linux. I just installed a Debian Java 11 and Jetty on a Ubuntu-server system, so it's pretty certain that Java 11 should work on Chromebook that is enabled with Crostini. The question remains, though, on how "scary" enabling Linux will be to school district IT departments, and whether doing so disrupts other programs that the units are intended to run.  
11 months ago
Looks like installing GalliumOS enables the install of either Java 8 or Java 11, and that it is an OpenJDK version (good!). That should allow the creation of a JLINK-created jre for a self-contained Java application.

The program would need the GalliumOS running on the Chromebook in order to run.

So the main practical hurdle is more non-technical: whether a school teacher (or IT department for a school that purchases the Chromebooks) is willing to install GalliumOS on multiple Chromebooks.
11 months ago
Yes, thanks, I've been looking at the articles. I'm trying to ballpark "commercial viability," so that entails ease-of-install and -use for the user base (elementary school kids and teachers).

Maybe it is the way my brain works--I tend to read a lot more ambiguity into text than other people. (Part of why I love Java is it's relative lack of ambiguity, it's tendency to explicit and clear at the cost of a little verbosity.)

Things that to me are not answered:

Are "extra steps" required of the user in order to run a Java program? From the articles, it seems that the we are dealing with the need to do one or more of the following:

> run via "Developer mode"
> have dual boot ChrUbuntu installed
or
> have Crouton installed

Also, I see references to Java 8 but none to module-based Javas. A self-contained program with the entire JRE embedded runs, what, 300+MB? With JLINK, I am able to package downloads in the vicinity of 18MB that unpack to around 75-80 MB.

One article mentioned the ability to boot ChrUbuntu from a thumb drive. Selling programs with a thumb drive would be a plausible business plan (not necessarily a good one, but at least worth considering). But not if the user also has to be in developer mode to boot from the thumb drive.

It seems that schools are increasingly making use of Chromebooks, and so, Chromebooks are becoming an important platform for educational software.

(Alternate plan to be considered to reach this market: write GUI in HTML/CSS/JS with FreeMarker link to the Java program, run a Jetty or Apache server, make the programs .war files. But that will require researching if WebAudio can perform in a manner comparable to a javax.sound.sampled.SourceDataLine.)
11 months ago
I have been developing a library and code base in Java pertaining to audio (relying on javax.sound.sampled, but I've previously made a wrapper that allows audio output on Android). I was just speaking with some school teachers who thinks some of the musical programs I made would be interesting to her students. She has been budgeted with one Chromebook per student. I'm wondering what is required to get my applications running on Chromebook.

Based on very cursory research, it appears that running a Java application on a Chromebook is no easy feat. I have had success with using jlink to make self-contained applications that run on Windows (64-bit) and MacOSX. Is there a process for creating a runnable program, written in Java, for the Chromebook? I don't mind going through a few elaborate hoops, but the resulting program would have to be easy for the end user to install in order to make this worthwhile.

Is this a possibility?
Has Google designed their system to exclude the running of Java?
11 months ago
Thank you for testing and replying.

I think the problem is particular to this Dell Laptop. Or maybe its touchpad.
I just tried to do a quick letter type and touchpad click in Notepad, and got exactly the same result.
The click was completely ignored unless I first waited a little over a second.

However, when using a mouse instead of the touchpad, the click responds immediately, no matter how quickly done after the key press.

Also, the JavaFX code I listed works with a mouse, and only exhibits the problem with the touchpad.

I was wrong to use the terms mouse and touch pad as if they were equivalent in my original post. Bad assumption on my part.

Well, it's good to know this isn't a JavaFX coding problem. But it is still kind of messed up. I'm going to have to rethink some aspects of the GUI I had in mind. Can't be requiring people who use a touchscreen laptop to attach a mouse just for my program.
1 year ago
In the following example, if one moves the mouse over the red rectangle in the application and presses the mouse, "mouse pressed" messages are sent to the console.

On my system (Dell Laptop, Windows 10, OpenJKD 11, OpenJFX 11), if I press and release a key (e.g., the letter "r") and then click the mouse, the event does not appear to reach either the filter or the node unless a certain amount of time has first elapsed. I'm not sure of the duration, but if one clicks the mouse within 1/2 second of releasing the key, nothing. If one clicks after waiting for 2 seconds to elapse, then the event is captured.

During this time interval, mouse movements ARE being captured, as is shown by the console displaying "mouse moved" messages. There is no interference to mouse movement events caused by pressing a key.

I have tried (as can be see in the code) using an event filter, and made sure the node was focus-traverseable in case it was some sort of focus issue. In another example (not shown) I created a key-event handler and explicitly request focus for the "playpad" after hitting the letter "r", and this did not help.

Does anyone know why there is this time interval where mouse-pressed events are not being captured? Any thoughts on how to avoid this delay?

In the larger application where this issue showed up, I was using the "r" key to start capturing mouse state (position, pressed/not pressed) while the mouse is over the pad. But it is "blind" to mouse presses at the start, as described.



1 year ago
The two theGreatNarratorReader function calls are going to be executed immediately one after the other.

Maybe instead of two calls, you can put your text into a String array, and write code to step through this array? Then, there would only be the one function call.


3 years ago
I wrote an alternative to javax.sound.sampled.Clip, for the handling of sound cues in games. The license is BSD-based, the source code is viewable. To use, just add three classes to your project: AudioCue, AudioCueListener (an interface), and AudioCueInstanceEvent (used with the Listener). The API can be examined here.

This class will handle most* of the functionality that Clip provides, but with a couple useful additions:
  • concurrent playback of cues,
  • real-time fading for volume, panning and pitch, at the independent playback instance level.

  • Output is from an accessible internal float[] array via a javax.sound.sampled.SourceDataLine. Aspects like the audio playback thread priority and the internal buffer size used by the SourceDataLine are optionally configurable. The fader controls are built in, they do not make use of javax.sound.sampled.Control.

    *An important limitation, however, is that I only implemented one format so far: 44100 fps, 16-bit, stereo, little-endian (aka "CD Quality").

    I'm posting here at JavaRanch in part because I'm hoping for code review. I've had some great experiences here as a student (via the CattleDrive) and have found the feedback of excellent quality in terms of paying attention to best practices and design principles. I've made efforts to conform as best as I could to both the Javadocs API recommendations and to those of Joshua Bloch, and am wondering how code reviewers here would assess my efforts, in both the coding and the JavaDocs. Bloch says to expect that there will be things found that will need to change in the API after it is subjected to use--so, I will be appreciative of feedback and advice.

    I notice that JavaRanch now has a "blatant advertising" tag for posts. Seems like it would be appropriate here. Is there something I need to do to add that tag? I don't see anything obvious, and am assuming this is something that moderators will do.

    Additional discussion of the class and supporting downloads can be found here, including source code examples and jars. This example jar illustrates the real-time fader controls. This example jar illustrates how a single cue, (a single frog croak), might be used to build soundscape elements (a pond with many frogs). (The size of these jars comes mostly from the media content, and source is included.)

    I hope JavaRanch game programmers find this class useful for their games!

    3 years ago
    I agree with the advice to make things more event driven. But I think the util.Timer is usually a better bet for games than the Swing.Timer. It is true that you need to be more careful with interacting with Swing components, but this can often be handled by posting code on the EDT directly when necessary. Too much activity on the EDT really slows down performance--it quickly becomes a significant bottleneck.

    In "Killer Game Programming" there are some test cases with the game loop timing being provided via a util.Timer vs a Swing.Timer, and the util.Timer ended up with much better performance, pretty much identical in performance to the fastest game loop structure that the book described and preferred.

    Even easier to code, though, is the AnimationTimer in JavaFX! It runs at 60fps as a default.

    Instead of BufferedImages, you would be using WritableImages. There is no need for either repaints or paint() methods or dealing Graphics2D and things like opacity are a simple property setting. There is a tutorial over at JavaGaming.org if you want a quick intro to JavaFX game loops. I've started converting a game I starting with Java2D to JavaFX and am really pleased with how much easier and cleaner the JavaFX code is. And, it integrates well with functional programming constructs that have been added in Java 8.

    3 years ago
    Overlooked. Thanks for the link!

    Why is it so far down the list? Maybe put it next to the Swing button? GUI stuff should go together?
    3 years ago
    I may have found my own answer. The API for Application has the following quote:

    Threading

    JavaFX creates an application thread for running the application start method, processing input events, and running animation timelines. Creation of JavaFX Scene and Stage objects as well as modification of scene graph operations to live objects (those objects already attached to a scene) must be done on the JavaFX application thread.  



    If I understand the above correctly, the code where I alter opacities via the AnimationTimer is by definition already on the JavaFX application thread.

    This would also explain why the Particle Generator code I linked also runs without any noticeable problems.

    So, I think I am good. I will leave this thread "unresolved" for a while to allow others to comment/confirm or counter the solution to the question, as I am not 100% confident I have this right.
    3 years ago
    The API for Node clearly states that one should not modify a live Node outside of the JavaFX Application Thread:

    Node objects may be constructed and modified on any thread as long they are not yet attached to a Scene. An application must attach nodes to a Scene, and modify nodes that are already attached to a Scene, on the JavaFX Application Thread.



    I came across this rule via a closely related forum question. Is this rule overly conservative? I've not managed to find any discussion on the matter. It seems to me there are cases where one can modify a property of a Node subclass with no repercussions. One example that seems perfectly fine is to modify the opacity value of a Group--I've been doing this, with no problems, from an AnimationTimer thread.

    The project where I am doing it is described on this blog post. The jar file for the post is here.

    My AnimationTime is simple:

    I refer to a Group: TitleBlocks that is a live Node, in an update() method with the code line:


    The above is working fine, so far.

    Here's an example of a way to schedule commands on the FX Application thread:

    I worry that for more involved graphics, the FX Application thread could become overwhelmed if I every instance of an opacity value change (and other changes, such as icon and sprite movements) all have to be scheduled this way.

    My guess is that for certain types of properties, the code in the JavaFX Application Thread that handles the Nodes only does a read of the current value, and if the property value is changed after the fact, this is simply ignored until the next iteration. But without having this practice sanctioned (such as with the fades I employ on my game-to-be), I'm nervous about leaving my code as is.

    Following is another example to consider (the one that inspired me to try writing a game with JavaFX). This particle generator application modifies 20,000 objects at the rate of 60 fps. Each object is a subclass of Node when you trace the parentage. the modifications are being done on the AnimationTimer thread, not the FX Application thread. Why doesn't this program exhibit any problems? Doesn't it violate the rule about only modifying nodes via the FX Application thread? Or am I misreading the code?

    Blogpost (describes code, has video and link to code):
    http://wecode4fun.blogspot.co.at/2015/07/particles.html

    Code (so you can jump to it directly, if desired):
    https://gist.github.com/Roland09/71ef45f14d0ec2a353e6
    3 years ago