okay, I have this problem: my audio starts playing correctly, but it wont stop even after "clip.stop()" or "clip.close()" ... do you have any idea what to do to stop it? (i could accept even muting it, I am really desperate)
public class Main {
//audio playing
public static void audio(boolean a) {
try {
File file = new File("textures/Main_theme.wav");
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(file));
if(a == true){
// this loads correctly, but wont stop music
clip.stop();
System.out.println(a);
}
else{
clip.start();
}
} catch (Exception e) {
System.err.println("Put the music.wav file in the sound folder if you want to play background music, only optional!");
}
}
private static String arg;
public static void main(String[] args){
//picture loading ... ignorable now
arg = "textures/ccc.gif";
JFrame f = new JFrame();
JPanel p = new JPanel();
JLabel l = new JLabel();
ImageIcon icon = new ImageIcon(arg);
f.setSize(480, 360);
f.setVisible(true);
l.setIcon(icon);
p.add(l);
f.getContentPane().add(p);
f.setLocationRelativeTo(null);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//calling audio method to play sound (works)
audio(false);
//should stop music and run another class
KeyListener action = new KeyListener()
{
#Override
public void keyPressed(KeyEvent e) {
//trying to stop music
f.dispose();
try {
Menu.menu(args);
Main.audio(true);
} catch (IOException e1) {
//rest of code ... ignorable
e1.printStackTrace();
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
};
f.addKeyListener( action );
}
}
You need to step back for a second and think about what you're doing.
You're creating a Clip and you're playing it. At some point in the future, you create a new Clip and try and stop. What connection does these two Clips have in common? How are they connected? The answer is, they're not. It's quite reasonable to load the same file into to sepearate Clips and play them individually.
Instead, you need to stop the instance of the Clip you started earlier.
Because I'm lazy, I'd start by encapsulating the audio functionality into a simple class.
public class Audio {
private Clip clip;
protected Audio() {
}
public Audio(File source) throws LineUnavailableException, MalformedURLException, IOException, UnsupportedAudioFileException {
this(source.toURI().toURL());
}
public Audio(URL source) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
this(source.openStream());
}
public Audio(InputStream source) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
init(source);
}
protected void init(File source) throws LineUnavailableException, MalformedURLException, IOException, UnsupportedAudioFileException {
init(source.toURI().toURL());
}
protected void init(URL source) throws IOException, LineUnavailableException, UnsupportedAudioFileException {
init(source.openStream());
}
protected void init(InputStream source) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(source));
}
public void setRepeats(boolean repeats) {
clip.loop(repeats ? Clip.LOOP_CONTINUOUSLY : 1);
}
public void reset() {
clip.stop();
clip.setFramePosition(0);
}
public void play() {
clip.start();
}
public void stop() {
clip.stop();
}
public boolean isPlaying() {
return clip.isActive();
}
}
"Why?" you ask, because now I can create subclass which represent specific sounds and load them, without needing to care or remember what the source of the audio is, for example...
public class MainTheme extends Audio {
public MainTheme() throws LineUnavailableException, MalformedURLException, IOException, UnsupportedAudioFileException {
init(getClass().getResource("textures/Main_theme.wav"));
}
}
Now, I can easily create the "main theme" audio whenever I need to without having to care about what the source of it is
This also means I can pass the MainTheme to other parts of the program which expect an instance of Audio and off load the management simply
Then you just need to create an instance of the class and start/stop it as required, for example...
package test;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JButton btn = new JButton("Click");
btn.addActionListener(new ActionListener() {
private Audio audio;
#Override
public void actionPerformed(ActionEvent e) {
try {
if (audio == null) {
audio = new MainTheme();
}
if (audio.isPlaying()) {
audio.stop();
} else {
audio.play();
}
} catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) {
ex.printStackTrace();
}
}
});
add(btn);
}
}
}
Related
I was wondering why the JTextArea prints the same line twice. Im using multithreading and im new to this concept. I was wondering if that's where the issue is. As of looking it over I tried seeing if any run methods were called twice to cause such a thing. There aren't any loops in the code either. The line that says "Prints twice?" in the GameThread class is where the issue starts. Thanks for help.
Main Menu Class
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.Font;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.awt.event.ActionEvent;
public class MainMenu {
private JFrame menu;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainMenu window = new MainMenu();
window.menu.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
* #throws IOException
*/
public MainMenu() throws IOException {
initialize();
}
/**
* Initialize the contents of the frame.
* #throws IOException
*/
private void initialize() throws IOException {
menu = new JFrame();
menu.getContentPane().setBackground(Color.BLACK);
menu.setTitle("Zombie Game");
menu.setBounds(100, 100, 574, 374);
menu.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
menu.getContentPane().setLayout(null);
JButton btnPlay = new JButton("Play");
// button action on click
btnPlay.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
GameScreen enterGame = new GameScreen();
menu.setVisible(false);
enterGame.run();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
JLabel lblNewLabel = new JLabel("Zombie Survival");
lblNewLabel.setFont(new Font("Tahoma", Font.BOLD, 40));
lblNewLabel.setForeground(Color.WHITE);
lblNewLabel.setBounds(118, 34, 381, 73);
menu.getContentPane().add(lblNewLabel);
btnPlay.setBackground(Color.WHITE);
btnPlay.setForeground(Color.RED);
btnPlay.setFont(new Font("Tahoma", Font.BOLD, 17));
btnPlay.setToolTipText("Click to begin.");
btnPlay.setBounds(225, 190, 118, 54);
menu.getContentPane().add(btnPlay);
}
}
Game Board
import java.awt.EventQueue;
import java.io.PrintStream;
import javax.swing.JFrame;
import java.awt.Color;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.JTextArea;
import java.awt.Font;
import javax.swing.JScrollPane;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class GameScreen {
private JFrame gameFrm;
/**
* Launch the application.
*/
public void run() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GameScreen window = new GameScreen();
window.gameFrm.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
* #throws InterruptedException
*/
public GameScreen() throws InterruptedException {
initialize();
}
/**
* Initialize the contents of the frame.
* #throws InterruptedException
*/
private void initialize() throws InterruptedException {
gameFrm = new JFrame();
gameFrm.getContentPane().setBackground(Color.BLACK);
gameFrm.getContentPane().setLayout(null);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10, 478, 718, 134);
gameFrm.getContentPane().add(scrollPane);
JTextArea displayTextArea = new JTextArea();
displayTextArea.setLineWrap(true);
displayTextArea.setWrapStyleWord(true);
displayTextArea.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
}
}
});
scrollPane.setViewportView(displayTextArea);
displayTextArea.setFont(new Font("Monospaced", Font.PLAIN, 18));
displayTextArea.setForeground(Color.WHITE);
displayTextArea.setBackground(Color.BLACK);
PrintStream printStream = new PrintStream(new CustomOutputStream(displayTextArea));
System.setOut(printStream);
JLabel forestPicture = new JLabel("New label");
forestPicture.setIcon(new ImageIcon("C:\\Users\\fstal\\Documents\\Java Programs\\UpdatedZombieGame\\src\\gameForest.jpg"));
forestPicture.setBounds(0, 0, 738, 622);
gameFrm.getContentPane().add(forestPicture);
gameFrm.setBackground(Color.WHITE);
gameFrm.setTitle("Zombie Game");
gameFrm.setBounds(100, 100, 752, 659);
gameFrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Game work
GameThread gThread = new GameThread();
gThread.start();
}
}
Thread Class
public class GameThread extends Thread {
static String [] zombies = {"Zombie", "Fast Zombie", "Big Zombie", "Crawler"};
static String [] bag = {"Assault Rifle", "SMG", "Shotgun", "Sniper"};
static int [] zHealth = {100, 90, 200, 50};
static int [] damage = {90, 80, 100, 200};
static int playerHealth = 50;
public void run() {
try {
System.out.println("Zombies are coming!");
//Thread.sleep(2000);
System.out.println("Prints twice?");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
CustomOutputStream Class for TextArea
import java.io.IOException;
import java.io.OutputStream;
import javax.swing.JTextArea;
public class CustomOutputStream extends OutputStream {
private JTextArea displayTextArea;
CustomOutputStream(JTextArea textArea) {
this.displayTextArea = textArea;
}
#Override
public void write(int b) throws IOException {
// redirects data to the text area
displayTextArea.append(String.valueOf((char)b));
// scrolls the text area to the end of data
displayTextArea.setCaretPosition(displayTextArea.getDocument().getLength());
}
}
You're creating two instance of the GameScreen, so your output get's printed twice
When you perform...
btnPlay.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
GameScreen enterGame = new GameScreen();
menu.setVisible(false);
enterGame.run();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
It calls the GameScreen constructor, which calls initialize()
/**
* Create the application.
*
* #throws InterruptedException
*/
public GameScreen() throws InterruptedException {
initialize();
}
And when you call run, it does it again...
/**
* Launch the application.
*/
public void run() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GameScreen window = new GameScreen();
window.gameFrm.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
You really don't need to do this again in run.
Now that we've discussed that problem, you have a number of other issues.
Firstly, Swing is NOT thread safe and you should never modify the UI (or anything the UI relies on) from outside the context of the Event Dispatching Thread.
See Concurrency in Swing for some more details (and possible solutions)
Second, null layouts are generally a bad idea - it made a mess of your UI on my PC. You should really take the time to learn how to use the various layout managers available in the API - see Laying Out Components Within a Container
I am using ffmpeg java library to convert captured screenshots to video. Video which is generated as output is blurry.
I am using bit rate as 9000, frames per sec as 25 and video size as that of desktop screen size.
Any suggestions on how to solve this issue.
P.S. I cannot use ffmpeg.exe and command line due to certain restrictions and hence I am opting for ffmpeg java library.
Any suggestions on the issue or suggestions on any better approach will be helpful.
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import org.bytedeco.javacpp.avcodec;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.OpenCVFrameConverter;
public class ScreenRecorder{
public static boolean videoComplete=false;
public static String inputImageDir="inputImgFolder"+File.separator;
public static String inputImgExt="png";
public static String outputVideo="recording.mp4";
public static int counter=0;
public static int imgProcessed=0;
public static FFmpegFrameRecorder recorder=null;
public static int videoWidth=1920;
public static int videoHeight=1080;
public static int videoFrameRate=3;
public static int videoQuality=0; // 0 is the max quality
public static int videoBitRate=9000;
public static String videoFormat="mp4";
public static int videoCodec=avcodec.AV_CODEC_ID_MPEG4;
public static Thread t1=null;
public static Thread t2=null;
public static JFrame frame=null;
public static boolean isRegionSelected=false;
public static int c1=0;
public static int c2=0;
public static int c3=0;
public static int c4=0;
public static void main(String[] args) {
try {
if(getRecorder()==null)
{
System.out.println("Cannot make recorder object, Exiting program");
System.exit(0);
}
if(getRobot()==null)
{
System.out.println("Cannot make robot object, Exiting program");
System.exit(0);
}
File scanFolder=new File(inputImageDir);
scanFolder.delete();
scanFolder.mkdirs();
createGUI();
} catch (Exception e) {
System.out.println("Exception in program "+e.getMessage());
}
}
public static void createGUI()
{
frame=new JFrame("Screen Recorder");
JButton b1=new JButton("Select Region for Recording");
JButton b2=new JButton("Start Recording");
JButton b3=new JButton("Stop Recording");
JLabel l1=new JLabel("<html><br/>If you dont select a region then full screen recording <br/> will be made when you click on Start Recording</html>");
l1.setFont (l1.getFont ().deriveFont (20.0f));
b1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
JOptionPane.showMessageDialog(frame, "A new window will open. Use your mouse to select the region you like to record");
new CropRegion().getImage();
} catch (Exception e1) {
// TODO Auto-generated catch block
System.out.println("Issue while trying to call the module to crop region");
e1.printStackTrace();
}
}
});
b2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
counter=0;
startRecording();
}
});
b3.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
stopRecording();
System.out.print("Exiting...");
System.exit(0);
}
});
frame.add(b1);
frame.add(b2);
frame.add(b3);
frame.add(l1);
frame.setLayout(new FlowLayout(0));
frame.setVisible(true);
frame.setSize(1000, 170);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void startRecording()
{
t1=new Thread()
{
public void run() {
try {
takeScreenshot(getRobot());
} catch (Exception e) {
JOptionPane.showMessageDialog(frame, "Cannot make robot object, Exiting program "+e.getMessage());
System.out.println("Cannot make robot object, Exiting program "+e.getMessage());
System.exit(0);
}
}
};
t2=new Thread()
{
public void run() {
prepareVideo();
}
};
t1.start();
t2.start();
System.out.println("Started recording at "+new Date());
}
public static Robot getRobot() throws Exception
{
Robot r=null;
try {
r = new Robot();
return r;
} catch (AWTException e) {
JOptionPane.showMessageDialog(frame, "Issue while initiating Robot object "+e.getMessage());
System.out.println("Issue while initiating Robot object "+e.getMessage());
throw new Exception("Issue while initiating Robot object");
}
}
public static void takeScreenshot(Robot r)
{
Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle rec=new Rectangle(size);
if(isRegionSelected)
{
rec=new Rectangle(c1, c2, c3-c1, c4-c2);
}
while(!videoComplete)
{
counter++;
BufferedImage img = r.createScreenCapture(rec);
try {
ImageIO.write(img, inputImgExt, new File(inputImageDir+counter+"."+inputImgExt));
} catch (IOException e) {
JOptionPane.showMessageDialog(frame, "Got an issue while writing the screenshot to disk "+e.getMessage());
System.out.println("Got an issue while writing the screenshot to disk "+e.getMessage());
counter--;
}
}
}
public static void prepareVideo()
{
File scanFolder=new File(inputImageDir);
while(!videoComplete)
{
File[] inputFiles=scanFolder.listFiles();
try {
getRobot().delay(500);
} catch (Exception e) {
}
//for(int i=0;i<scanFolder.list().length;i++)
for(int i=0;i<inputFiles.length;i++)
{
//imgProcessed++;
addImageToVideo(inputFiles[i].getAbsolutePath());
//String imgToAdd=scanFolder.getAbsolutePath()+File.separator+imgProcessed+"."+inputImgExt;
//addImageToVideo(imgToAdd);
//new File(imgToAdd).delete();
inputFiles[i].delete();
}
}
File[] inputFiles=scanFolder.listFiles();
for(int i=0;i<inputFiles.length;i++)
{
addImageToVideo(inputFiles[i].getAbsolutePath());
inputFiles[i].delete();
}
}
public static FFmpegFrameRecorder getRecorder() throws Exception
{
if(recorder!=null)
{
return recorder;
}
recorder = new FFmpegFrameRecorder(outputVideo,videoWidth,videoHeight);
try
{
recorder.setFrameRate(videoFrameRate);
recorder.setVideoCodec(videoCodec);
recorder.setVideoBitrate(videoBitRate);
recorder.setFormat(videoFormat);
recorder.setVideoQuality(videoQuality); // maximum quality
recorder.start();
}
catch(Exception e)
{
JOptionPane.showMessageDialog(frame, "Exception while starting the recorder object "+e.getMessage());
System.out.println("Exception while starting the recorder object "+e.getMessage());
throw new Exception("Unable to start recorder");
}
return recorder;
}
public static OpenCVFrameConverter.ToIplImage getFrameConverter()
{
OpenCVFrameConverter.ToIplImage grabberConverter = new OpenCVFrameConverter.ToIplImage();
return grabberConverter;
}
public static void addImageToVideo(String imgPath)
{
try {
getRecorder().record(getFrameConverter().convert(cvLoadImage(imgPath)));
} catch (Exception e) {
JOptionPane.showMessageDialog(frame, "Exception while adding image to video "+e.getMessage());
System.out.println("Exception while adding image to video "+e.getMessage());
}
}
public static void stopRecording()
{
try {
videoComplete=true;
System.out.println("Stopping recording at "+new Date());
t1.join();
System.out.println("Screenshot thread complete");
t2.join();
System.out.println("Video maker thread complete");
getRecorder().stop();
System.out.println("Recording has been saved successfully at "+new File(outputVideo).getAbsolutePath());
JOptionPane.showMessageDialog(frame, "Recording has been saved successfully at "+new File(outputVideo).getAbsolutePath());
} catch (Exception e) {
System.out.println("Exception while stopping the recorder "+e.getMessage());
}
}
}
Imagepanel.java
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
class ImagePanel
extends JPanel
{
private Image img;
public ImagePanel(String img)
{
this(new ImageIcon(img).getImage());
}
public ImagePanel(Image img)
{
this.img = img;
Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
setSize(size);
setLayout(null);
}
public void paintComponent(Graphics g)
{
g.drawImage(this.img, 0, 0, null);
}
}
CropRegion.java
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
public class CropRegion implements MouseListener,
MouseMotionListener {
int drag_status = 0;
int c1;
int c2;
int c3;
int c4;
JFrame frame=null;
static int counter=0;
JLabel background=null;
public void getImage() throws AWTException, IOException, InterruptedException {
Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
Robot robot = new Robot();
BufferedImage img = robot.createScreenCapture(new Rectangle(size));
ImagePanel panel = new ImagePanel(img);
frame=new JFrame();
frame.add(panel);
frame.setLocation(0, 0);
frame.setSize(size);
frame.setLayout(new FlowLayout());
frame.setUndecorated(true);
frame.setVisible(true);
frame.addMouseListener(this);
frame.addMouseMotionListener(this);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
public void draggedScreen() throws Exception {
ScreenRecorder.c1=c1;
ScreenRecorder.c2=c2;
ScreenRecorder.c3=c3;
ScreenRecorder.c4=c4;
ScreenRecorder.isRegionSelected=true;
JOptionPane.showMessageDialog(frame, "Region Selected.Please click on Start Recording button to record the selected region.");
frame.dispose();
}
public void mouseClicked(MouseEvent arg0) {
}
public void mouseEntered(MouseEvent arg0) {
}
public void mouseExited(MouseEvent arg0) {
}
public void mousePressed(MouseEvent arg0) {
paint();
this.c1 = arg0.getX();
this.c2 = arg0.getY();
}
public void mouseReleased(MouseEvent arg0) {
paint();
if (this.drag_status == 1) {
this.c3 = arg0.getX();
this.c4 = arg0.getY();
try {
draggedScreen();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void mouseDragged(MouseEvent arg0) {
paint();
this.drag_status = 1;
this.c3 = arg0.getX();
this.c4 = arg0.getY();
}
public void mouseMoved(MouseEvent arg0) {
}
public void paint() {
Graphics g = frame.getGraphics();
frame.repaint();
int w = this.c1 - this.c3;
int h = this.c2 - this.c4;
w *= -1;
h *= -1;
if (w < 0) {
w *= -1;
}
g.drawRect(this.c1, this.c2, w, h);
}
}
I'm having some trouble getting an image drawn in java. There are no console errors and it prints 'drawing'. I believe I am loading the image wrong but I can't figure out the right way. If someone could tell me the correct way that would be great.
package platformer;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.util.List;
import java.util.ArrayList;
import javax.swing.Timer;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.awt.Image;
public class test2 extends JPanel implements KeyListener, ActionListener {
int Width = 1000;
int Height = 600;
private static Image offScreenBuffer;// needed for double buffering graphics
private Graphics offScreenGraphics;// needed for double buffering graphics
private BufferedImage[] img = new BufferedImage[1];
public test2() {
}
public void paint(Graphics g) {
super.paint(g);
g.drawImage(img[0],0,0,null);
}
public void timer1() {
int delay = 30; // milliseconds
new Timer(delay, this).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void actionPerformed(ActionEvent evt) {
}
public static void main(String args[]) throws InterruptedException, Exception {
test2 test2 = new test2();
JFrame frame = new JFrame("platformer");
frame.setSize(test2.Width, test2.Height);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.green);
frame.add(test2);
frame.setResizable(false);
frame.addKeyListener(test2);
test2.init();
test2.timer1();
// What to do after the program starts
while (true) {
test2.repaint();
}
}
public void init() {
try {
URL url = new URL("platform.png");
img[0] = ImageIO.read(url);
} catch (IOException e) {
}
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
}
Swing has an infinite loop that does event handling for you. You don't need the while(true) loop. You should call frame.setVisible(true) after all of your UI is configured. I mean that it should be the last thing in main(). Also, you should do this on the UI thread with
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.setVisible(true);
}
});
So main() should look like
public static void main(String args[]) throws InterruptedException, Exception {
test2 test2 = new test2();
JFrame frame = new JFrame("platformer");
frame.setSize(test2.Width, test2.Height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.green);
frame.add(test2);
frame.setResizable(false);
frame.addKeyListener(test2);
test2.init();
test2.timer1();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.setVisible(true);
}
});
}
However, the main problem is the try... catch in init() which ignores exceptions. You should never leave a catch empty. At the very least you should print a stacktrace. Better yet, add the appropriate exceptions to the methods throws clause like this:
public void init() throws IOException {
URL url = new URL("platform.png");
img[0] = ImageIO.read(url);
}
Note if a problem occurs, you will know about it immediately.
I have a question about my code, first of all little pre information about what it is going...
A Graphic Design friend of mine, has an exhibition/project from her University to influence the ppl with acoustic drugs (the topic of the exhibition is drugs..)
She wanted to have an interface, where a user can push a button and listen to an acoustic drug. further the user should have the opportunity, to mix up the sounds like kokain and heroin and stop either all by repushing the buttons each or just one button for stopping one title.
My code has follow problems. at the time i debug the code, my second listen button is not shown, u have to push the left bot of the window that the button is visible, and u can start one title and stop it, but if u play two sounds in same time, u can stop one, if u stop the second one its shown that its stopped but its actually not.
I would be happy if somebody could help me in my case.
Here the code:
package test;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JButton;
import javax.swing.JFrame;
public class c extends JFrame {
String lsd="/Users/shaggy/Desktop/Lsd.wav";
JButton btnPlaySoundLSD=new JButton("Listen");
Clip clip = null;
String koka ="/Users/shaggy/Desktop/Kokain.wav";
JButton btnPlaySoundKokain=new JButton("Listen");
public c(){
btnPlaySoundLSD.setBounds(0, 0, 250, 240);
btnPlaySoundLSD.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
JButton b=(JButton)arg0.getSource();
// play the sound clip
if(b.getText().equals("Listen")){
b.setText("Stop");
btnPlaySoundCLickLSD();
} else if(btnPlaySoundLSD.getText().equals("Stop")) {
b.setText("Listen");
clip.stop();
}
} catch (LineUnavailableException | IOException
| UnsupportedAudioFileException e) {
e.printStackTrace();
}
}
});
setSize(500, 500);
getContentPane().setLayout(null);
getContentPane().add(btnPlaySoundLSD);
setVisible(true);
btnPlaySoundKokain.setBounds(0, 238, 250, 240);
btnPlaySoundKokain.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg1) {
try {
JButton b=(JButton)arg1.getSource();
// play the sound clip
if(b.getText().equals("Listen")){
b.setText("Stop");
btnPlaySoundCLickKokain();
} else if(btnPlaySoundKokain.getText().equals("Stop")) {
b.setText("Listen");
clip.stop();
}
} catch (LineUnavailableException | IOException
| UnsupportedAudioFileException e) {
e.printStackTrace();
}
}
});
setSize(500, 500);
getContentPane().setLayout(null);
getContentPane().add(btnPlaySoundKokain);
setVisible(true);
}
private void btnPlaySoundCLickKokain() throws LineUnavailableException, IOException, UnsupportedAudioFileException{
File soundFile = new File(koka);
AudioInputStream sound = AudioSystem.getAudioInputStream(soundFile);
DataLine.Info info = new DataLine.Info(Clip.class, sound.getFormat());
clip = (Clip) AudioSystem.getLine(info);
clip.open(sound);
clip.addLineListener(new LineListener() {
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP) {
System.out.println("stop");
event.getLine().close();
}
}
});
clip.start();
}
private void btnPlaySoundCLickLSD() throws LineUnavailableException, IOException, UnsupportedAudioFileException{
File soundFile = new File(lsd);
AudioInputStream sound = AudioSystem.getAudioInputStream(soundFile);
DataLine.Info info = new DataLine.Info(Clip.class, sound.getFormat());
clip = (Clip) AudioSystem.getLine(info);
clip.open(sound);
clip.addLineListener(new LineListener() {
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP) {
System.out.println("stop");
event.getLine().close();
}
}
});
clip.start();
}
public static void main(String[] args) {
c cc=new c();
}
}
I'm making a game which is using sound and images. The weirdest thing is happening. When I load sound, my image won't appear. However, when I don't load my sound, my image does appear. Here is my code:
package com.gbp.chucknorris;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Title extends JPanel implements Runnable {
private static final long serialVersionUID = 1L;
public Thread thread;
private BufferedImage logo;
private Clip clip, titleClip;
public Title() {
super();
loadSound();
loadImages();
bind();
setBackground(Color.WHITE);
}
private void loadSound() {
File f = new File("res/sounds/title.wav");
AudioInputStream stream = null;
try {
stream = AudioSystem.getAudioInputStream(f);
} catch (UnsupportedAudioFileException | IOException e) {
e.printStackTrace();
}
DataLine.Info info = new DataLine.Info(Clip.class, stream.getFormat());
try {
clip = (Clip) AudioSystem.getLine(info);
} catch (LineUnavailableException e) {
e.printStackTrace();
}
try {
clip.open(stream);
} catch (LineUnavailableException | IOException e) {
e.printStackTrace();
}
File title = new File("res/sounds/theme.wav");
AudioInputStream titleStream = null;
try {
titleStream = AudioSystem.getAudioInputStream(title);
} catch (UnsupportedAudioFileException | IOException e) {
e.printStackTrace();
}
DataLine.Info titleInfo = new DataLine.Info(Clip.class, titleStream.getFormat());
try {
titleClip = (Clip) AudioSystem.getLine(titleInfo);
titleClip.open(titleStream);
} catch (LineUnavailableException | IOException e) {
e.printStackTrace();
}
titleClip.loop(Clip.LOOP_CONTINUOUSLY);
}
private void bind() {
InputMap im = getInputMap();
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke("DOWN"), "down");
am.put("down", new AbstractAction() {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
}
});
}
private void loadImages() {
try {
logo = ImageIO.read(new File("res/pics/MenuPanel.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
while (true) {
repaint();
}
}
public void addNotify() {
super.addNotify();
thread = new Thread(this);
thread.start();
}
public void paint(Graphics g) {
super.paint(g);
g.drawImage(logo, 0, 0, null);
}
}
Thanks in advance!
You need to learn to use background threading such as a SwingWorker so as not to tie up the event thread, the EDT, when loading and playing sounds. You can read up on how to use this here: Lesson: Concurrency in Swing.
Edit: I wouldn't recommend doing this:
#Override
public void run() {
while (true) {
repaint();
}
}