I'm trying to play a video using vlcj inside a JPanel - java

I'm trying to play a video using vlcj inside a JPanel but it doesn't work for me. The message exception I am getting is:
"java.lang.IllegalStateException: The video surface component must be displayable"
The code:
public class MediaPlayerPanel extends JPanel {
private static final long serialVersionUID = 1L;
MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory();
EmbeddedMediaPlayer mediaPlayer = mediaPlayerFactory.newEmbeddedMediaPlayer();
Canvas c = new Canvas();
JPanel p = new JPanel();
public MediaPlayerPanel() {
c.setBackground(Color.black);
p.setLayout(new BorderLayout());
p.add(c, BorderLayout.CENTER);
mediaPlayer.setVideoSurface(mediaPlayerFactory.newVideoSurface(c));
c.setVisible(true);
p.setVisible(true);
}
public void play(String video) {
mediaPlayer.playMedia(video);
}
}
public class VideoPlayer {
public static void main(final String[] args) {
NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), "C:\\Program Files\\VideoLAN\\VLC");
Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
JFrame frame = new JFrame("Video Player");
MediaPlayerPanel mpp = new MediaPlayerPanel();
frame.setLocation(100, 100);
frame.setSize(1050, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mpp, BorderLayout.CENTER);
frame.setVisible(true);
mpp.play("E:\\Filmek\\Game.of.Thrones.S04E02.HDTV.x264-2HD\\game.of.thrones.s04e02.hdtv.x264-2hd.mp4");
}
}

That error message usually means that you tried to do mediaPlayer.play() before you showed (or pack()'ed) the application frame that contains the video surface.
In the code you posted, you are not adding your panel p to the MediaPlayerPanel panel that you create. So your video surface Canvas is not actually attached to any visible component hierarchy.
Your MediaPlayerPanel should set a BorderLayout on itself and add p to that.

Related

Panel doesn't display anything

I have this code bellow that is suppose to display some text but it don't and I can't find the reason why.
public class TestMLD extends JPanel{
TestMLD(){
init();
}
private void init() {
FlowLayout flow = new FlowLayout(FlowLayout.CENTER);
Font font = new Font(Font.MONOSPACED, Font.ITALIC, 100);
JLabel helloLabel = new JLabel("Hello World !");
helloLabel.setFont(font);
helloLabel.setForeground(Color.BLUE);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new TestMLD());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
new TestMLD();
}
}
Thanks in advance
The issue here is that you never actually add the JLabel helloLabel to your JPanel / TestMLD.
To do so, add this line of code at the end of your init() method:
add(helloLabel);
You also never actually set the layout you created to your panel
setLayout(flow);
Also, the second time you create a new TestMLD() object is redundant. You can omit that.
All together, the updated code should look something like this:
public class TestMLD extends JPanel {
TestMLD() {
init();
}
private void init() {
FlowLayout flow = new FlowLayout(FlowLayout.CENTER);
setLayout(flow);
Font font = new Font(Font.MONOSPACED, Font.ITALIC, 100);
JLabel helloLabel = new JLabel("Hello World !");
helloLabel.setFont(font);
helloLabel.setForeground(Color.BLUE);
add(helloLabel);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new TestMLD());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
}
}

How to provide communicate from panel to frame in java

I have used cardlayout in my main class. I have added first panel in that cardlayout. I'm trying to hide the image in frame from first panel. So I have used interface like below code,
My Main class,
public class HomePage implements OptionMenuListener{
private static void createAndShowGUI() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Already there
frame.setUndecorated(true);
frame.setLocationRelativeTo(null);
JPanel contentPane = new JPanel();
contentPane.setLayout(new CardLayout(20, 20));
File file = new File(jsonFilePath);
if(!file.exists()) {
LoginPage login = new LoginPage();
contentPane.add(login, Constants.CARD_LOGIN);
ConfigueBranch configureBranch = new ConfigueBranch(false);
contentPane.add(configureBranch, Constants.CARD_CONFIGURE_BRANCH);
ConfigureSystem configureSystem = new ConfigureSystem(false);
contentPane.add(configureSystem, Constants.CARD_CONFIGURE_SYSTEM);
ConfigureCustomer configureCustomer = new ConfigureCustomer(false);
contentPane.add(configureCustomer, Constants.CARD_CONFIGURE_CUSTOMER);
}
MainPage mainPage = new MainPage(HomePage.this);
contentPane.add(mainPage, Constants.CARD_MAINPAGE);
// SettingsPage configureExpinContainer = new SettingsPage();
// contentPane.add(configureExpinContainer, Constants.CARD_SETTINGS_PAGE);
JPanel buttonPanel = new JPanel();
buttonPanel.setBorder(new EmptyBorder(50, 10, 10, 10));
Image image = MyUtil.loadImage("/logo.png"); // transform it
Image newimg = image.getScaledInstance(244, 80, java.awt.Image.SCALE_SMOOTH);
ImageIcon icon = new ImageIcon(newimg); // transform it back
JLabel label = new JLabel("", icon, JLabel.LEFT);
label.setFont(new java.awt.Font("Arial", Font.BOLD, 24));
label.setOpaque(true);
label.setForeground(Color.BLACK);
label.setBounds(0, 60, 300, 200);
buttonPanel.add(label);
frame.add(contentPane, BorderLayout.CENTER);
frame.add(buttonPanel, BorderLayout.PAGE_START);
frame.pack();
frame.setSize(1000, 700);
centeredFrame(frame);
frame.setVisible(true);
frame.setResizable(false);
}
public static void centeredFrame(javax.swing.JFrame objFrame) {
Dimension objDimension = Toolkit.getDefaultToolkit().getScreenSize();
int iCoordX = (objDimension.width - objFrame.getWidth()) / 2;
int iCoordY = (objDimension.height - objFrame.getHeight()) / 2;
objFrame.setLocation(iCoordX, iCoordY);
}
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
#Override
public void onMenuSelect(boolean isShow) {
}
}
I'm using for interface to provide communication to frame from panel,
public interface OptionMenuListener {
void onMenuSelect(boolean isShow);
}
I'm using the below panel in cardlayout,
public class MainPage extends JPanel{
JButton inputOutputFilesBtn, syncBtn, tsBtn, settingsBtn;
public MainPage(HomePage homePage){
homePage.onMenuSelect(true);
init();
}
public void init(){
JTabbedPane jtbExample = new JTabbedPane();
JPanel jplInnerPanel1 = createInnerPanel("No device connected");
jtbExample.addTab("Input and Output Files", jplInnerPanel1);
jtbExample.setSelectedIndex(0);
JPanel jplInnerPanel2 = createInnerPanel("No device connected");
jtbExample.addTab("Sync", jplInnerPanel2);
JPanel jplInnerPanel3;
if(configuredSystem.equalsIgnoreCase("Expeditors")) {
jplInnerPanel3 = createInnerPanel("No device connected");
jtbExample.addTab("TS", jplInnerPanel3);
}
JPanel jplInnerPanel4 = new SettingsPage();
jtbExample.addTab("Settings", jplInnerPanel4);
JPanel jplInnerPanel5 = new LogoutPage();
jtbExample.addTab("Logout", jplInnerPanel5);
this.setLayout(new BorderLayout());
this.setPreferredSize(new Dimension(620, 400));
this.add(jtbExample, BorderLayout.CENTER);
add(jtbExample);
}
protected JPanel createInnerPanel(String text) {
JPanel jplPanel = new JPanel();
JLabel jlbDisplay = new JLabel(text);
jlbDisplay.setHorizontalAlignment(JLabel.CENTER);
jplPanel.setLayout(new GridLayout(1, 1));
jplPanel.add(jlbDisplay);
return jplPanel;
}
But i'm getting Cannot use this in a static context error in this below line
MainPage mainPage = new MainPage(HomePage.this);
Now i want to send some information from panel to the frame which have cardlayout. Could you please suggest me an idea to do this? Thanks in advance.
You can't use this in a static context like since this represent the class instance that is executing a method. Here, you are in a static context, so you don't have an instance.
private static void createAndShowGUI() {
MainPage mainPage = new MainPage(HomePage.this);
}
You either need to declare a variable
private static void createAndShowGUI() {
HomePage homePage = /*initialize or get it from somewhere */
MainPage mainPage = new MainPage(homePage);
}
Or move that logic outside the static context
private void createAndShowGUI() {
MainPage mainPage = new MainPage(HomePage.this);
}

One of the JLayeredPane layers is not showing up

There are a number of similar posts, notably:
Java Swing JLayeredPane not showing up
and
Top layer in JLayeredPane not displaying
But none of them seem to solve my specific problem.
I have the following code:
public class PlayScreen{
private JLayeredPane playScreen;
private Player player;
private JPanel towerButtons;
private JPanel detailPanel;
private JLabel map;
public PlayScreen(Player player){
this.player = player;
playScreen = new JLayeredPane();
playScreen.setLayout(new BorderLayout());
setTowerButtons();
playScreen.add(towerButtons, BorderLayout.EAST);
playScreen.setLayer(towerButtons, 0);
setDetailLabels();
playScreen.add(detailPanel, BorderLayout.WEST);
playScreen.setLayer(detailPanel, 0);
setMap(player.getNextMap());
playScreen.add(map, BorderLayout.CENTER);
playScreen.setLayer(map, 0);
JButton playButton = new JButton("play");
playScreen.add(playButton, BorderLayout.NORTH);
playScreen.setLayer(playButton, 0);
playButton.addActionListener(new playListener());
playScreen.setVisible(true);
}
where setTowerButtons(), setDetailLabels() and setMap() methods called in the constructor basically initialize the towerButtons, detailPanel and map fields.
When the "play" button is pressed, the following code is called:
public class playListener implements ActionListener{
public void actionPerformed(ActionEvent e){
Image image = null;
try{
image = ImageIO.read(new File("mob1.bmp"));
}
catch (Exception e1){
System.out.println("image creation failed");
}
ImageIcon img = new ImageIcon(image);
JLabel mob1Button = new JLabel(img);
System.out.println("hi");
playScreen.add(mob1Button, BorderLayout.CENTER);
playScreen.setLayer(mob1Button, 1);
mob1Button.setVisible(true);
}
}
I know that this is definitely called, because "hi" appears on the output stream.
(The playScreen is a JLayeredPane that is constructed from this:)
public class View {
private JFrame frame;
private Container contentPane;
private Player player;
private LoadScreen loadScreen;
private PlayScreen playScreen;
public View(Player player){
frame = new JFrame("Display");
contentPane = frame.getContentPane();
contentPane.setLayout(new BorderLayout());
this.player = player;
frame.setLocationRelativeTo(null); //puts frame in middle of screen
frame.pack();
frame.setVisible(true);
}
public void makeLoadScreen(){
loadScreen = new LoadScreen();
contentPane.add(loadScreen.getLoadScreen(), BorderLayout.CENTER);
frame.pack();
}
public void makePlayScreen(Player player){
contentPane.remove(loadScreen.getLoadScreen());;
playScreen = new PlayScreen(player);
contentPane.add(playScreen.getPlayScreen());
frame.pack();
}
public class LoadScreen{
private JPanel loadScreen;
public LoadScreen(){
loadScreen = new JPanel();
JButton play = new JButton("Play");
JButton load = new JButton("Load");
loadScreen.setLayout(new GridLayout(2,1,0,0));
loadScreen.add(play);
loadScreen.add(load);
play.addActionListener(new OpenActionListener());
load.addActionListener(new LoadActionListener());
}
public JPanel getLoadScreen(){
return loadScreen;
}
public class OpenActionListener implements ActionListener{
public void actionPerformed(ActionEvent e){
makePlayScreen(player);//might not be receiving correct player variable?
}
}
public class LoadActionListener implements ActionListener{
public void actionPerformed(ActionEvent e){
}
}
}
}
public GameManager(){
player = new Player();
player.setNextMap("map.bmp");
//Tower tower = new Tower1();
//player.addUnlockedTower(tower);
view = new View(player);
view.makeLoadScreen();
}
A GameManager Class is created. This creates the loadScreen, which has two buttons, "play" and "load." Clicking on "play" creates the playScreen, which is governed by a separate class.
Sorry for all the code, but I have no idea anymore where it is going wrong, I thought it was to do with not setting the sizes of the playScreen, towerButtons etc, as in the similar post, but that didn't seem to work when I added preferred /min / max sizes.
Currently an image of the map comes up, but the image of the "mob1" does not appear at all, and I would expect it to overlay the map image.

Java CardLayout not displaying

I have a game that already runs and works and I want to add a title screen to it. I'm trying to add a CardLayout for easy switching between game and titlescreen. My current issue is that nothing is being displayed. Here is an image: http://i.imgur.com/kVIXYQ7.png . I simply get a blank JPanel when I run it. What am I doing wrong?
public class UI
{
private static JPanel cards;
private static CardLayout cardLayout;
public static void main(String args[])
{new UI();}
public UI()
{
JFrame frame = new JFrame("Scrolling Shooter");
frame.setResizable(false);
Toolkit tk = Toolkit.getDefaultToolkit();
int width = ((int) tk.getScreenSize().getWidth());
int height = ((int) tk.getScreenSize().getHeight());
frame.setSize(width, height);
TitleScreen title = new TitleScreen(frame);
ScrollingShooter game = new ScrollingShooter(frame);
cards = new JPanel(new CardLayout());
cards.add(title, "title");
cards.add(game, "game");
cards.setOpaque(true);
frame.getContentPane().add(cards);
cardLayout = (CardLayout) cards.getLayout();
cardLayout.first(cards);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
/**
* Switches to the next screen
*/
public static void nextScreen()
{cardLayout.next(cards);}
/**
* Returns to the first screen
*/
public static void firstScreen()
{cardLayout.first(cards);}
}
You haven't added Cards to anything.
Try adding Cards to frame and then make the frame visible
For example...
JFrame frame = new JFrame("Scrolling Shooter");
TitleScreen title = new TitleScreen(frame);
ScrollingShooter game = new ScrollingShooter(frame);
cards = new JPanel(new CardLayout());
cards.add(title, "title");
cards.add(game, "game");
cards.setOpaque(true);
cardLayout = (CardLayout) cards.getLayout();
cardLayout.first(cards);
frame.add(cards);
//...
frame.setResizable(false);
frame.setSize(width, height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
FYI: You should come setResizable before setting the frame size as setResizable can change the frames border insets

vlcj video not showing, but video sound is heard

when the application is run, the sound is heard and other button controls are visible on the frame, but the panel containing the video does not show any black screen neither is it displayed on the frame.
public class MediaPlayer extends JPanel {
private JFrame ourframe = new JFrame();
//Declares our media player component
private EmbeddedMediaPlayerComponent mediaplayer;
//This string holds the media URL path
private String mediapath = "";
//This string holds the vlc URL path
private final String vlcpath = "C:\\Program Files (x86)\\VideoLAN\\VLC";
private JPanel panel, panel2;
private JButton play_btn, stop_btn, foward_btn, rewind_btn, enlarge_btn;
private JSlider timeline;
public MediaPlayer(String mediapath) {
this.mediapath = mediapath;
NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), vlcpath);
mediaplayer = new EmbeddedMediaPlayerComponent();
panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(mediaplayer, BorderLayout.CENTER); //panel containing the video
play_btn = new JButton("play");
stop_btn = new JButton("stop");
foward_btn = new JButton("ff");
rewind_btn = new JButton("rew");
enlarge_btn = new JButton("enlarge");
timeline = new JSlider(0, 100, 0);
timeline.setMajorTickSpacing(10);
timeline.setMajorTickSpacing(5);
timeline.setPaintTicks(true);
panel2 = new JPanel();
panel2.setLayout(new FlowLayout(FlowLayout.CENTER));
panel2.add(play_btn);
panel2.add(stop_btn);
panel2.add(foward_btn);
panel2.add(rewind_btn);
panel2.add(enlarge_btn);
panel2.add(timeline);
panel.add(panel2, BorderLayout.SOUTH);
add(panel);
}
public void play() {
mediaplayer.getMediaPlayer().playMedia(mediapath);
}
public static void main(String[] args) {
//Declare and initialize local variables
String mediaPath = "";
mediaPath = "C:\\Users\\goldAnthony\\Desktop\\Videos\\Whistle.mp4";
//creates instances of the VlcPlayer object, pass the mediaPath and invokes the method "run"
MediaPlayer mediaplayer = new MediaPlayer(mediaPath);
JFrame ourframe = new JFrame();
ourframe.setContentPane(mediaplayer);
ourframe.setSize(720, 560);
ourframe.setVisible(true);
mediaplayer.play();
ourframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
This is because you are adding the video surface to a JPanel without choosing an appropriate layout manager.
By default JPanel has a FlowLayout and this will layout components according to their preferred size.
The video surface panel has no preferred size set.
The solution is to set a layout manager like BorderLayout on the main panel.
So at the end of your constructor, instead of this...
add(panel);
...do this...
setLayout(new BorderLayout());
add(panel, BorderLayout.CENTER);
Cross-posted at [1].
[1] https://groups.google.com/forum/#!topic/vlcj-users/m0zG-fx4qm8

Categories