I am trying to stop the stream when i close the jframe. i do not want to EXIT_ON_CLOSE beacuse i do not want to exit my application. When i use DISPOSE_ON_CLOSE the frame closes but the audiostream keeps on playing. Is there a way to stop this stream without the use of some external button.(i want to close the stream just by clicking "X" on the jframe).
Thank you for help.
public class MediaPlayer {
private JFrame ourFrame = new JFrame();
private EmbeddedMediaPlayerComponent ourMediaPlayer;
private String mediapath = "";
MediaPlayer(String vlcPath,String mediaURL) {
this.mediapath = mediaURL;
NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), vlcPath);
ourMediaPlayer = new EmbeddedMediaPlayerComponent();
ourFrame.setContentPane(ourMediaPlayer);
ourFrame.setSize(1200, 800);
ourFrame.setVisible(true);
ourFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
public void run() {
ourMediaPlayer.getMediaPlayer().playMedia(mediapath);
}
}
You can handle your stream closing operation on window close, with below:
ouFrame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
// close/stop audio stream here
System.out.println("closed");
}
});
Related
Methods are underlined in red. I have tried to figure out why this is happening, but I keep running into cannot resolve method. I have the methods in the main TextoToSpeechExample1 class and am invoking the methods in my gui class.
class TextToSpeechExample1 {
public static void main(String args[]) throws IOException, EngineException, AudioException, InterruptedException {
static void start(){
// code to be executed
String fileName = "/Users/stevenshivayka/Documents/kjv.txt";
Path path = Paths.get(fileName);
byte[] bytes = Files.readAllBytes(path);
List<String> allLines = Files.readAllLines(path, StandardCharsets.UTF_8);
//setting properties as Kevin Dictionary
System.setProperty("freetts.voices", "com.sun.speech.freetts.en.us" + ".cmu_us_kal.KevinVoiceDirectory");
//registering speech engine
Central.registerEngineCentral("com.sun.speech.freetts" + ".jsapi.FreeTTSEngineCentral");
//create a Synthesizer that generates voice
Synthesizer synthesizer = Central.createSynthesizer(new SynthesizerModeDesc(Locale.US));
//allocates a synthesizer
synthesizer.allocate();
//resume a Synthesizer
synthesizer.resume();
//speak the specified text until the QUEUE become empty
synthesizer.speakPlainText(allLines.toString(), null);
synthesizer.waitEngineState(Synthesizer.QUEUE_EMPTY);
//deallocating the Synthesizer
synthesizer.deallocate();
}
public static void pause(){
Synthesizer synthesizer = Central.createSynthesizer(new SynthesizerModeDesc(Locale.US));
synthesizer.allocate();
synthesizer.resume();
synthesizer.deallocate();
synthesizer.pause();
}
}
}
class gui {
public static void main(String args[]) {
JFrame frame = new JFrame("Babbel Audio Application");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setLayout(new FlowLayout());
JButton button = new JButton("Start Audio");
frame.add(button); // Adds Button to content pane of frame
frame.setVisible(true);
JButton button2 = new JButton("Pause Audio");
frame.add(button2);
frame.setVisible(true);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//your actions
TextToSpeechExample1.start();
}
});
button2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//your actions
pause();
}
});
}
}
`
I expected the methods to be invoked. Please if you can review this and see what I am doing wrong I would greatly appreciate it. This is a project I am working on myself.
This isn't a good question for StackOverflow but anyway...
As far as I can see it, you implemented the two methodes start and pause in the main methode but you need to implement them outside of it.
Try this:
class TextToSpeechExample1 {
public static void main(String args[]) throws IOException, EngineException, AudioException, InterruptedException {}
static void start(){
// code to be executed
String fileName = "/Users/stevenshivayka/Documents/kjv.txt";
Path path = Paths.get(fileName);
byte[] bytes = Files.readAllBytes(path);
List<String> allLines = Files.readAllLines(path, StandardCharsets.UTF_8);
//setting properties as Kevin Dictionary
System.setProperty("freetts.voices", "com.sun.speech.freetts.en.us" + ".cmu_us_kal.KevinVoiceDirectory");
//registering speech engine
Central.registerEngineCentral("com.sun.speech.freetts" + ".jsapi.FreeTTSEngineCentral");
//create a Synthesizer that generates voice
Synthesizer synthesizer = Central.createSynthesizer(new SynthesizerModeDesc(Locale.US));
//allocates a synthesizer
synthesizer.allocate();
//resume a Synthesizer
synthesizer.resume();
//speak the specified text until the QUEUE become empty
synthesizer.speakPlainText(allLines.toString(), null);
synthesizer.waitEngineState(Synthesizer.QUEUE_EMPTY);
//deallocating the Synthesizer
synthesizer.deallocate();
}
public static void pause(){
Synthesizer synthesizer = Central.createSynthesizer(new SynthesizerModeDesc(Locale.US));
synthesizer.allocate();
synthesizer.resume();
synthesizer.deallocate();
synthesizer.pause();
}
}
class gui {
public static void main(String args[]) {
JFrame frame = new JFrame("Babbel Audio Application");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setLayout(new FlowLayout());
JButton button = new JButton("Start Audio");
frame.add(button); // Adds Button to content pane of frame
frame.setVisible(true);
JButton button2 = new JButton("Pause Audio");
frame.add(button2);
frame.setVisible(true);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//your actions
TextToSpeechExample1.start();
}
});
button2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//your actions
TextToSpeechExample1.pause();
}
});
}
}
Quickly looking over your code, a few things jump out:
You're attempting to declare a new function static void start() inside your public static void main(..) function. This isn't allowed in java. You should be declaring your functions inside the class itself:
class TextToSpeechExample1 {
static void start() { ...your code here... }
public static void pause() { ... your code here ... }
public static void main (String args[]) { ... your code here ...}
}
You should probably also look into the basics of access modifiers/specifiers in Java.
You won't be able to call a private function, or a function declared in a private class from another class, for example.
The void start and pause are inside the main void of your TextoToSpeechExample1 class, remove them from inside the main void and it will not give an error.
I have this webcam program that runs in a JFrame. Whenever I close the frame, it prints out "Closed" like it's supposed to, but my IDE says that is still running. Why is this and how do I fix it? I am not running any threads anywhere in the program. This doesn't have anything to do with the default close operation as I have tested for that already.
public class Webcam extends JPanel {
private static BufferedImage image;
public Webcam() {
super();
}
public static void main(String args[]) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
JFrame frame = new JFrame("Webcam");
Webcam panel = new Webcam();
// Initialize JPanel parameters
//frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(1080, 720);
frame.setContentPane(panel);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter()
{
#Override
public void windowClosing(WindowEvent e)
{
System.out.println("Closed");
e.getWindow().dispose();
System.exit(0);
}
});
Mat currentImage = new Mat();
VideoCapture capture = new VideoCapture(0);
if(capture.isOpened()) {
// Infinitely update the images
while(true) {
// VideoCapture returns current Mat
capture.read(currentImage);
if(!currentImage.empty()) {
frame.setSize(currentImage.width() + 40, currentImage.height() + 60);
image = panel.matrixToBuffer(currentImage);
// Update the panel
panel.repaint();
}
else {
System.out.println("Error: no frame captured");
frame.dispose();
System.exit(0);
break;
}
}
}
return;
}
Okay, while I appreciate all of the helpful comments, the issue was that the VideoCapture had an internal thread running, and adding capture.release() to my listener fixed it.
I am trying to get my application to display a simple loading dialog so users know when a time intensive process is working and when its done. I just want it to show a simple "loading" using a gif I downloaded. I already tried using only text and it still doesn't work.
I can get the dialog to display (and disappear) when I want it to, the problem is nothing will display on the dialog (or frame) after displaying it. I have tried many different techniques and all give the same result, a blank dialog.
I finally made a separate class to display the dialog (with loading gif) and I got it to display properly (by itself), but when I run it from my main application, it shows a black dialog again. I tested putting the gif into a JOptionPane and it works, the problem with that is I can't close it at will.
Here is my custom code.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import java.util.logging.*;
import org.w3c.dom.*;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import javax.swing.filechooser.FileNameExtensionFilter;
public class Loader implements Runnable {
final JFileChooser jfc = new JFileChooser();
static JFrame frame = new JFrame();
Frame parentUI = new Frame();
JDialog dialog = new JDialog();
JLabel lbl_filename = new JLabel();
JLabel lbl_path = new JLabel();
static Loader load = new Loader(null);
public static void main(String[] args) throws InterruptedException, InvocationTargetException {
load.run();
frame.setVisible(true);
}
public Loader(Frame parent) {
init();
parentUI = parent;
}
#Override
public void run() {
createDialog(parentUI);
}
public final void init() {
JButton btn = new JButton("Open");
frame.setTitle("Loader Test");
frame.setSize(500, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setLayout(new FlowLayout());
btn.addActionListener(new Action1());
frame.add(btn);
frame.add(lbl_filename);
frame.add(lbl_path);
}
class Action1 implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
openFile();
load.Close();
}
}
private void createDialog(final Frame parent) {
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setTitle("Loader");
URL url = this.getClass().getResource("/resource/loader.gif");
Icon icon = new ImageIcon(url);
JLabel label = new JLabel(icon);
dialog.add(label);
dialog.pack();
dialog.setLocationRelativeTo(parent);
}
public void Show(Boolean visible) {
this.run();
dialog.setVisible(visible);
}
public void Close() {
dialog.setVisible(false);
}
private void setJFCFilter(String file, String ext) {
FileNameExtensionFilter filter = new FileNameExtensionFilter(file, ext);
jfc.setFileFilter(filter);
}
private void openFile() {
File default_dir = new File(".");
jfc.setCurrentDirectory(default_dir);
setJFCFilter("Scalable Vector Graphics", "svg");
int returnVal = jfc.showOpenDialog(parentUI);
if (returnVal == JFileChooser.APPROVE_OPTION) {
String path = jfc.getSelectedFile().getAbsolutePath();
String fileName = jfc.getSelectedFile().getName();
lbl_filename.setText(fileName);
lbl_path.setText(path);
load.Show(true);
createDoc(path);
load.Close();
}
}
private void createDoc(String file) {
try {
NodeList svgIDPaths;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);
String xpathIDExp = "//g/#id";
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
XPathExpression expression = xpath.compile(xpathIDExp);
svgIDPaths = (NodeList)expression.evaluate(doc, XPathConstants.NODESET);
} catch (Exception ex) {
Logger.getLogger(Loader.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Edit: Use this file for testing -> svg_test.svg
I have tried calling it like this:
loader.show(true);
And also in its own thread like this:
private void load(final Boolean visible) {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
loader.show(visible);
}
});
t.start();
}
Neither method works and gives me the same result, a blank dialog. I have had this issue in the past, but just gave up and removed it (loading dialog). I have tried it with a progress bar and simple text, nothing seems to work.
Also I tried it in a JOptionPane and it worked, but that's not desirable (I want to close/open when I want not via a button click).
private void load() {
ImageIcon icon = new ImageIcon(MainForm.class.getResource("/resource/loader.gif").getFile());
JOptionPane.showMessageDialog(null, "Loading...", "Loader", JOptionPane.INFORMATION_MESSAGE, icon);
}
I am aware you can't run multiple dialogs on the EDT and have to use a separate thread, but I'm using a separate thread and its not working (it works by itself).
(Also note I have one main application (frame) that is running/opening this second dialog).
Any assistance is appreciated.
You look to have a Swing threading issue where you have long-running code on the event thread messing up drawing of images, and my guess is that the long running code is in your createDoc method. Consider calling that from a background thread, such as from a SwingWorker, and calling close on your load object only after the worker has completed its work. For example something like so:
class Action1 implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
openFile();
// load.Close(); // get rid of this
}
}
// .......
private void openFile() {
// ....
load.Show(true); // load dialog on event thread
new SwingWorker<Void, Void>() {
protected Void doInBackground() throws Exception {
createDoc(path); // call this from background thread
return null;
};
protected void done() {
load.Close(); // only call this once createDoc has completed
// probably should call get() in here to catch all exceptions
};
}.execute();
}
I have a simple JFrame where the user is changing the background color of it using a JPopupMenu. When the user exit the application, I want to save the changes made in the background.
I have tried to handle this with method windowClosing() from WindowAdapter class but when when I launch the application again, I don't see the changes I made earlier. I don't know what the problem is. I will appreciate any help. Here's my code.
/*i have removed unnnecessary codes*/
public class Popupframe extends JFrame{
private JRadioButtonMenuItem[] items;
private final Color[] colorvalues={Color.BLUE,Color.YELLOW,Color.RED};
static Color bgcolor=Color.CYAN;
JRadioButtonMenuItem[] cheek;
public Popupframe() {
super("using popups");
String[] colors = {"Blue","Yellow","Red"};
setBackground(bgcolor);
addMouseListener(new Handler());
}
private class Handler extends MouseAdapter implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
for(int i=0; i<items.length; i++) {
if(event.getSource()==items[i]) {
getContentPane().setBackground(colorvalues[i]);
bgcolor=colorvalues[i];
}
}
}
}
public static void main(String[] args) {
Popupframe frame=new Popupframe();
frame.setSize(width,height);
frame.setDefaultCloseOperation(Popupframe.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
int ok=JOptionPane.showConfirmDialog(frame,"are sure?","close",JOptionPane.WARNING_MESSAGE);
if(ok==JOptionPane.OK_OPTION) {
bgcolor=frame.getContentPane().getBackground();
System.out.println(bgcolor);
System.exit(0);
}
}
});
frame.setVisible(true);
}
You need to save the color code into a file(like settings file or shared preference) before System.exit(0) and read it in the main and set that color code. Then it works fine.
You are not persisting the color. Color is serializable, so you could just save the object in the program root directory. Put this code in your WindowClosing method :
//serialize the Color
try (
OutputStream file = new FileOutputStream("myBgColor.ser");
OutputStream buffer = new BufferedOutputStream(file);
ObjectOutput output = new ObjectOutputStream(buffer);
){
output.writeObject(bgColor);
}
catch(IOException ex){
log.log(Level.SEVERE, "Cannot perform output.", ex);
}
When you reload the application you need to get the color back. In the PopupFrame() constructor, before you call setBackground(color), put in this code here :
//deserialize the Color file
try(
InputStream file = new FileInputStream("myBgColor.ser");
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream (buffer);
){
//deserialize the List
bgColor = (Color)input.readObject();
}
catch(ClassNotFoundException ex){
fLogger.log(Level.SEVERE, "Cannot perform input. Class not found.", ex);
}
That should do the trick.
I am attempting to use a GUI to write out to a text file. I ran into a problem while doing this, and was able to figure out that the WindowEvent is somehow terminating the program early for some reason.
Initially I had outFile.close(); after the WindowEvent line, so the text from the JTextArea wouldn't be transferred to the text file. After switching a few lines of code around, I realized that when trying to automatically close the JFrame with the WindowEvent, none of the code afterwards executed.
How can I fix this problem?
import ...
public class TxtManager {
static Input input;
public static void overwriteCurrentFile() throws IOException {
TxtManager txt = new TxtManager();
input = new Input(txt);
}
public synchronized void sendData() throws IOException {
try {
BufferedWriter outFile = new BufferedWriter(new FileWriter(file1));
String data = input.textArea.getText();
outFile.write(data);
outFile.close();
input.frame.dispatchEvent(new WindowEvent(input.frame,WindowEvent.WINDOW_CLOSING));
// Code from this point on in the try block does not execute.
System.out.println("Finished with the write out..."); // Used for pinpointing the problem
JOptionPane.showMessageDialog(null,"Data in " + TxtManager.file1 + " has been overwritten successfully.");
TxtManager.showData = true;
TxtManager.menu2();
} catch (Exception ex) {
JOptionPane.showMessageDialog(null,"Error: " + ex.getMessage(),"Error",JOptionPane.ERROR_MESSAGE);
}
}
}
class Input extends Thread {
TxtManager txt;
public JTextArea textArea;
public JFrame frame;
private JButton button;
public Input(TxtManager txt) throws IOException {
this.txt = txt;
JOptionPane.showMessageDialog(null,"Enter desired data into the GUI screen.\n" +
"Press the <Done> button once you are finished.");
frame = new JFrame("Prompt");
JPanel panel = new JPanel(new BorderLayout());
frame.add(panel);
JLabel label = new JLabel("Enter desired data.");
panel.add(label,BorderLayout.NORTH);
textArea = new JTextArea(15,80);
panel.add(textArea,BorderLayout.CENTER);
panel.add(new JScrollPane(textArea));
button = new JButton("Done");
panel.add(button,BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
start();
}
public void run() {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
txt.sendData();
} catch (IOException ex) {
JOptionPane.showMessageDialog(null,"Error: " + ex.getMessage(),"Error",JOptionPane.ERROR_MESSAGE);
}
}
});
}
}
I believe your problem stems from this line (assuming input.frame is equivalent to the frame you create here)
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
From the API
EXIT_ON_CLOSE (defined in JFrame): Exit the application using the System exit method. Use this only in applications.
What this all means is that when you throw the WindowClosing event, the frame (rightfully) tries to close itself. This in turn calls the default close operation, which happens to be EXIT_ON_CLOSE, which calls System.exit() right there. This ends your program without executing any more lines of code. What you're probably looking for is WindowConstants.DISPOSE_ON_CLOSE instead of Frame.EXIT_ON_CLOSE, which should close the window and dispose its resources without exiting your program.
Although honestly, it might make more sense to just hide your window via Frame.setVisible(false);.That way if you wanted to reuse the frame in the future, there wouldn't be as much overhead starting it up.
Don't close window during method execution. If you want to hide the window, use setVisible(false) instead. Close it after finishing your method