I am having a bit of trouble with nested JPanels playing a video. I have an AVPlayer class extend JPanel which plays up to 4 videos simultaneously. Each video is played inside its own canvas which is inside its own JPanel. All the panels are then put into the AVPlayer panel. But when I try to play the videos all I get is a black square.
I'm not sure what the actual problem in my bigger program is but I think I can solve it if I can get the videos to play using the second bit of code below. Can someone tell me why the first bit of code is properly able to display all the videos, but the second one is not.
Code that works:
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setVisible(true);
AVPlayer player = new AVPlayer();
frame.getContentPane().add(player);
frame.revalidate();
String[] path = {"(ei)ga_00.mp4", "ei-utsu(ru)_00.mp4", "video.mp4"};
player.playVideo(path);
Code that shows one small black square
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setVisible(true);
AVPlayer player = new AVPlayer();
JPanel panel = new JPanel();
panel.add(player);
frame.getContentPane().add(panel);
frame.revalidate();
String[] path = {"(ei)ga_00.mp4", "ei-utsu(ru)_00.mp4", "video.mp4"};
player.playVideo(path);
Change JPanel panel = new JPanel(); to JPanel panel = new JPanel(new BorderLayout());
Your AVPlayer should also override the getPreferredSize method of JPanel and return the "preferred size" of the component, this way the layout managers have some hope of actually been able to do there jobs
See Laying Out Components Within a Container for more details
Beware that vlcj's primary video surface is a heavy weight component and mixing them on light weight containers can generate some undesirable effects
Related
I have a JPanel subclass on which I add buttons, labels, tables, etc. To show on screen it I use JFrame:
MainPanel mainPanel = new MainPanel(); //JPanel subclass
JFrame mainFrame = new JFrame();
mainFrame.setTitle("main window title");
mainFrame.getContentPane().add(mainPanel);
mainFrame.setLocation(100, 100);
mainFrame.pack();
mainFrame.setVisible(true);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
But when I size the window, size of panel don't change. How to make size of panel to be the same as the size of window even if it was resized?
You can set a layout manager like BorderLayout and then define more specifically, where your panel should go:
MainPanel mainPanel = new MainPanel();
JFrame mainFrame = new JFrame();
mainFrame.setLayout(new BorderLayout());
mainFrame.add(mainPanel, BorderLayout.CENTER);
mainFrame.pack();
mainFrame.setVisible(true);
This puts the panel into the center area of the frame and lets it grow automatically when resizing the frame.
You need to set a layout manager for the JFrame to use - This deals with how components are positioned. A useful one is the BorderLayout manager.
Simply adding the following line of code should fix your problems:
mainFrame.setLayout(new BorderLayout());
(Do this before adding components to the JFrame)
If the BorderLayout option provided by our friends doesnot work, try adding ComponentListerner to the JFrame and implement the componentResized(event) method. When the JFrame object will be resized, this method will be called. So if you write the the code to set the size of the JPanel in this method, you will achieve the intended result.
Ya, I know this 'solution' is not good but use it as a safety net.
;)
From my experience, I used GridLayout.
thePanel.setLayout(new GridLayout(a,b,c,d));
a = row number, b = column number, c = horizontal gap, d = vertical gap.
For example, if I want to create panel with:
unlimited row (set a = 0)
1 column (set b = 1)
vertical gap= 3 (set d = 3)
The code is below:
thePanel.setLayout(new GridLayout(0,1,0,3));
This method is useful when you want to add JScrollPane to your JPanel. Size of the JPanel inside JScrollPane will automatically changes when you add some components on it, so the JScrollPane will automatically reset the scroll bar.
As other posters have said, you need to change the LayoutManager being used. I always preferred using a GridLayout so your code would become:
MainPanel mainPanel = new MainPanel();
JFrame mainFrame = new JFrame();
mainFrame.setLayout(new GridLayout());
mainFrame.pack();
mainFrame.setVisible(true);
GridLayout seems more conceptually correct to me when you want your panel to take up the entire screen.
I am creating a game, and I have a JPanel inside my JFrame, and I want my panel to maintain a constant size ratio: 1.3x1 (as large as possible). I have a component listener on the frame, and when the frame is resized it resets the size of the panel using setPreferredSize, the problem is that every time I change the frame size, the panel gets resized to a Dimension(10, 10) - meaning that the frame is always tiny. The frame also has a GridBagLayout set because i want the panel in the middle. In addition - sometimes if you resize the frame quickly (draw the corner fast) the frame will appear at the right size for a split second, then go back to 10, 10.
Resizing code in the component listener:
Game.frameSize.x = (int) Math.round((GameFrame.frameSize.y - 2) * 1.2);
Game.frameSize.y = GameFrame.frameSize.y - 2;
this.panel.setPreferredSize(new Dimension(Game.frameSize.x, Game.frameSize.y));
* Game is my jpanel and GameFrame is my JFrame, Game.frameSize and GameFrame.frameSize is only for resizing sprites on the screen
Configuration of the JFrame and the JPanel
JFrame frame = new JFrame("");
frame.setLayout(new GridBagLayout());
frame.setPreferredSize(new Dimension(frameSize.x, frameSize.y));
frame.setSize(new Dimension(frameSize.x, frameSize.y));
frame.setMinimumSize(new Dimension(800, 600));
frame.setResizable(true);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setFocusable(true);
Game game = new Game(frame);
Game.frameSize = new Vector((int) Math.round((GameFrame.frameSize.x - 2) * 1.3), GameFrame.frameSize.y - 2);
game.setSize(new Dimension(frameSize.x, frameSize.y));
game.setPreferredSize(new Dimension(frameSize.x, frameSize.y));
frame.addMouseMotionListener(new GameMouseMotionListener());
frame.addComponentListener(new GameComponentListener(frame, game));
frame.addMouseListener(new GameMouseListener());
frame.addKeyListener(new GameKeyListener());
frame.add(game);
I am really not sure what to do here, as far as google is concerned, no one has ever had this issue. Thank you, any help is appreciated :)
I'm trying to create a basic game where a character can move an image on the screen, which is on top of a background image. Here is my main method, where I'm setting all of this up:
public static void main(String[] args){
EventQueue.invokeLater(new Runnable(){
public void run(){
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Stuff");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
// Create a panel with a component to be moved
JPanel character = new JPanel();
JLabel component = new JLabel();
component.setIcon(new ImageIcon("C:/Users/Cory/Desktop/img/eagle.jpg"));
component.setSize( component.getPreferredSize() );
component.setLocation(200, 200);
component.repaint();
JButton left = addMotionSupport( component );
character.add(component);
character.repaint();
//end moveable
frame.add( character );
frame.repaint();
JPanel background = new JPanel();
JLabel contentPane = new JLabel();
contentPane.setIcon(new ImageIcon("C:/Users/Cory/Desktop/img/background.png"));//sets contentPane to display the background
contentPane.setSize(contentPane.getPreferredSize());
background.add(contentPane);
background.repaint();
frame.add(background);
frame.repaint();
//frame.add(left, BorderLayout.SOUTH);
frame.setSize(1000, 800);
frame.setVisible(true);
}
});
}
The issue I'm running into is the following. I am able to display the background image OR the moveable image, but not both. What I believe is happening is that the two jpanels are 'overlapping' on top of each other - is this correct? How would I fix something like this? I browsed through the API a bit and I found something called a JLayeredPane, but I'm not sure how to use that and if it is even the correct tool. Any insight you provide would be most appreciated.
N.B. the 'addMotionSupport' method only adds a KeyListener to the passed argument.
a character can move an image on the screen, which is on top of a background image.
Then you need to add the character to the background.
So the basic code should be:
JLabel character = new JLabel(...);
character.setSize( character.getPreferredSize() );
JLabel background = new JLabel(...);
background.add( character );
frame.add( background );
You don't need the extra panels. You can add a label directly to the frame.
You need to set the size of the character label because a JLabel does not use a layout manager. So in this case you are responsible for managing the size and location of the character when you add it to the background component. The location will default to (0, 0);
You don't need all the frame.repaint() statements, the frame will be painted when it is made visible. Don't use frame.setSize(), instead use frame.pack(). Then the frame will be set to the size of the background image.
I'm trying to create a program using BorderLayout() that I want to look like this (but with even left right height and such)
although I am having trouble resizing the two JPanels (two boxes within the large box). At the moment my GUI looks like this,
I believe it is due to the CENTER still being there, I looked up on how to remove it but could not get it to work,
Question
Can can I edit this so that it will look like the top image.
package fuelstation;
import java.awt.*;
import java.util.*;
import javax.swing.*;
public class Fuelstation extends JFrame {
JButton btn1 = new JButton("Random Button");
public Fuelstation() {
JFrame frame = new JFrame("Fuel Station");
frame.setLayout(new BorderLayout());
frame.setResizable(false);
frame.setPreferredSize(new Dimension(500,350));
frame.setMaximumSize(new Dimension(500,350));
// Left Hand Side
JPanel lhs = new JPanel();
JTextArea tf_list = new JTextArea();
tf_list.setEditable(false);
tf_list.setWrapStyleWord(true);
tf_list.setText("This is a list of items");
lhs.add(tf_list);
tf_list.setSize(245, 325);
lhs.setBorder(BorderFactory.createTitledBorder("Left"));
// Left Hand Side End
// Right Hand Side
JPanel rhs = new JPanel();
rhs.setAlignmentX(Component.CENTER_ALIGNMENT);
rhs.setBorder(BorderFactory.createTitledBorder("Right"));
rhs.add(btn1);
tf_list.setSize(245, 325);
JPanel center = new JPanel();
center.setSize(0, 0);
// Right Hand Side End
frame.add(lhs, BorderLayout.WEST);
frame.add(center, BorderLayout.CENTER);
frame.add(rhs, BorderLayout.EAST);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
Fuelstation gui = new Fuelstation();
}
}
You need to drop the requirement to use a BorderLayout. The resizing policy for components when using a BorderLayout is stated in the class javadoc
The components are laid out according to their preferred sizes and the constraints of the container's size. The NORTH and SOUTH components may be stretched horizontally; the EAST and WEST components may be stretched vertically; the CENTER component may stretch both horizontally and vertically to fill any space left over.
By forcing your JFrame to a certain size
frame.setResizable(false);
frame.setPreferredSize(new Dimension(500,350));
frame.setMaximumSize(new Dimension(500,350));
your center component will take the extra width, as the EAST and WEST component will only stretch vertically.
So you need to use another LayoutManager. You can use the Visual guide to layout managers to get a grasp of the available LayoutManagers and their capabilities. That document states that a GridLayout would be a good candidate:
GridLayout simply makes a bunch of components equal in size and displays them in the requested number of rows and columns
I have a JFrame with a BorderLayout(). In the SOUTH Layout Constraint I want to put a progressbar. Not a dynamic one but one that gets set with a value (0-100) from time to time.
I thinking of a JPanel in which I draw a Rectangle with appropriate Width.
How can I draw a rectangle inside a JPanel?
JFrame frame = new JFrame();
frame.setBounds(100, 100, 790, 539);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout(0,0));
frame.setResizable(false);
JPanel panelSouth = new JPanel();
frame.getContentPane().add(panelSouth, BorderLayout.WEST);
What I was thinking, maybe I could just resize the JPanel panelSouth. But in the Borderlayout it always stretches out to filll the whole SOUTH.
Instead of starting from scratch, stick with JProgressBar to simplify your event coding. You can draw a rectangle in your implementation of the paint() method in a BasicProgressBarUI, as shown here with an ellipse drawn using fillOval() in paintIndeterminate().