I have a desktop application using vclj and swing. I have a frame (JFrame component) that contains a video created using vclj (instance of VideoPanel). The problem is that I need to update the video to show in this jframe in runtime. When I try to do it I don't get that it works. Instead, the component of video vclj appears in black color without showing any video.
Code of video component:
public class VideoPanel extends JPanel {
private EmbeddedMediaPlayerComponent mymediaPlayer;
private EmbeddedMediaPlayer mediaPlayer;
private Canvas canvas;
public VideoPanel() {
setLayout(new BorderLayout(10, 10));
Canvas canvas_1 = new Canvas();
add(canvas_1, BorderLayout.CENTER);
NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), vlcPath);
Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory();
CanvasVideoSurface videoSurface = mediaPlayerFactory.newVideoSurface(canvas_1);
mediaPlayer = mediaPlayerFactory.newEmbeddedMediaPlayer();
mediaPlayer.setVideoSurface(videoSurface);
}
public void startPlayer() {
mediaPlayer.playMedia(mediaPath);
}
}
Code called each time that I try to update the video shown in the jframe:
// Remove last video shown
getContentPane().removeAll();
// Create new video vclj
video = new VideoPanel();
// add video to jframe
add(video, BorderLayout.CENTER);
setVisible(true);
// Update hierarchy of components and repaint
revalidate();
repaint();
// Start the player
video.startPlayer();
// Update hierarchy of components and repaint
revalidate();
repaint();
setVisible(true);
pack();
As you can see, I call to revalidate and repaint methods before and after starting player for content is updated in the jframe.
BTW, When I pressed the close button of the window that has the video, it shows a frame of the video.
Thanks in advance!!
i made a simple small example working example with hard coded MediaPaths, replace this through your mediaPath Variable:
VideoFrame.java
package de.professional_webworkx.vlcj;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class VideoFrame extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private VideoPanel videoPanel;
public VideoFrame() {
initializeGUI();
}
private void initializeGUI() {
JPanel buttonPanel = createButtonPanel();
this.setTitle("MyVideoApp");
this.setSize(1024, 768);
this.setLayout(new BorderLayout());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
videoPanel = new VideoPanel("/home/ottp/Videos/Test.ogv");
this.getContentPane().add(buttonPanel, BorderLayout.NORTH);
this.getContentPane().add(videoPanel, BorderLayout.CENTER);
this.setVisible(true);
videoPanel.startPlayer();
}
private JPanel createButtonPanel() {
JPanel buttonPanel = new JPanel(new GridLayout(1, 2));
JButton nextVideo = new JButton("Next Video");
nextVideo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
updateVideoPanel();
}
});
buttonPanel.add(nextVideo);
JButton prevVideo = new JButton("Prev Video");
buttonPanel.add(prevVideo);
return buttonPanel;
}
private void updateVideoPanel() {
this.remove(videoPanel);
videoPanel = new VideoPanel("/home/ottp/Videos/Example.ogv");
this.getContentPane().add(videoPanel, BorderLayout.CENTER);
videoPanel.startPlayer();
revalidate();
}
}
VideoPanel.java
package de.professional_webworkx.vlcj;
import java.awt.BorderLayout;
import java.awt.Canvas;
import javax.swing.JPanel;
import uk.co.caprica.vlcj.binding.LibVlc;
import uk.co.caprica.vlcj.player.MediaPlayerFactory;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
import uk.co.caprica.vlcj.player.embedded.videosurface.CanvasVideoSurface;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;
import com.sun.jna.Native;
public class VideoPanel extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private EmbeddedMediaPlayer mediaPlayer;
private Canvas _canvas;
private String mediaPath;
public VideoPanel(final String mediaPath) {
this.mediaPath = mediaPath;
setLayout(new BorderLayout(10, 10));
_canvas = new Canvas();
add(_canvas, BorderLayout.CENTER);
Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory();
CanvasVideoSurface videoSurface = mediaPlayerFactory.newVideoSurface(_canvas);
mediaPlayer = mediaPlayerFactory.newEmbeddedMediaPlayer();
mediaPlayer.setVideoSurface(videoSurface);
}
public void startPlayer() {
mediaPlayer.playMedia(mediaPath);
}
}
App.java
package de.professional_webworkx.vlcj;
import javax.swing.SwingUtilities;
import uk.co.caprica.vlcj.binding.LibVlc;
import uk.co.caprica.vlcj.component.EmbeddedMediaListPlayerComponent;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;
import com.sun.jna.Native;
/**
* Hello world!
*
*/
public class App
{
private static EmbeddedMediaListPlayerComponent component;
public static void main( String[] args )
{
Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new App();
}
});
}
private App() {
new VideoFrame();
}
}
It is a maven project, i added vlcj as a maven dependency to my pom.xml, so i had not to add the searchpath. And also the click on the Next Video Button is handled, so update your Videocontent within the updateVideoPanel() Method, there you can have a List or an Array with all your Videos you would like to show.
Hope this helps..
Related
I want to be able to call the Introduction.Intro() method into my main file code, but it tells me I am unable to call a non-static method intro from a static context. Since I am still fairly new to coding I'm not entirely sure what the problem is. I've added my codes down below. I've tried countless online methods but sadly none have seemed to work.
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Start extends JFrame implements ActionListener
{
private JFrame Main;
private JPanel PanelA, PanelB, PanelC;
private JLabel Text, ImageL;
private JButton Button;
private ImageIcon Image;
public Start ()
{
//Button
Button = new JButton("Start");
Button.addActionListener(new ButtonListener());
//Text
Text = new JLabel("Welcome To The Game"); //ADD NAME OF THE GAME
//Image
Image = new ImageIcon(getClass().getResource("download.jfif")); //ADD THE IMAGE FOR WELCOME
ImageL = new JLabel(Image);
//Top Panel (PanelA) - Image
PanelA = new JPanel();
PanelA.setBorder(BorderFactory.createEmptyBorder(0,200,150,200));
PanelA.setLayout(new FlowLayout(FlowLayout.CENTER));
PanelA.add(ImageL);
//Middle Panel (PanelB) - Text
PanelB = new JPanel();
PanelB.setBorder(BorderFactory.createEmptyBorder(50,200,10,200));
PanelB.setLayout(new FlowLayout(FlowLayout.CENTER));
PanelB.add(Text);
//Bottom Panel (PanelC) - Buttons
PanelC = new JPanel();
PanelC.setBorder(BorderFactory.createEmptyBorder(0,200,20,200));
PanelC.setLayout(new FlowLayout(FlowLayout.CENTER));
PanelC.add(Button);
//Main Frame
Main = new JFrame ();
Main.add(PanelA, BorderLayout.NORTH);
Main.add(PanelB, BorderLayout.CENTER);
Main.add(PanelC, BorderLayout.SOUTH);
Main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Main.setTitle("GAME TITLE"); //ADD THIS LATER
Main.pack();
Main.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent ae)
{
}
public class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == Button)
{
Introduction.Intro1(); //THESE LINE RIGHT HERE
return null; //THESE LINE RIGHT HERE
}
}
}
public static void main(String[] args)
{
new Start();
}
}
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Introduction
{
private JFrame Main;
private JPanel PanelD;
private JLabel Text, ImageL;
private JButton Button;
private ImageIcon Image;
public void Intro()
{
Image = new ImageIcon(getClass().getResource("guy.jfif"));
ImageL = new JLabel(Image);
PanelD = new JPanel();
PanelD.setBorder(BorderFactory.createEmptyBorder(0,100,10,100));
PanelD.setLayout(new FlowLayout(FlowLayout.CENTER));
PanelD.add(ImageL);
PanelD.setVisible(true);
Main.add(PanelD, BorderLayout.NORTH);
}
}
EDIT: So I made another method in the Introduction class where I added this line of code, it managed to fix the error, however, the panel isn't being saved and my JFrame is outputting blank.
public static JFrame Intro1()
{
Introduction M = new Introduction();
return M;
}
If you are looking to initialize the Introduction class in main method of Start class, You can add belo code in main method after Start()
Introduction M = new Introduction();
You main method becomes :
public static void main(String[] args)
{
new Start();
Introduction M = new Introduction();
m.Intro
}
Looking at this set of code, It looks like there is incompatible issue, as you have declare JFrame as return type, while you are returning instance of Introduction.
public static JFrame Intro1()
{
Introduction M = new Introduction();
return M;
}
I would like to draw something like this weather map:
On the top, there is a header which contains information (title, ...) and below there is the actual picture. I tried to model the program like the following but it does not show the image of the weather map.
Later I would like to be able to resize the whole weather map (title and picture).
public class Application {
public static void main(String[] args) {
Window meteoWindow = new Window();
meteoWindow.setVisible(true);
}
}
import javax.swing.*;
import java.awt.*;
public class Window extends JFrame {
Container c;
WeatherMap wm1;
public Window() {
c = getContentPane();
// Loading weather maps
wm1 = new WeatherMap("http://www.link-to-image.com/weatherimage.png");
// ---
c.add(wm1);
setTitle("Meteoview Alpha");
setSize(new Dimension(1920, 1080));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
public class WeatherMap extends JPanel {
private DescriptionPanel descriptionPanel;
private ImagePanel imagePanel;
private WeatherImage weatherImage;
public WeatherMap(String urlPath) {
imagePanel = new ImagePanel();
descriptionPanel = new DescriptionPanel("Wetterkarte 1");
weatherImage = new WeatherImage("http://www.linktoweatherimage/image.png");
}
}
import javax.swing.*;
import java.awt.*;
public class DescriptionPanel extends JPanel {
private String name;
private JLabel nameLabel;
public DescriptionPanel(String name) {
this.name = name;
nameLabel = new JLabel(name, JLabel.LEFT);
setLayout(new FlowLayout());
add(nameLabel);
}
}
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.net.URL;
public class ImagePanel extends JPanel {
private BufferedImage image;
public ImagePanel() {
//setBorder(BorderFactory.createLineBorder(Color.BLACK, 5));
try {
image = ImageIO.read(new URL("http://www.linktoimage/image.png"));
System.out.println("Successfully read...");
} catch(Exception e) {
e.printStackTrace();
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
}
As you can see, I tried it with a few different approaches, but nothing really works. Can you help me to model this? (JPanel on JPanel, or BufferedImage on JPanel, ...)
imagePanel = new ImagePanel();
descriptionPanel = new DescriptionPanel("Wetterkarte 1");
weatherImage = new WeatherImage("http://www.modellzentrale.de/WRF4km/12Z/15h/RR3h_eu.png");
You create 3 components, but you don't add the components to the panel.
Not really sure what you are trying to do since you attempt to read the same image twice, so I don't know why you have a "WeatherImage" and an "ImagePanel".
So I will just suggest you first try something like the following to understand how to use a panel with a layout manager.
imagePanel = new ImagePanel();
descriptionPanel = new DescriptionPanel("Wetterkarte 1");
setLayout( new BorderLayout() );
add(descriptionPanel, BorderLayout.PAGE_START);
add(imagePanel, BorderLayout.CENTER);
Also, then is no need to create a custom painting to simply paint an image at it actual size. You can just add the Image to a JLabel by using an ImageIcon:
image = ImageIO.read(…);
JLabel imageLabel = new JLabel( new ImageIcon(image) );
Now you add the label to any panel you want.
I'm trying to make a simple stickman game where the stickman runs. I've added 2 pictures; 1 where he's standing and 1 where he's running. Have made a JFrame and have tried to switch between the pictures in it by adding the first pic then remove it and add the another.
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Spil extends JFrame {
private static String path_for_image = "index.jpeg";
private static String path2_for_image = "run.jpeg";
#SuppressWarnings("deprecation")
public void run(){
JFrame frame = new JFrame("STICKMAN");
frame.setVisible(true);
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImageIcon image = new ImageIcon(path_for_image);
JLabel label = new JLabel(image);
ImageIcon image2 = new ImageIcon(path2_for_image);
JLabel label2 = new JLabel(image2);
while(true){
add(label);
label.move(10, 0);
if(label.isEnabled()){
remove(label);
add(label2);
} else {
remove(label2);
add(label);
}
}
}
}
^^Here I make the JFrame and the code below is my main class:
EDIT:
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Spil extends JFrame {
private static String path_for_image = "index.jpeg";
private static String path2_for_image = "run.jpeg";
#SuppressWarnings("deprecation")
public void run(){
JFrame frame = new JFrame("STICKMAN");
frame.setVisible(true);
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImageIcon image = new ImageIcon(path_for_image);
JLabel label = new JLabel(image);
ImageIcon image2 = new ImageIcon(path2_for_image);
JLabel label2 = new JLabel(image2);
while(true){
frame.add(label);
label.move(10, 0);
if(label.isEnabled()){
frame.remove(label);
frame.add(label2);
} else {
frame.remove(label2);
frame.add(label);
}
}
}
}
public class Main {
public static void main(String[] args){
Spil run = new Spil();
run.run();
}
}
The problem is that the JFrame appears but without the pictures
use swing timer
there are bunch of problems in your code
1) add(label); should be frame.add(label); you have extends your class with frame .but you have created frame local varible and used it.so add will add to your class/jframe instead of frame.so your frame don't have a lable.
either you can remove extends keyword or you can use your Spil class as a jframe then you don't need to create a another frame variable.
JFrame frame = new JFrame("STICKMAN");) .see example 2 how to do using extends jframe
2) label.isEnabled() always true so you never execute else block.to isEnable be false it should be disabled.
3) removing and adding jlables is really inefficient you can easily change image icon.
4) infinite loop will block the Edt and freez your gui.swing timer will handle this without blocking EDT
5) animation need a time gap if you do very fast it really doesn't look nice.in this example i have set time gap to 10 millisecond. you can change speed of your animation by changing value 10.
swing timer is easy to use and perfect for your requirement.
example 1 without extends JFrame
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
public class Spil {
private static final ImageIcon img1 = new ImageIcon("index.jpeg");
private static final ImageIcon img2 = new ImageIcon("run.jpeg");
boolean bool = false;
public void run() {
JFrame frame = new JFrame("STICKMAN");
frame.setVisible(true);
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel(img1);
frame.add(label);
Timer t = new Timer(10, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (bool) {
label.setIcon(img1);
} else {
label.setIcon(img2);
}
bool=!bool;
}
});
t.start();
}
public static void main(String[] args) {
Spil run = new Spil();
run.run();
}
}
example 2 / extends Jframe
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
public class Spil extends JFrame {
private static final ImageIcon img1 = new ImageIcon("index.jpeg");
private static final ImageIcon img2 = new ImageIcon("run.jpeg");
boolean bool = false;
public void run() {
super.setTitle("STICKMAN");
JLabel label = new JLabel(img1);
add(label);
Timer t = new Timer(10, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (bool) {
label.setIcon(img1);
} else {
label.setIcon(img2);
}
bool = !bool;
}
});
t.start();
}
public static void main(String[] args) {
Spil run = new Spil();
run.setSize(400,300);
run.setVisible(true);
run.run();
}
}
I want to show a changing image on my frame. The imagepath is always the same, but the image will be getting overwritten every 10 seconds from another program.
The problem is that the image is not changing when I overwrite it with another image with the same name. So in my understanding: Compiler looks every look in the path and gets the image -> when the image changed it will be changed on the frame!
I hope you understand my problem and somebody could help me.
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class GUI extends JFrame{
public ImageIcon imageBar;
public JLabel labelimage1;
private JLabel labelimage2;
private JLabel bar1 = new JLabel();
private JLabel bar2 = new JLabel();
private JLabel bar3 = new JLabel();
private JLabel bar4 = new JLabel();
private JLabel bar5 = new JLabel();
private JButton buttonBar1 = new JButton("1");
private JButton buttonBar2 = new JButton("2");
private JButton buttonBar3 = new JButton("3");
private JButton buttonBar4 = new JButton("4");
private JButton buttonBar5 = new JButton("5");
private JPanel panel1 = new JPanel();
private JPanel panel2 = new JPanel();
private JPanel panel3 = new JPanel();
private JFrame window = new JFrame("Interface");
public GUI(){
//set the layouts
panel1.setLayout(new GridLayout(1, 2));
panel2.setLayout(new GridLayout(2, 1));
panel3.setLayout(new GridLayout(2, 5));
//place Panel2 and Panel3 in the window
panel1.add(panel2);
panel1.add(panel3);
//----Panel2
//refreshImage();
//----Panel3
panel3.add(buttonBar1); //add the bars 1-5 on panel3
panel3.add(buttonBar2);
panel3.add(buttonBar3);
panel3.add(buttonBar4);
panel3.add(buttonBar5);
//configure the frame
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
window.setSize(800, 400);
window.getContentPane().add(panel1);
}
public void refreshImage() {
panel2.removeAll(); //delete the old panel
//panel2.repaint();
//panel2.revalidate()
DrawImage pan = new DrawImage();
panel2.add(pan);
panel2.add(labelimage2);
}
}
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class DrawImage extends JPanel implements ActionListener{
private ImageIcon image;
public DrawImage(){
image = new ImageIcon("C:\\Users\\usuario\\Desktop\\image.png");
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
image.paintIcon(this, g, 50, 50);
repaint();
}
#Override
public void actionPerformed(ActionEvent e) {
repaint();
}
}
import java.io.File;
public class Main {
public static void main(String[] args) {
GUI Interface = new GUI();
while(true)
{
Interface.refreshImage();
try {
Thread.sleep(5000); //wait for 5000ms
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Thank you very much!
The likely cause is Java is caching the image in memory, associated with the source name. So rather then trying to reload the image again, Java simply returns the cached version.
You could use ImageIcon#getImage#flush to force Java to reconstruct the image
Problems
You are calling refreshImage from a Thread other then the Event Dispatching Thread, this could cause issues with the updating of the components and cause rendering artifacts
You are forcefully removing the DrawImage pane and adding a new instance, rather the trying to reload the image
You're calling repaint within the paintComponent method, don't do this...
You should consider using a Swing Timer, which will allow you to schedule a regular update and be notified within the context of the Event Dispatching Thread.
You could provide a simple refresh method which flushes the current ImageIcon and schedule a repaint of the panel...or you could just use a JLabel and save your self the time
An example of Image#flush
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SlideShow {
public ImageIcon imageBar;
public static void main(String[] args) {
new SlideShow();
}
public SlideShow() {
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 DrawImage());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DrawImage extends JPanel {
private ImageIcon image;
public DrawImage() {
image = new ImageIcon("D:\\thumbs\\image.png");
Timer timer = new Timer(5000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
refresh();
}
});
timer.start();
}
public void refresh() {
image.getImage().flush();
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image.getImage(), 0, 0, this);
}
}
}
The problem with this, is because the image data is loaded in a background thread, it won't may no be available when the component is first repainted, which could make the component appear to flicker.
A better approach would be to use ImageIO.read, which will ensure that the image is fully loaded before the method returns, the draw back here is that could cause the application to "pause" momentary as the image is loaded, personally, I'd use the refresh method to stop the the Timer (or set the Timer to non-repeating), start a background Thread to load the image (using ImageIO.read) call repaint (which is thread safe) and restart the Timer...
Your while (true) loop risks typing up the Swing event thread locking your program. If it doesn't do that, then you risk unpredictable threading issues by making Swing calls off of the event Thread. These problems can be solved easily by your using a Swing Timer not a while true loop to do your swapping.
Rather than removing and adding components, why not simply display images as ImageIcons within a single non-swapped JLabel.
To swap images here, simply call setIcon(...) on the JLabel.
For an example of using a Swing Timer to swap images, please check out my answer to a similar question here.
For example:
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class TimerImageSwapper {
public static final String[] IMAGE_URLS = {
"http://imaging.nikon.com/lineup/dslr/d7000/img/sample/img_01.png",
"http://imaging.nikon.com/lineup/dslr/d7000/img/sample/img_02.png",
"http://imaging.nikon.com/lineup/dslr/d7000/img/sample/img_04.png",
"http://imaging.nikon.com/lineup/dslr/d3200/img/sample/img_08.png",
"http://imaging.nikon.com/lineup/dslr/d3200/img/sample/img_05.png",
"http://imaging.nikon.com/lineup/dslr/d3200/img/sample/img_01.png",
"http://imaging.nikon.com/lineup/dslr/d3200/img/sample/img_06.png" };
private ImageIcon[] icons = new ImageIcon[IMAGE_URLS.length];
private JLabel mainLabel = new JLabel();
private int iconIndex = 0;;
public TimerImageSwapper(int timerDelay) throws IOException {
for (int i = 0; i < icons.length; i++) {
URL imgUrl = new URL(IMAGE_URLS[i]);
BufferedImage image = ImageIO.read(imgUrl);
icons[i] = new ImageIcon(image);
}
mainLabel.setIcon(icons[iconIndex]);
new Timer(timerDelay, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
iconIndex++;
iconIndex %= IMAGE_URLS.length;
mainLabel.setIcon(icons[iconIndex]);
}
}).start();
}
public Component getMainComponent() {
return mainLabel;
}
private static void createAndShowGui() {
TimerImageSwapper timerImageSwapper;
try {
timerImageSwapper = new TimerImageSwapper(5 * 1000);
JFrame frame = new JFrame("Timer Image Swapper");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(timerImageSwapper.getMainComponent());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I have created a simple VLCJ project that consists of a simple embedded player and a button to exit.
The code is as follows:
package test;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import uk.co.caprica.vlcj.binding.LibVlc;
import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
public class Demo {
private final JFrame frame;
private final EmbeddedMediaPlayerComponent mediaPlayerComponent;
private JPanel videoPane;
private JPanel buttonPane;
private Button exitButton;
private ActionListener a;
private static String vlc_location = "C:\\Program Files\\VideoLAN\\VLC";
public static void main(String[] args) {
NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), vlc_location);
Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Demo().run();
}
});
}
public Demo() {
mediaPlayerComponent = new EmbeddedMediaPlayerComponent();
a = new MyActionListener();
exitButton = new Button("Exit");
exitButton.setActionCommand("Exit app");
exitButton.addActionListener(a);
buttonPane = new JPanel();
buttonPane.setLayout(new BorderLayout());
buttonPane.setBackground(Color.black);
buttonPane.add(exitButton, BorderLayout.CENTER);
videoPane = new JPanel();
videoPane.setLayout(new BorderLayout());
videoPane.setBackground(Color.black);
videoPane.add(mediaPlayerComponent, BorderLayout.CENTER);
videoPane.add(buttonPane, BorderLayout.PAGE_END);
frame = new JFrame("vlcj demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(100, 100);
frame.setSize(1200, 800);
frame.setContentPane(videoPane);
frame.setVisible(true);
}
public void run() {
mediaPlayerComponent.getMediaPlayer().playMedia(video_file);
}
class MyActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent arg0) {
String s = arg0.getActionCommand();
if (s.equals("Exit")) {
System.exit(0);
}
}
}
}
The problem is that the button does show up but it cannot be clicked. When i removed the videoPane, it was back to clickable! Any ideas if I'm missing something?
I am using the version 2.1.0 for vlcj.
Thanks!
Thanks MadProgrammer for your advise. I went on to think about it and tried commenting away the line of code in run(). The JButton came back!
However, when i un-commented the code in run(), the JButton disappeared. I was thinking maybe the Swing runnable was causing issue with the creation of the JButton.
Hence, what i did was to comment away the whole Swing runnable and just use:
final Demo demo = new Demo();
demo.run();
The demo can now play video and display the Exit button, thanks!