I have a movie-player type application. You have a movie of JPanels that you can "play", that is you can have the frames change either automatically on a timer or by advancing a frame at a time manually. I've created 4 trivial frames (simple JPanels with different colors). It can go through all the frames (JPanels) once, but then it cannot do it again. When a frame changes, it is removed from the larger JPanel and replaced with a different frame. Clearly something is wrong when I am removing and adding frames from my BorderLayout. Can someone please run this and see where I am going wrong (relevant line numbers should be lines 182 - 194. That's where I am removing the current JPanel and adding a different one)?
Please note that in the above explanation, I am referring to "frame" as a "movie frame", not a JFrame. The lingo can get a bit confusing.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class FramePlayer extends JPanel implements ActionListener, ChangeListener
{
JPanel frames[];
JPanel currentFrame;
javax.swing.Timer timer;
int timeBetweenFrames;
int numFrames;
int currentFrameNumber;
Color playerColor;
JButton playButton, pauseButton, firstFrameButton, lastFrameButton, nextFrameButton,
prevFrameButton;
JSlider speedSlider;
JLabel displayLabel;
boolean timerMode;
JPanel viewPanel;
public FramePlayer (JPanel[] theframes, Color viewBorderColor, int playerWidth,
int playerHeight, int frameWidth, int frameHeight)
{
frames = theframes;
numFrames = frames.length;
timerMode = false;
playButton = new JButton ("Play");
pauseButton = new JButton ("Pause");
firstFrameButton = new JButton ("First Frame");
lastFrameButton = new JButton ("Last Frame");
nextFrameButton = new JButton ("Next Frame");
prevFrameButton = new JButton ("Prev. Frame");
playButton.addActionListener (this);
pauseButton.addActionListener (this);
pauseButton.setEnabled (false);
firstFrameButton.addActionListener (this);
lastFrameButton.addActionListener (this);
nextFrameButton.addActionListener (this);
prevFrameButton.addActionListener (this);
speedSlider = new JSlider (1, 100, 25);
speedSlider.addChangeListener(this);
timer = new javax.swing.Timer (250, this);
displayLabel = new JLabel ();
this.setLayout (new BorderLayout ());
this.setPreferredSize (new Dimension (playerWidth, playerHeight));
int controlPanelHeight = 200;
int controlPanelWidth = playerWidth;
int viewPanelHeight = playerHeight - controlPanelHeight;
int viewPanelWidth = playerWidth;
viewPanel = new JPanel ();
viewPanel.setLayout (new BorderLayout ());
viewPanel.setPreferredSize (new Dimension (viewPanelWidth, viewPanelHeight));
JPanel controlPanel = new JPanel ();
controlPanel.setLayout (new GridLayout (3, 1));
controlPanel.setPreferredSize (new Dimension (controlPanelWidth, controlPanelHeight));
for (int i = 0; i < numFrames; i++)
frames[i].setPreferredSize (new Dimension (frameWidth, frameHeight));
JPanel topBorder = new JPanel ();
topBorder.setPreferredSize(new Dimension (viewPanelWidth, (viewPanelHeight - frameHeight) / 2));
JPanel botBorder = new JPanel ();
botBorder.setPreferredSize(new Dimension (viewPanelWidth, (viewPanelHeight - frameHeight) / 2));
JPanel leftBorder = new JPanel ();
leftBorder.setPreferredSize(new Dimension ((viewPanelWidth - frameWidth) / 2, frameHeight));
JPanel rightBorder = new JPanel ();
rightBorder.setPreferredSize(new Dimension ((viewPanelWidth - frameWidth) / 2, frameHeight));
topBorder.setBackground (viewBorderColor);
botBorder.setBackground (viewBorderColor);
leftBorder.setBackground (viewBorderColor);
rightBorder.setBackground (viewBorderColor);
viewPanel.add (topBorder, BorderLayout.PAGE_START);
viewPanel.add (botBorder, BorderLayout.PAGE_END);
viewPanel.add (leftBorder, BorderLayout.LINE_START);
viewPanel.add (rightBorder, BorderLayout.LINE_END);
FrameChange (1);
// control panel setup
JPanel panel1 = new JPanel ();
panel1.setLayout (new GridLayout (1, 6));
panel1.add (playButton);
panel1.add (pauseButton);
panel1.add (firstFrameButton);
panel1.add (lastFrameButton);
panel1.add (nextFrameButton);
panel1.add (prevFrameButton);
JPanel panel2 = new JPanel ();
panel2.setLayout (new GridLayout (1, 2));
JLabel speedLabel = new JLabel ("Speed : ");
speedLabel.setHorizontalAlignment(JLabel.RIGHT);
panel2.add (speedLabel);
panel2.add (speedSlider);
controlPanel.add (panel1);
controlPanel.add (panel2);
displayLabel.setHorizontalAlignment(JLabel.CENTER);
controlPanel.add (displayLabel);
this.add (viewPanel, BorderLayout.CENTER);
this.add (controlPanel, BorderLayout.PAGE_END);
}
public void setLabelString ()
{
timeBetweenFrames = speedSlider.getValue ();
String labelString = "Frame " + Integer.toString (currentFrameNumber) + " of ";
labelString = labelString.concat (Integer.toString (numFrames) + " : Time Between Frames = ");
labelString = labelString.concat (Integer.toString (timeBetweenFrames) + " / 100 sec.");
displayLabel.setText(labelString);
}
public void actionPerformed(ActionEvent e)
{
Object obj = e.getSource();
if (obj == playButton)
{
if (timerMode)
return;
timerMode = true;
timer.start ();
playButton.setEnabled (false);
pauseButton.setEnabled (true);
}
else if (obj == pauseButton)
{
if (!timerMode)
return;
timerMode = false;
timer.stop ();
playButton.setEnabled (true);
pauseButton.setEnabled (false);
}
else if (obj == firstFrameButton)
{
currentFrameNumber = 1;
timer.stop ();
timerMode = false;
pauseButton.setEnabled (false);
if (numFrames > 1)
playButton.setEnabled (true);
else
playButton.setEnabled (false);
}
else if (obj == lastFrameButton)
{
FrameChange (numFrames);
}
else if (obj == nextFrameButton)
{
FrameChange (currentFrameNumber + 1);
}
else if (obj == prevFrameButton)
{
FrameChange (currentFrameNumber - 1);
}
else if (obj == timer)
{
if (!FrameChange (currentFrameNumber + 1))
timer.stop ();
}
}
public boolean FrameChange (int framenumber)
{
if (framenumber < 1 || framenumber > numFrames)
return false;
currentFrameNumber = framenumber;
currentFrame = frames[currentFrameNumber - 1];
setLabelString();
BorderLayout bl = (BorderLayout) viewPanel.getLayout ();
JPanel currentCenterPanel = (JPanel) bl.getLayoutComponent(BorderLayout.CENTER);
if (currentCenterPanel != null)
bl.removeLayoutComponent (currentCenterPanel);
viewPanel.add (currentFrame, BorderLayout.CENTER);
if (currentFrameNumber == 1)
{
firstFrameButton.setEnabled (false);
prevFrameButton.setEnabled (false);
}
else
{
firstFrameButton.setEnabled (true);
prevFrameButton.setEnabled (true);
}
if (currentFrameNumber >= numFrames)
{
nextFrameButton.setEnabled (false);
lastFrameButton.setEnabled (false);
timerMode = false;
}
else
{
nextFrameButton.setEnabled (true);
lastFrameButton.setEnabled (true);
}
if (timerMode)
{
playButton.setEnabled (false);
pauseButton.setEnabled (true);
}
else
{
if (currentFrameNumber >= numFrames)
playButton.setEnabled (false);
else
playButton.setEnabled (true);
pauseButton.setEnabled (false);
}
return true;
}
public void stateChanged(ChangeEvent e)
{
Object obj = e.getSource();
if (obj == speedSlider)
{
timeBetweenFrames = speedSlider.getValue();
timer.setDelay (timeBetweenFrames * 10);
setLabelString ();
}
}
public static void main (String args[])
{
JFrame frame = new JFrame ();
frame.setSize (800, 700);
JPanel frames[] = new JPanel[4];
Color colors[] = {Color.BLUE, Color.GREEN, Color.RED, Color.YELLOW};
for (int i = 0; i < 4; i++)
{
frames[i] = new JPanel ();
frames[i].setBackground (colors[i]);
}
FramePlayer fp = new FramePlayer (frames, Color.BLACK, 800, 700, 300, 300);
frame.getContentPane ().add (fp);
frame.setVisible (true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}