How can i add background music to my program? - java

I am attempting to add background music to my program but when i specify the path to the audio file i get the error message. How else can I specify this(this is going to be sent to another person). So the path cannot be on my system, it must be located in the JAR as well.
package main;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
javax.sound.sampled.AudioSystem;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
public class Main extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main frame = new Main();
frame.setVisible(true);
PlaySound();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public static void PlaySound() {
InputStream in;
try {
in = new FileInputStream(new File("/audio/Happy_Happy_Birthday.wav"));
AudioStream audios = new AudioStream(in);
AudioPlayer.player.start(audios);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
public Main() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 717, 508);
contentPane = new JPanel() {
/**
*
*/
private static final long serialVersionUID = 1L;
public void paintComponent(Graphics g) {
Image img = Toolkit.getDefaultToolkit().getImage(
Main.class.getResource("/images/happy_birthday.jpg"));
g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
}
};
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
}
}

Load the clip using an URL rather than a File. By the time of deployment, those resources will likely become an embedded-resource. That being the case, the resource must be accessed by URL instead of File. See the info page for the tag, for a way to form an URL.
Play the sound using a javax.sound.sampled.Clip (as opposed to undocumented classes in the sun.audio package). See the Java Sound info. page for working source.

InputStream in;
try {
in = new FileInputStream(new File("Jock_Jams_-_Are_You_Ready_For_This.wav"));
AudioStream audios = new AudioStream(in);
AudioPlayer.player.start(audios);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
I use this outside of my while loop and it works as long as if you don't mind it not being able to stop.

Related

Java Jar File Graphics are Not Showing Up

I have created a simple graphics program(LIKE VERY SIMPLE). It worked all fine when I ran the class file, but when I simply created a JAR file (executable), nothing ran. Could I please get a bit of help with this. Thanks. I compiled it normally in the cmd, with the command "jar -cf Graphics.jar Graphics.class Render.class icon.png"
Graphics.java:
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Graphics extends JFrame{
/**
*
*/
private static final long serialVersionUID = 1L;
public Graphics() {
JFrame window = new JFrame();
window.setDefaultCloseOperation(EXIT_ON_CLOSE);
window.setSize(500, 500);
window.add(new Render());
window.setTitle("Example of Graphics in JAVA");
ClassLoader ldr = this.getClass().getClassLoader();
URL imager = ldr.getResource("./icon.png");
String path = imager.getPath();
File f = new File(path);
File imageicon = f;
Image im = null;
try {
im = ImageIO.read(imageicon);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
window.setIconImage(im);
window.setVisible(true);
}
public static void main(String[] args) {
Graphics g = new Graphics();
}
}
Render.java:
import javax.swing.*;
import java.awt.Color;
import java.awt.Graphics;
public class Render extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
public void paintComponent(Graphics graph) {
super.paintComponent(graph);
this.setBackground(Color.blue);
graph.setColor(Color.red);
graph.fillArc(0,0, 400, 400, 0, 360);
}
}
There is also an image called "icon.png"
Change the File:
im = ImageIO.read(imageicon);
Back to the URL:
im = ImageIO.read(imager);
As an embedded resource (in the Jar) it is no longer a File.

Strange error with Drag and Drop in AWT in Java

Allright here is the error: java.awt.dnd.InvalidDnDOperationException: The operation requested cannot be performed by the DnD system since it is not in the appropriate state. The error appears when I drop some File inside the program (grabbed from the desktop). I am using Ubuntu 16.04 with Nautilus.
import javax.swing.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.*;
import java.io.File;
import java.util.List;
class UI extends JFrame {
List<File> droppedFiles;
UI(){
super("My Program");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLayout(null);
this.setVisible(true);
this.setResizable(true);
this.setSize(800, 500);
this.setExtendedState(MAXIMIZED_BOTH);
JTextField dropArea = getDropArea();
this.add(dropArea);
}
private JTextField getDropArea(){
JTextField dropArea = new JTextField("Drop file here");
dropArea.setBounds(50, 50, 200, 200);
dropArea.setDropTarget(createNewDropTarget(dropArea));
return dropArea;
}
private DropTarget createNewDropTarget(JTextField dropArea) {
DropTarget dt = new DropTarget(){
#Override
public synchronized void drop(DropTargetDropEvent dtde) {
super.drop(dtde);
try {
dtde.acceptDrop(DnDConstants.ACTION_COPY);
droppedFiles = (List<File>) dtde.getTransferable().
getTransferData(DataFlavor.javaFileListFlavor);
dropArea.setText(droppedFiles.get(0).getName());
}catch (Exception e){
e.printStackTrace();
}
}
};
return dt;
}
}
The Error appears on the line where droppedFiles is initialized. (in the try catch block).
In a way you set up DropTarget there is no need to call super.drop(dtde);. This is actually the reason for the exception. Here is the implementation of DropTarget.drop():
public synchronized void drop(DropTargetDropEvent dtde) {
clearAutoscroll();
if (dtListener != null && active)
dtListener.drop(dtde);
else { // we should'nt get here ...
dtde.rejectDrop();
}
}
Since you are not initializing DropTarget with a listener the drop is rejected, and the subsequent call getTransferable() fails with InvalidDnDOperationException. If you comment super.drop(dtde); the problem should go away. A cleaner alternative would be to create a listener and pass it to DropTarget. Here is a small example:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;
import java.io.File;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class DDTest extends JPanel {
public DDTest() {
setLayout(new BorderLayout());
final JTextField dropArea = new JTextField("Drop file here");
add(dropArea);
new DropTarget(dropArea, new DropTargetAdapter() {
#Override
public void drop(DropTargetDropEvent dtde) {
try {
dtde.acceptDrop(DnDConstants.ACTION_COPY);
List<File> droppedFiles = (List<File>) dtde
.getTransferable().getTransferData(
DataFlavor.javaFileListFlavor);
dropArea.setText(droppedFiles.get(0).getName());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
private static void createAndShowGUI() {
final JFrame frame = new JFrame("DDTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DDTest());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
PS:
Note that using absolute layout can be complex and usually can be avoided. See A Visual Guide to Layout Managers for some ideas.

How do I run something as an applet and application?

I'm working on this project and I need it run as an applet and an application. This is what I have but I stuck on where to go because I can't find anything on the internet. Are there any resources or does someone have some quick advice to give me?
public class Project extends JApplet {
public void init() {
try {
URL pictureURL = new URL(getDocumentBase(), "sample.jpg");
myPicture = ImageIO.read(pictureURL);
myIcon = new ImageIcon(myPicture);
myLabel = new JLabel(myIcon);
} catch (Exception e) {
e.printStackTrace();
}
add(label, BorderLayout.NORTH);
add(bio);
add(bio, BorderLayout.CENTER);
pane.add(play);
getContentPane().add(pane, BorderLayout.SOUTH);
play.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try{
FileInputStream FIS = new FileInputStream("sample.mp3");
player = new Player (FIS);
player.play();
} catch (Exception e1) {
e1.printStackTrace();
}}});
}
public static void main(String args[]) {
JFrame frame = new JFrame("");
frame.getContentPane().add();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.show();
}
private JPanel pane = new JPanel();
private TextArea bio = new TextArea("Bio");
private JButton play = new JButton("Play");
private Image myPicture;
private ImageIcon icon;
private JLabel label;
private Player player;
}
When trying to run something as an applet and as an application, there are several caveats.
Applets have a certain life cycle that must be obeyed. One can add the applet to the content pane of the JFrame and manually call init(), but in general, if the applet expects its start() or stop() methods to be called, things may become tricky...
More importantly: The way how resources are handled is different between applets and applications.
Handling files in applets (e.g. with a FileInputStream) may have security implications, and will plainly not work in some cases - e.g. when the applet is embedded into a website. (Also see What Applets Can and Cannot Do).
Conversely, when running this as an application, calling getDocumentBase() does not make sense. There simply is no "document base" for an application.
Nevertheless, it is possible to write a program that can be shown as an Applet or as an Application. The main difference will then be whether the main JPanel is placed into a JApplet or into a JFrame, and how data is read.
One approach for reading data that works for applets as well as for applications is via getClass().getResourceAsStream("file.txt"), given that the respective file is in the class path.
I hesitated a while, whether I should post an example, targeting the main question, or whether I should modify your code so that it works. I'll do both:
Here is an example that can be executed as an Applet or as an Application. It will read and display a "sample.jpg". (This file is currently basically expected to be "in the same directory as the .class-file". More details about resource handling, classpaths and stream handling are beyond the scope of this answer)
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class AppletOrApplicationExample extends JApplet
{
#Override
public void init()
{
add(new AppletOrApplicationMainComponent());
}
public static void main(String args[])
{
JFrame frame = new JFrame("");
frame.getContentPane().add(new AppletOrApplicationMainComponent());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
class AppletOrApplicationMainComponent extends JPanel
{
public AppletOrApplicationMainComponent()
{
super(new BorderLayout());
InputStream stream = getClass().getResourceAsStream("sample.jpg");
if (stream == null)
{
add(new JLabel("Resource not found"), BorderLayout.NORTH);
}
else
{
try
{
BufferedImage image = ImageIO.read(stream);
add(new JLabel(new ImageIcon(image)), BorderLayout.NORTH);
}
catch (IOException e1)
{
add(new JLabel("Could not load image"), BorderLayout.NORTH);
}
}
JTextArea textArea = new JTextArea("Text...");
add(textArea, BorderLayout.CENTER);
JButton button = new JButton("Button");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
doSomething();
}
});
add(button, BorderLayout.SOUTH);
}
private void doSomething()
{
System.out.println("Button was clicked");
}
}
And here is something that is still a bit closer to your original code. However, I'd strongly recommend to factor out the actual application logic as far as possible. For example, your main GUI component should then not be the applet itself, but a JPanel. Resources should not be read directly via FileInputStreams or URLs from the document base, but only from InputStreams. This is basically the code that you posted, with the fewest modifications that are necessary to get it running as an applet or an application:
import java.awt.BorderLayout;
import java.awt.Image;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Module5Assignment2 extends JApplet
{
public void init()
{
try
{
InputStream stream = getClass().getResourceAsStream("sample.jpg");
if (stream == null)
{
System.out.println("Resource not found");
}
else
{
myPicture = ImageIO.read(stream);
icon = new ImageIcon(myPicture);
label = new JLabel(icon);
add(label, BorderLayout.NORTH);
}
}
catch (Exception e)
{
e.printStackTrace();
}
add(bio);
add(bio, BorderLayout.CENTER);
pane.add(play);
getContentPane().add(pane, BorderLayout.SOUTH);
play.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try
{
FileInputStream FIS = new FileInputStream("sample.mp3");
// player = new Player (FIS);
// player.play();
}
catch (Exception e1)
{
e1.printStackTrace();
}
}
});
}
public static void main(String args[])
{
JFrame frame = new JFrame("");
// ******PRETTY SURE I NEED TO ADD SOMETHING HERE*************
Module5Assignment2 contents = new Module5Assignment2();
frame.getContentPane().add(contents);
contents.init();
// *************************************************************
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.show();
}
private JPanel pane = new JPanel();
private TextArea bio = new TextArea(
"This is the bio of Christian Sprague; he doesn't like typing things.");
private JButton play = new JButton("Play");
private Image myPicture;
private ImageIcon icon;
private JLabel label;
// private Player player;
}

How to attach opengl display to a JFrame and dispose of it properly?

How can i attach the OpenGl display to a JFrame and so that when i close the JFrame is destroys the display? Here is my code so far:
package test.core;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import static org.lwjgl.opengl.GL11.*;
public class Main {
private static CreateCanvas canvas;
private static CreateFrame frame;
private static int width = 800;
private static int height = 600;
public static void main(String[] args) throws InterruptedException {
startFrames();
startDisplay();
}
public static void cleanUp() {
Display.destroy();
}
private static void startDisplay() {
try
{
Display.setParent(canvas);
Display.create();
}catch(LWJGLException ex)
{
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static void startFrames()
{
Runnable r = new Runnable(){
#Override
public void run(){
frame = new CreateFrame();
JButton button = new JButton("BUTTON");
canvas = new CreateCanvas();
JPanel panel = frame.panel;
panel.add(canvas);
panel.add(button);
frame.add(panel);
canvas.setSize(300, 300);
frame.setSize(width, height);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
WindowListener listen = new WindowAdapter(){
#Override
public void windowClosing(WindowEvent we){
int result = JOptionPane.showConfirmDialog(frame, "Do you want to quit the Application?");
if(result == JOptionPane.OK_OPTION){
frame.setVisible(false);
cleanUp();
frame.dispose();
}
}
};
frame.addWindowListener(listen);
frame.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
I had the opengl display attach to the JFrame before i did the runnable. But after adding the runnable the display now shows up the same size as my screen size. I have tried rearranging the
canvas.setSize();
and the
frame.setSize();
but nothing changes the opengl display is still the same size and when i try to close the JFrame first rather then close the display first i get this error:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: From thread Thread[AWT-EventQueue-0,6,main]: Thread[main,5,main] already has the context current
which points me to my
Display.destroy();
which im guessing is telling me that i am not properly disposing the display? Can anyone help me attach the opengl display to the JFrame and fix the error above?
It appears that you started the Display in the "main" thread (which gives the main thread the current OpenGL context), but you're trying to destroy the display from a different thread, which in this case is the Event Dispatch Thread (EDT).
However, only one thread can have the current OpenGL context at a given time.
Although it is possible to change which thread has the current context, I don't think that's what you want to do here.
What we want to do here then is to destroy the display on the same thread that we created it on (the thread with the current OpenGL context). An approach I've seen is to use the Canvas's addNotify() and removeNotify() methods, which are run on the EDT, to set a flag that is checked on the OpenGL thread to determine when to destroy the display.
Also, the question mentioned problems about setting the size of the display. Your JFrame display size and Display size were not being set to what you desired because of how setSize() and LayoutManager's work. Please see the Java tutorials and documentation for details. In the following example, I have use one approach to address this issue.
So here is an example trying to stay close to the intent of the code posted in the question:
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
public class LWJGLTester {
private volatile boolean isRunning = false;
/*
* The question asker seemed to desire that the JFrame be 800x600 and
* that the Display be 300x300. Regardless of the desired sizes,
* I think the important thing is to set the Canvas and Display to the same sizes.
*/
private int frameWidth = 800;
private int frameHeight = 600;
private int displayWidth = 300;
private int displayHeight = 300;
private Thread glThread;
public static void main(String[] args) {
new LWJGLTester().runTester();
}
private void runTester() {
final JFrame frame = new JFrame("LWJGL in Swing");
frame.setSize(frameWidth, frameHeight);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent we){
int result = JOptionPane.showConfirmDialog(frame, "Do you want to quit the Application?");
if(result == JOptionPane.OK_OPTION){
frame.setVisible(false);
frame.dispose(); //canvas's removeNotify() will be called
}
}
});
JPanel mainPanel = new JPanel(new BorderLayout());
JButton button = new JButton("BUTTON");
JPanel buttonPanel = new JPanel();
buttonPanel.add(button);
mainPanel.add(buttonPanel, BorderLayout.NORTH);
Canvas canvas = new Canvas() {
#Override
public void addNotify() {
super.addNotify();
startGL();
}
#Override
public void removeNotify() {
stopGL();
super.removeNotify();
}
};
canvas.setPreferredSize(new Dimension(displayWidth, displayHeight));
canvas.setIgnoreRepaint(true);
try {
Display.setParent(canvas);
} catch (LWJGLException e) {
//handle exception
e.printStackTrace();
}
JPanel canvasPanel = new JPanel();
canvasPanel.add(canvas);
mainPanel.add(canvasPanel, BorderLayout.SOUTH);
frame.getContentPane().add(mainPanel);
//frame.pack();
frame.setVisible(true);
}
private void startGL() {
glThread = new Thread(new Runnable() {
#Override
public void run() {
isRunning = true;
try {
Display.setDisplayMode(new DisplayMode(displayWidth, displayHeight));
Display.create();
} catch (LWJGLException e) {
//handle exception
e.printStackTrace();
}
// init OpenGL here
while(isRunning) {
// render OpenGL here
Display.update();
}
Display.destroy();
}
}, "LWJGL Thread");
glThread.start();
}
private void stopGL() {
isRunning = false;
try {
glThread.join();
} catch (InterruptedException e) {
//handle exception
e.printStackTrace();
}
}
}
Note: This is example was tested using lwjgl version 2.9.1, since that seemed to be the latest version available at the time the question was originally posted.

image as component issue

I am trying to do my final project for my java class. I am attempting to take a .png picture and use it as a component that I can add to my JFrame. However, when I try to do this it throws an exception and does what is in the catch statement. I do not understand why it would do this. I have the .png file in the same folder as my .java files.
package InventoryApp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
/**
*
* #author Curtis
*/
public class FinalProject extends DFrame
{
//main method
public static void main(String[] args)
{
start();
}
//building splash screen
public static void start()
{ DFrame splashFrame = new DFrame();
try
{
BufferedImage myPicture = ImageIO.read(new File("logo.png"));
JLabel picLabel = new JLabel(new ImageIcon( myPicture ));
splashFrame.add(picLabel);
}
catch(IOException g)
{
JLabel error = new JLabel("Picture Could Not Be Found");
splashFrame.add(error);
}
JButton create = new JButton("Click to Create Item List");
JButton view = new JButton("Click to View Item List");
splashFrame.add(create);
splashFrame.add(view);
}
}
When you create a File object with no path specified, it assumes the directory the program was launched from, not the directory the current class file is in. You probably want to instead use FinalProject.class.getResource():
BufferedImage myPicture = ImageIO.read(FinalProject.class.getResource("logo.png"));

Categories

Resources