How do you close a JOGL/NEWT GLWindow completely? - jogl

I have an incredibly dumb little sample, probably ripped straight from a tutorial, every time it runs it generates warnings on exit. I'm curious what I'm missing. Any ideas, links, things I'm forgetting?
Here's the main window setup...
package com.emarcotte;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.FPSAnimator;
public class Main2 {
public static void main(String[] args) {
final RenderLoop loop = new RenderLoop();
GLProfile glp = GLProfile.get(new String[] { GLProfile.GL3 }, true);
GLCapabilities caps = new GLCapabilities(glp);
GLWindow window = GLWindow.create(caps);
window.setSize(300, 300);
window.setVisible(true);
window.setTitle("NEWT Window Test");
window.addGLEventListener(loop);
window.setAnimator(new FPSAnimator(window, 120));
window.getAnimator().start();
window.addWindowListener(new WindowAdapter() {
#Override public void windowResized(WindowEvent we) {
loop.setHeight(window.getHeight());
loop.setWidth(window.getWidth());
}
});
window.addKeyListener(new KeyAdapter() {
#Override public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
window.getAnimator().stop();
}
}
});
}
}
here are the warnings:
X11Util.Display: Shutdown (JVM shutdown: true, open (no close attempt): 2/2, reusable (open, marked uncloseable): 0, pending (open in creation order): 2)
X11Util: Open X11 Display Connections: 2
X11Util: Open[0]: NamedX11Display[:0.0, 0x7f214c0012b0, refCount 1, unCloseable false]
X11Util: Open[1]: NamedX11Display[:0.0, 0x7f214c017390, refCount 1, unCloseable false]

Call GLWindow.destroy() to close your NEWT GLWindow: http://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/newt/opengl/GLWindow.html#destroy%28%29

Related

Restarting and pausing and resuming clip hangs the gui of music player, while pressing pause and play resumes playing from stopping point

This program is a music player that allows user to pick a .wav file, play, pause, resume, and restart a the music file from a clip object and audioinput stream. The audio input stream loads a file that is determined by user via FileChooser. The program can play, pause, and resume by selecting a file, pressing play, pause, then play again, but does not play using the restart method or the resume method invoked via the respective buttons. Instead, the program hangs until the X button is clicked. I think it has something to do with the resetaudiostream method, but I am unsure what. Maybe something to do with ending the old clip and creating a new clip instance. Please review the logic and let me know what is making it hang and how that could be remedied.
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javax.sound.sampled.*;
import java.io.File;
import java.io.IOException;
public class Main extends Application {
static File musicfile;
static Long currentFrame;
static Clip clip;
static String status = "play";
static AudioInputStream audioInputStream;
static String filePath;
public void SimpleAudioPlayer()
throws UnsupportedAudioFileException,
IOException, LineUnavailableException
{
// create AudioInputStream object
audioInputStream =
AudioSystem.getAudioInputStream(new File(filePath).getAbsoluteFile());
// create clip reference
clip = AudioSystem.getClip();
// open audioInputStream to the clip
clip.open(audioInputStream);
clip.loop(Clip.LOOP_CONTINUOUSLY);
}
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Music Player");
GridPane gp = new GridPane();
Button selectFile = new Button("Select File");
GridPane.setConstraints(selectFile, 0,0);
selectFile.setOnAction(event->{
FileChooser filechooser = new FileChooser();
// create AudioInputStream object
try {
musicfile = filechooser.showOpenDialog(null);
audioInputStream = AudioSystem.getAudioInputStream(musicfile);
clip = AudioSystem.getClip();
// open audioInputStream to the clip
clip.open(audioInputStream);
}catch(IOException | UnsupportedAudioFileException | LineUnavailableException e){
e.printStackTrace();
}
});
Button play = new Button("Play");
GridPane.setConstraints(play, 1,0);
play.setOnAction(event->{
if(status == "play") {
clip.loop(Clip.LOOP_CONTINUOUSLY);
}
play();
});
Button pause = new Button("Pause");
GridPane.setConstraints(pause, 2,0);
pause.setOnAction(event -> pause());
Button restart = new Button("Restart");
GridPane.setConstraints(restart, 0,1);
restart.setOnAction(event -> {
try{
restart();
}
catch(IOException | UnsupportedAudioFileException | LineUnavailableException e){
e.printStackTrace();}
});
Button resume = new Button("Resume");
GridPane.setConstraints(resume, 1,1);
resume.setOnAction(event -> {
try {
resumeAudio();
}catch(IOException | LineUnavailableException | UnsupportedAudioFileException e){
e.printStackTrace();
}
});
gp.getChildren().addAll(play,selectFile, pause, restart, resume);
primaryStage.setScene(new Scene(gp, 300, 275));
primaryStage.show();
}
public void play()
{
//start the clip
clip.start();
status = "play";
}
// Method to pause the audio
public void pause()
{
if (status.equals("paused"))
{
System.out.println("audio is already paused");
return;
}
currentFrame =
clip.getMicrosecondPosition();
clip.stop();
status = "paused";
}
// Method to resume the audio
public void resumeAudio() throws UnsupportedAudioFileException,
IOException, LineUnavailableException
{
if (status.equals("play"))
{
System.out.println("Audio is already "+
"being played");
return;
}
clip.close();
resetAudioStream();
clip.setMicrosecondPosition(currentFrame);
status = "play";
play();
}
// Method to restart the audio
public void restart() throws IOException, LineUnavailableException,
UnsupportedAudioFileException
{
clip.stop();
clip.close();
resetAudioStream();
currentFrame = 0L;
clip.setMicrosecondPosition(0);
status = "play";
play();
}
// Method to stop the audio
public void stop() throws UnsupportedAudioFileException,
IOException, LineUnavailableException
{
currentFrame = 0L;
clip.stop();
clip.close();
}
// Method to jump over a specific part
public void jump(long c) throws UnsupportedAudioFileException, IOException,
LineUnavailableException
{
if (c > 0 && c < clip.getMicrosecondLength())
{
clip.stop();
clip.close();
resetAudioStream();
currentFrame = c;
clip.setMicrosecondPosition(c);
this.play();
}
}
// Method to reset audio stream
public void resetAudioStream() throws UnsupportedAudioFileException, IOException,
LineUnavailableException
{
audioInputStream = AudioSystem.getAudioInputStream(musicfile);
clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.loop(Clip.LOOP_CONTINUOUSLY);
}
public static void main(String[] args) {
launch(args);
}
}
It is quiet simple to get the required functionality with a MediaPlayer:
import java.net.URI;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaPlayer.Status;
import javafx.stage.Stage;
import javafx.util.Duration;
/*
* If you get "cannot access class com.sun.glass.utils.NativeLibLoader" exception you may need to
* add a VM argument: --add-modules javafx.controls,javafx.media as explained here:
* https://stackoverflow.com/questions/53237287/module-error-when-running-javafx-media-application
*/
public class Main extends Application {
private MediaPlayer player;
private static final long JUMP_BY = 5000;//millis
#Override
public void start(Stage primaryStage) throws Exception{
URI uri = new URI("https://www.soundhelix.com/examples/mp3/SoundHelix-Song-5.mp3");
Media media = new Media(uri.toString());
//OR Media media = new Media("https://www.soundhelix.com/examples/mp3/SoundHelix-Song-5.mp3");
player = new MediaPlayer(media);
player.setOnError(() -> System.out.println(media.getError().toString()));
GridPane gp = new GridPane();
gp.setHgap(10);
Button play = new Button("Play");
GridPane.setConstraints(play, 0,0);
play.setOnAction(event-> playAudio());
Button pause = new Button("Pause");
GridPane.setConstraints(pause, 1,0);
pause.setOnAction(event -> pauseAudio());
Button resume = new Button("Resume");
GridPane.setConstraints(resume, 2,0);
resume.setOnAction(event -> resumeAudio());
Button stop = new Button("Stop");
GridPane.setConstraints(stop, 3,0);
stop.setOnAction(event -> stopAudio());
Button restart = new Button("Restart");
GridPane.setConstraints(restart, 4,0);
restart.setOnAction(event -> restartAudio());
Button jump = new Button("Jump >");
GridPane.setConstraints(jump, 5,0);
jump.setOnAction(event -> jump(JUMP_BY));
Label time = new Label();
GridPane.setConstraints(time, 6,0);
time.textProperty().bind( player.currentTimeProperty().asString("%.4s") );
gp.getChildren().addAll(play, pause, resume, stop, restart, jump, time);
primaryStage.setScene(new Scene(gp, 400, 45));
primaryStage.show();
}
//play audio
public void playAudio()
{
player.play();
}
//pause audio
public void pauseAudio()
{
if (player.getStatus().equals(Status.PAUSED))
{
System.out.println("audio is already paused");
return;
}
player.pause();
}
//resume audio
public void resumeAudio()
{
if (player.getStatus().equals(Status.PLAYING))
{
System.out.println("Audio is already playing");
return;
}
playAudio();
}
//restart audio
public void restartAudio()
{
player.seek(Duration.ZERO);
playAudio();
}
// stop audio
public void stopAudio()
{
player.stop();
}
//jump by c millis
public void jump(long c)
{
player.seek(player.getCurrentTime().add(Duration.millis(c)));
}
public static void main(String[] args) {
launch(args);
}
}

HERE SDK TrafficUpdater.request(Geocordinate, TrafficUpdater.Listener) not returning traffic results

I have been working on integrating several HERE features into an app I am working on. Right now I am trying to add traffic data to the application. The default auto-updates aren't quite frequent enough for me (~1 min), so I am trying to use the TrafficUpdater.request(GeoCoordinate, TrafficUpdater.Listener) to manually retrieve traffic information every 5 seconds or so. The problem is, although the request line executes, the listener is never called, and I never receive any traffic updates. Below is my activity:
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.here.android.mpa.common.GeoCoordinate;
import com.here.android.mpa.common.GeoPosition;
import com.here.android.mpa.common.MapSettings;
import com.here.android.mpa.common.OnEngineInitListener;
import com.here.android.mpa.common.PositioningManager;
import com.here.android.mpa.guidance.TrafficUpdater;
import com.here.android.mpa.mapping.Map;
import com.here.android.mpa.mapping.MapFragment;
import com.here.android.mpa.mapping.MapTrafficLayer;
import com.here.android.mpa.mapping.MapView;
import com.here.android.mpa.mapping.TrafficEvent;
import java.io.File;
import java.lang.ref.WeakReference;
public class MainActivity extends AppCompatActivity {
private Map map;
private MapFragment mapFragment;
private TrafficUpdater trafficUpdater;
private PositioningManager.OnPositionChangedListener onPositionChangedListener = new PositioningManager.OnPositionChangedListener() {
#Override
public void onPositionUpdated(PositioningManager.LocationMethod locationMethod, GeoPosition geoPosition, boolean b) {
onLocationUpdate(geoPosition);
}
#Override
public void onPositionFixChanged(PositioningManager.LocationMethod locationMethod, PositioningManager.LocationStatus locationStatus) {
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MapSettings.setIsolatedDiskCacheRootPath(
getApplicationContext().getExternalFilesDir(null) + File.separator + ".here-maps",
"MAP_SERVICE");
mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
mapFragment.init(new OnEngineInitListener() {
#Override
public void onEngineInitializationCompleted(Error error) {
if (error == Error.NONE) {
map = mapFragment.getMap();
initTracker();
}
}
});
}
private void initTracker() {
trafficUpdater = TrafficUpdater.getInstance();
trafficUpdater.enableUpdate(false);
PositioningManager positioningManager = PositioningManager.getInstance();
positioningManager.addListener(new WeakReference<PositioningManager.OnPositionChangedListener>(onPositionChangedListener));
mapFragment.getPositionIndicator().setVisible(true);
positioningManager.start(PositioningManager.LocationMethod.GPS_NETWORK);
}
private boolean isTimerRunning = false;
CountDownTimer trafficTimer = new CountDownTimer(5000,5000) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
isTimerRunning = false;
getTrafficInfo();
}
};
private GeoPosition lastGeoPosition;
private void onLocationUpdate(GeoPosition geoPosition) {
map.setCenter(geoPosition.getCoordinate(), Map.Animation.NONE);
Log.i("____MAINACTIVITY", "location update");
lastGeoPosition = geoPosition;
if(!isTimerRunning) {
trafficTimer.cancel();
trafficTimer.start();
isTimerRunning = true;
}
}
private TrafficUpdater.Listener trafficListener = new TrafficUpdater.Listener() {
#Override
public void onStatusChanged(TrafficUpdater.RequestState requestState) {
Log.i("____MAINACTIVITY", requestState.name());
}
};
private void getTrafficInfo() {
if(lastGeoPosition != null) {
TrafficUpdater.RequestInfo requestInfo = trafficUpdater.request(lastGeoPosition.getCoordinate(), trafficListener);
Log.i("___MAINACTIVITY", requestInfo.getError().name());
}
}
}
I have tried several things to remedy this issue. First, I have checked all of my app permissions and project dashboard on the developer portal to ensure everything is setup properly, and it is. I was providing the listener as an anonymous method in the line we execute the request, and that did not work. I moved the listener to be a private member variable of the activity, and provided it that way, but it still isn't working. I've checked the RequestInfo returned by the method, and it always indicates an error code of NONE, so it seems as though no errors are occurring. Lastly, I set my updater frequency to once every 1.5 seconds (well above the default value), and I still receive nothing. Does anyone know a solution to this problem? I feel as though it's something simple that I'm missing. Updates from the Positioning Manager are coming through just fine, and the app is talking to our server with no problems, so I don't think it's a connectivity issue.
The traffic feed does provide updates only in a one minute time frame. To force the application to request this in a higher frequency won't provide fresher data. I would recommend to keep the default auto-updates.

When does the JavaFX Thread paint to the display?

I've noticed a Platform.runLater() doesn't update the stage/screen immediately after running, so I'm guessing the painting is happening elsewhere or on another queued event. I'm curious as to when or how the actual painting or rendering to the screen is queued or signaled, after the runnable completes.
The following code will print 1.begin, 1.end, 2.begin, 2.end, 3.begin, 3.end to the console, but the label never shows 1, though the second runLater() waits.
package main;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.concurrent.CountDownLatch;
public class SmallRunLater extends Application {
SimpleStringProperty labelValue = new SimpleStringProperty("0");
#Override
public void start(Stage stage) throws InterruptedException {
Scene scene = new Scene(new Group());
stage.setWidth(550);
stage.setHeight(550);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
Label label = new Label();
label.textProperty().bind(labelValue);
Button startBtn = new Button("Start");
vbox.getChildren().addAll(startBtn, label);
startBtn.setOnAction((action) -> {
try {
Task task = new Task<Void>() {
#Override
protected Void call() throws Exception {
SmallWork work = new SmallWork();
work.doWork(labelValue);
return null;
}
};
new Thread(task).start();
} catch (Exception e) {
e.printStackTrace();
}
});
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
class SmallWork {
public void doWork(SimpleStringProperty labelValue) throws InterruptedException {
Platform.runLater(() -> {
System.out.println("1.begin");
labelValue.set("1");
System.out.println("1.end");
});
runNow(() -> {
System.out.println("2.begin");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
labelValue.set("2");
System.out.println("2.end");
});
Platform.runLater(() -> {
System.out.println("3.begin");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
labelValue.set("3");
System.out.println("3.end");
});
}
public static void runNow(Runnable r){
final CountDownLatch doneLatch = new CountDownLatch(1);
Platform.runLater(() -> {
try {
r.run();
} catch (Exception e) {
e.printStackTrace();
} finally {
doneLatch.countDown();
}
});
try {
doneLatch.await();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Yes, you are right, Platform.runLater() (as implied by the name) doesn't run right away and just pushes the Runnable to the internal queue. There is an internal render tick deep down. The Runnable objects will be executed in the update tick just before render. The fact that label never shows "1" simply coincides with the fact that your runNow() gets called immediately, in the same tick, so the two Runnable objects get pushed to same queue and executed in the same tick within JavaFX internal loop. Hence, the following happens:
label set to 1
internal thread set to sleep. This actually freezes the application if you noticed, since the rendering thread is now sleeping
label set to 2
render tick happens, so we get to see "2"
...
I have tried running the code above and sometimes I can see 1, which means the two Runnable objects were pushed in different ticks. Something like that:
label set to 1
render tick
...

samsung gear live audio encoding

I'm currently working on an Android Wear app, and I'm looking toward audio recording. I've followed the tutorial on the Android developper website, and it works well on my Nexus 7, but not on the Samsung Gear Live I have for testing. The application just goes crashing all the time.
Digging a bit into the problem, I might have figured out that it was a problem with 2 parameters for the recorder to work: either the OutputFormat, or the AudioEncoder. I tried pairing and trying all the OutputFormat and AudioEncoder available, but without any luck.
So here's my question: did someone encounter the same problem? And if so, did you find the right combination of Format/Encoder?
I don't paste my code as it's exactly the same as in the documentation. Here is the link if you want to have a look: http://developer.android.com/guide/topics/media/audio-capture.html
Thank you in advance for your answers and your time :)
The root problem is that you cannot use MediaRecorder, even though the Android audio capture example does, but instead you need to use the AudioRecord class.
Also, I'd recommend streaming the raw data back to your phone to assemble it into an audio file as that is very thorny on a wearable.
For more, see this answer for more.
I have included a sample below that I got working.
import android.app.Activity;
import android.content.Intent;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.support.wearable.view.WatchViewStub;
import android.util.Log;
import android.widget.TextView;
import android.view.View;
import java.util.List;
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getName();
private static final int SPEECH_REQUEST_CODE = 1;
private static final int RECORDER_SAMPLERATE = 44100;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private TextView mTextView;
private AudioRecord recorder;
private int bufferSize = 0;
private Thread recordingThread = null;
private volatile boolean isRecording;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.v(TAG, "Creating MainActivity");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
#Override
public void onLayoutInflated(WatchViewStub stub) {
mTextView = (TextView) stub.findViewById(R.id.text);
}
});
bufferSize =
AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,
RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING);
}
public void handleRecordButtonClick(View view) {
startAudioCapture();
}
public void handleStopButtonClick(View view) {
stopAudioCapture();
}
private void startAudioCapture() {
Log.v(TAG, "Starting audio capture");
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING, bufferSize);
if (recorder.getState() == AudioRecord.STATE_INITIALIZED) {
recorder.startRecording();
isRecording = true;
Log.v(TAG, "Successfully started recording");
recordingThread = new Thread(new Runnable() {
#Override
public void run() {
processRawAudioData();
}
}, "AudioRecorder Thread");
recordingThread.start();
} else {
Log.v(TAG, "Failed to started recording");
}
}
private void stopAudioCapture() {
Log.v(TAG, "Stop audio capture");
recorder.stop();
isRecording = false;
recorder.release();
}
private void processRawAudioData() {
byte data[] = new byte[bufferSize];
int read = 0;
while(isRecording) {
read = recorder.read(data, 0, bufferSize);
if(AudioRecord.ERROR_INVALID_OPERATION != read) {
Log.v(TAG, "Successfully read " + data.length + " bytes of audio");
}
}
}
}

importing error with import javax.imageio.ImageIO;

I am new to Java and are trying to display an image. I got code on the net but when trying it I get an error with the importing of " import javax.imageio.ImageIO;" The error message reads "javax.imageio.ImageIO" is either a misplace package name or a non-existing entity.
I have seen this on many samples but it does not work with me.
Is there any advice
mport java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Showmap extends Panel
{
BufferedImage img;
public Showmap ()
{
try
{
image = ImageIO.read (new File ("KNP.jpg"));
}
/*
catch (IOException e)
{
BufferedImage image;
public ShowImage() {
try {
System.out.println("Enter image name\n");
BufferedReader bf=new BufferedReader(new
InputStreamReader(System.in));
String imageName=bf.readLine();
File input = new File(imageName);
image = ImageIO.read(input);
}*/
catch (IOException e)
{
System.out.println ("Error:" + e.getMessage ());
}
}
public void paint (Graphics g)
{
g.drawImage (image, 0, 0, null);
}
static public void main (String args []) throws
Exception
{
JFrame frame = new JFrame ("Display image");
Panel panel = new Showmap ();
frame.getContentPane ().add (panel);
frame.setSize (500, 500);
frame.setVisible (true);
}
}
Thanks
Ivan
In your Project select:
Right Click on "JRE System Libary"
Select Properties
On Execution Enviroment select "J2SE-1.5(jre8)" or later; you should use the latest version of jre8
I was programming with "Ready to Program" and tried many options with out success. When I copied the same code to "JCreator" and run it fro there it was working fine. Seems "import javax.imageio.ImageIO;" is not working with "Ready to Program".

Resources