I've two classes, one that is responsible for "drawing" the graphics interface (MainFrame class) and another one that is a form that should be added to a panel.
When I run the code I get java.lang.NullPointerException
Here is the stack trace:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at view.MainFrame2.addModuleToLeftPanel(MainFrame2.java:213)
at view.modules.PingPong.<init>(PingPong.java:179)
at view.MainFrame2.<init>(MainFrame2.java:65)
at view.MainFrame2.<init>(MainFrame2.java:37)
at view.MainFrame2$3.run(MainFrame2.java:224)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:721)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:682)
at java.awt.EventQueue$3.run(EventQueue.java:680)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:691)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)
Here is the method in my MainFrame class:
public void addModuleToLeftPanel(String tittle, Component module)
{
leftTabbedPane.add(tittle, module);
}
And leftTabbedPane is a JTabbedPane()
My other class where I call this method from MainFrame is:
public PingPong(final Api api, MainFrame2 mainFrame) {
(...)
mainFrame.addModuleToLeftPanel("Test", this); // here I get Leaking this in construcor warning.
}
I understand that the null pointer exception is because I'm adding an object that has not been initialized, right? My question is, how can I fix this problem?
What I want is to let PingPong class tell MainFrame "Hey, add me to the left panel" and MainFrame adds PingPong to the left panel.
----------------------- EDIT ------------------------
As requested, here is the code from MainFrame2 class and PingPong class:
MainFrame2.class:
public class MainFrame2 extends JFrame {
// Classes in this project
private ToolBar2 toolBar;
private Api api;
private StatusPanel2 statusPanel;
private JMenuBar menuBar;
// Modules go here
private PingPong pingPong;
// Class variables
private JTabbedPane leftTabbedPane;
private JTabbedPane rightTabbedPane;
private JSplitPane splitPane;
private MainFrame2() {
super("An awesome piece of software");
// Classes Initialization
api = Api.getInstance();
toolBar = new ToolBar2(api);
statusPanel = StatusPanel2.getInstance();
// Module classes initialization
pingPong = new PingPong(api, this);
// Java Imported Classes Initialization
leftTabbedPane = new JTabbedPane();
rightTabbedPane = new JTabbedPane();
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftTabbedPane, rightTabbedPane);
// JSplitPanel properties, make is one click expandable.
splitPane.setOneTouchExpandable(true);
// Window properties
setExtendedState(JFrame.MAXIMIZED_BOTH);//start as maximized
setVisible(true);
setMinimumSize(new Dimension(600, 400));
// Do nothing because there is a window closing listener that handles it
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
// Set Layout Manager
setLayout(new BorderLayout());
// Rezise the textPanel, otherwise by default it is just one line height
statusPanel.setPreferredSize(new Dimension(getWidth(), 150));
statusPanel.revalidate(); //Apply the changes.
/*
* To disconnect to the MySQL server when closing
* the program window
*/
addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
try {
api.disconnet();
dispose(); //clean garbage collector
System.gc(); //clean garbage collector
} catch (SQLException ex) {
Logger.getLogger(MainFrame2.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
// Add the components
add(toolBar, BorderLayout.NORTH);
add(statusPanel, BorderLayout.SOUTH);
add(splitPane, BorderLayout.CENTER);
//Set the Menu
setJMenuBar(createMenuBar());
}
/*
* *************************************************************
* ----------------------- Menu Section ------------------------
* *************************************************************
*/
private JMenuBar createMenuBar() {
menuBar = new JMenuBar();
JMenu editMenu = new JMenu("Edit");
JMenu fileMenu = new JMenu("File");
JMenu windowMenu = new JMenu("Window");
JCheckBoxMenuItem showDataProcessForm = new JCheckBoxMenuItem("Show Data Input Panel");
showDataProcessForm.setSelected(true);
JMenuItem showSourceServerForm = new JMenuItem("Configure Source Server");
JMenuItem showDestinationServerForm = new JMenuItem("Configure Destination Server");
JMenuItem optionsDialogForm = new JMenuItem("Options");
editMenu.add(showSourceServerForm);
editMenu.add(showDestinationServerForm);
editMenu.add(optionsDialogForm);
windowMenu.add(showDataProcessForm);
JMenuItem importResults = new JMenuItem("Import Results");
JMenuItem exportResults = new JMenuItem("Export Results");
JMenuItem importDatabase = new JMenuItem("Import Table to the Database");
JMenuItem exportDatabaseTable = new JMenuItem("Export Table from the Database");
JMenuItem quitItem = new JMenuItem("Quit");
fileMenu.add(importResults);
fileMenu.add(exportResults);
fileMenu.addSeparator();
fileMenu.add(importDatabase);
fileMenu.add(exportDatabaseTable);
fileMenu.addSeparator();
fileMenu.add(quitItem);
menuBar.add(fileMenu);
menuBar.add(editMenu);
menuBar.add(windowMenu);
// Creating Mnemonics
fileMenu.setMnemonic(KeyEvent.VK_F);//VK_F stands for virtual key, alt+F
editMenu.setMnemonic(KeyEvent.VK_E); // alt + E
windowMenu.setMnemonic(KeyEvent.VK_W); // alt + W
// showSourceServerForm.setMnemonic(KeyEvent.VK_S); // alt + s
// showDestinationServerForm.setMnemonic(KeyEvent.VK_D); // alt + d
// Creating accelerators, control + s -> save file
quitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.CTRL_MASK));
importResults.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I, ActionEvent.CTRL_MASK));
exportResults.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, ActionEvent.CTRL_MASK));
showSourceServerForm.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
showDestinationServerForm.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, ActionEvent.CTRL_MASK));
/*
* Adding Action Listener
*/
quitItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int action = JOptionPane.showConfirmDialog(MainFrame2.this, "Do you really want to quit the application?", "Confirm Exit", JOptionPane.OK_CANCEL_OPTION);
if (action == JOptionPane.OK_OPTION) {
WindowListener[] listeners = getWindowListeners();
for (WindowListener listener : listeners) {
listener.windowClosing(new WindowEvent(MainFrame2.this, 0));
}
}
}
});
return menuBar;
}
public void addModuleToLeftPanel(String tittle, Component module)
{
leftTabbedPane.add(tittle, module);
}
// Main
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new MainFrame2();
}
});
}
}
PingPong.class:
public class PingPong extends JPanel {
private JLabel readFromLabel;
private JLabel accessSessionTimeThresholdLabelLabel;
private JLabel transitionTimeThresholdLabelLabel;
private JLabel smoothLabel;
private JLabel statisticsLabel;
private JTextField accessSessionTimeThresholdField;
private JTextField transitionTimeThresholdField;
private JTextField writeToNewTableField;
private JComboBox readFromComboBox;
private JComboBox writeToTableComboBox;
private JRadioButton writeResultsToNewTableRadio;
private JRadioButton writeResultsToExistingTableRadio;
private ButtonGroup writeResultsToTableGroup;
private JCheckBox smoothCheckBox;
private JCheckBox statisticsCheckBox;
private JButton applyButton;
private JButton refreshReadDataFrom;
private JButton refreshSaveDataTo;
private String[] itemsComboBox;
public PingPong(final Api api, MainFrame2 mainFrame)
{
Border innerBorder = BorderFactory.createTitledBorder("Detect Ping Pong");
Border outterBorder = BorderFactory.createEmptyBorder(5, 5, 5, 5);
setBorder(BorderFactory.createCompoundBorder(outterBorder, innerBorder));
Dimension dim = new Dimension(400, 100);
setPreferredSize(dim);
setMinimumSize(dim);
// Labels
readFromLabel = new JLabel("Read Data From: ");
writeResultsToExistingTableRadio = new JRadioButton("Save Results to Existing Table: ");
writeResultsToNewTableRadio = new JRadioButton("Save Results to New Table: ");
accessSessionTimeThresholdLabelLabel = new JLabel("Access Session Time Threshold: ");
transitionTimeThresholdLabelLabel = new JLabel("Transition Time Threshold: ");
smoothLabel = new JLabel("Smooth Ping Pong?");
statisticsLabel = new JLabel("Output Ping Pong statistics?");
// JTextFields
accessSessionTimeThresholdField = new JTextField(5);
transitionTimeThresholdField = new JTextField(5);
writeToNewTableField = new JTextField(10);
// JCheckBox
smoothCheckBox = new JCheckBox();
statisticsCheckBox = new JCheckBox();
itemsComboBox = new String[] {"Not Connected"};
readFromComboBox = new JComboBox(itemsComboBox);
writeToTableComboBox = new JComboBox(itemsComboBox);
// JButton
applyButton = new JButton("Apply");
refreshReadDataFrom = new JButton();
refreshReadDataFrom.setIcon(createIcon("/view/images/view-refresh.png"));
refreshReadDataFrom.setToolTipText("Refresh the current table list.");
refreshSaveDataTo = new JButton();
refreshSaveDataTo.setIcon(createIcon("/view/images/view-refresh.png"));
refreshSaveDataTo.setToolTipText("Refresh the current table list.");
writeResultsToTableGroup = new ButtonGroup();
writeResultsToTableGroup.add(writeResultsToExistingTableRadio);
writeResultsToTableGroup.add(writeResultsToNewTableRadio);
// Adding a listener to the Apply JButton
applyButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Get the database table to where save the results
String writeToTable = "";
String sessionThreshold = accessSessionTimeThresholdField.getText();
String transitionThreshold = transitionTimeThresholdField.getText();
String readFromTable = readFromComboBox.getSelectedItem().toString();
boolean smoothPingPong = smoothCheckBox.isSelected();
boolean statistics = smoothCheckBox.isSelected();
boolean newTable = writeResultsToNewTableRadio.isSelected();
if(writeResultsToExistingTableRadio.isSelected())
{
writeToTable = writeToTableComboBox.getSelectedItem().toString();
}
if(writeResultsToNewTableRadio.isSelected())
{
writeToTable = writeToNewTableField.getText();
}
// Validate the form
if(writeToTable.isEmpty() | sessionThreshold == null | transitionThreshold.isEmpty() | readFromTable.isEmpty() )
{
JOptionPane.showMessageDialog(null, "Please double check the input data "
+ "in the Ping Pong form. Select a radio buttom and/or insert the required data.", "Ping Pong Form Error",
JOptionPane.ERROR_MESSAGE);
return;
}
// To do...
}
});
// Adding a listener to the refresh JButton
refreshReadDataFrom.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
// api.showTables(api.getConnectionSourceServer());
String[] items = {"Testing 1", "Testing 2"};
api.setCombomBoxNewItemList(items, readFromComboBox);
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Please make sure you are connected to the server"
, "Connection Error",
JOptionPane.ERROR_MESSAGE);
}
}
});
// Adding a listener to the refresh JButton
refreshSaveDataTo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
api.showTables(api.getConnectionDestinationServer());
} catch (Exception ex) {
api.displayErrorBox(ex.getMessage(), "Connection Error!");
}
}
});
layoutComponents();
mainFrame.addModuleToLeftPanel("Teste", this);
}
public void layoutComponents()
{
setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints(); //class that specifies where goes what we want
////////// Insert and Align Labels and Fields //////////
gc.fill = GridBagConstraints.NONE;
// Specify to which side it will stick to
gc.anchor = GridBagConstraints.WEST; // stick to the left hand side
// how much space it takes relatively to other cells, on the X axis.
gc.weighty = 2;
// how much space it takes relatively to other cells, on the Y axis.
gc.weightx = 8;
gc.gridx = 0;
gc.gridy = 1;
add(readFromLabel, gc);
gc.gridx = 1;
add(readFromComboBox, gc);
gc.gridx = 2;
add(refreshReadDataFrom, gc);
gc.gridy = 2;
gc.gridx = 0;
add(writeResultsToNewTableRadio, gc);
gc.gridx = 1;
add(writeToNewTableField, gc);
gc.gridy = 3;
gc.gridx = 0;
add(writeResultsToExistingTableRadio, gc);
gc.gridx = 1;
add(writeToTableComboBox, gc);
gc.gridx = 2;
add(refreshSaveDataTo, gc);
gc.gridy = 4;
gc.gridx = 0;
add(accessSessionTimeThresholdLabelLabel, gc);
gc.gridx = 1;
add(accessSessionTimeThresholdField, gc);
gc.gridy = 5;
gc.gridx = 0;
add(transitionTimeThresholdLabelLabel, gc);
gc.gridx = 1;
add(transitionTimeThresholdField, gc);
gc.gridy = 6;
gc.gridx = 0;
add(smoothLabel, gc);
gc.gridx = 1;
add(smoothCheckBox, gc);
gc.gridy = 7;
gc.gridx = 0;
add(statisticsLabel, gc);
gc.gridx = 1;
add(statisticsCheckBox, gc);
gc.weighty = 15;
gc.anchor = GridBagConstraints.NORTHWEST;
gc.gridy = 8;
add(applyButton, gc);
}
// Should this method be in the API? I think so...
private ImageIcon createIcon(String path)
{
URL url = getClass().getResource(path);
if(url == null)
{
System.err.println("Could not load the icon: " + path);
}
ImageIcon icon = new ImageIcon(url);
return icon;
}
}
You have created a nice cyclic dependency. A MainFrame2 needs a PingPong which needs a MainFrame2 again. That's generally something you should avoid because it causes exactly problems like yours. Leaking this in the constructor is a good indication that you may have done that. It's not always a problem, especially if the other class just stores the reference for later.
The easy fix in your case should be moving the creation of PingPong after that part that initializes the fields that are required.
If you want to get rid of your dependency problem you need to break the cycle. Two options exist: Create PingPong without reference to MainFrame, then give it to MainFrame's constructor. Or the other way: create MainFrame first, then give it to PingPong's constructor.
For a simple implementation you could use a static factory method.
class MainFrame2 {
private MainFrame2() {
super("An awesome piece of software");
// etc.. no modules added here
}
public static MainFrame2 newInstance() {
MainFrame2 result = new MainFrame2();
new PingPong(api, result);
// alternatively something like:
// result.addModuleToLeftPanel("Teste", new PingPong(api))
// add more here
result.updateTheLayoutBecauseThereAreNewModules();
return result;
}
}
class User {
public static void main(String[] args) {
MainFrame2 frame = MainFrame2.newInstance();
// instead of: new MainFrame2();
}
}
Now if you want to solve the problem that adding modules requires changes of MainFrame2 you can expand the factory pattern to use a registry of modules that adds modules without need to know details about the modules.
public class MainFrame2 extends JFrame {
/** An interface that abstracts creation of a "Module" */
public interface ModuleFactory {
public String getTitle();
public Component createModule(Api api);
}
/** A Place to register modules */
public static enum ModuleRegistry {
INSTANCE;
private final List<ModuleFactory> leftModules = new ArrayList<ModuleFactory>();
public void registerModuleForLeftPanel(ModuleFactory factory) {
leftModules.add(factory);
}
private void addModulesTo(MainFrame2 mainFrame2, Api api) {
for (ModuleFactory factory : leftModules) {
mainFrame2.addModuleToLeftPanel(factory.getTitle(), factory.createModule(api));
}
}
}
/** Creates an instance of MainFrame2 with all registered modules */
public static MainFrame2 newInstance() {
MainFrame2 result = new MainFrame2();
ModuleRegistry.INSTANCE.addModulesTo(result, result.api);
return result;
}
// ...
}
Nothing needs to touch MainFrame2 now. You could distribute it as a library and people could add modules like below.
class User {
public static void main(String[] args) {
// static bootstrap code - needs to be run once at the beginning - can be anywhere
// if you want to add modules you can do it here
MainFrame2.ModuleRegistry.INSTANCE.registerModuleForLeftPanel(new ModuleFactory() {
#Override
public String getTitle() {
return "Teste";
}
#Override
public Component createModule(Api api) {
return new PingPong(api);
}
});
// create a mainframe
MainFrame2.newInstance();
}
}
You could in theory put the registration part into each module (in a static { } initializer block) but that causes another problem: The class needs to be loaded in order have a chance to execute code and that's not going to happen if nothing loads that class explicitly.
Related
I have a rectangle, and I am trying to grow it like a graph of some sorts, but it does not show it growing in real time, it just has a white screen then I see a rectangle. Any help would be appreciated, thanks. The code I am having a problem with is under the ¨Animates the bar¨ comment.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Main extends JPanel {
static String[] mainArr;
static int start;
static boolean done = false;
static double datapoint1;
static double datapoint2;
static int jPlaceholder;
public static void main(String[] args) throws Exception {
// Creating the window
JFrame panel = new JFrame();
panel.setSize(450,250);
// Creating the window that shows the animation
JFrame drawingFrame = new JFrame();
drawingFrame.setSize(450,250);
JPanel jp = new JPanel();
jp.setLayout(null);
jp.setBackground(Color.red);
drawingFrame.add(jp);
// Creating all the text fields
JTextField dataTypesTextField = new JTextField("This box is currently not in use. Please do not type anything into this box");
dataTypesTextField.setBounds(50,50, 400,30);
panel.add(dataTypesTextField);
JTextField yearStartTextField = new JTextField("Type in this box what year your data starts in:");
yearStartTextField.setBounds(50,100, 400,30);
panel.add(yearStartTextField);
JTextField yearEndTextField = new JTextField("Type in this box what year your data ends in:");
yearEndTextField.setBounds(50,150, 400,30);
panel.add(yearEndTextField);
// Creating the button to submit the data
JButton enterButton = new JButton("Enter");
enterButton.setBounds(50,200, 100, 30);
panel.add(enterButton);
// =================================== ActionListener for enter button ========================================
enterButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (done==false) {
// Creating the variables to store the data the user just inputted
start = Integer.parseInt(yearStartTextField.getText());
int end = Integer.parseInt(yearEndTextField.getText());
mainArr = new String[end-start+1];
// Gets the data points
dataTypesTextField.setText("Datapoints you will use in order, space between each: ");
done = true;
} else {
// Getting all the data needed
mainArr = dataTypesTextField.getText().split(" ");
double[] datapoints = new double[mainArr.length];
for (int i=0; i<datapoints.length; i++) {
datapoints[i] = Double.parseDouble(mainArr[i]);
}
under here is where I had my problems I am pretty sure, but I could have screwed up somewhere else.
// Animates the bar
for (int i=0; i<datapoints.length-1; i++) {
// Getting all the datapoints
datapoint1 = datapoints[i];
datapoint2 = datapoints[i+1];
int j = 0;
while(j<50) {
j++;
int width = (int) (datapoint1+((datapoint2-datapoint1)/50)*j);
JPanel rectangle = new JPanel();
rectangle.setBackground(Color.black);
rectangle.setBounds(50, 50, width, 30);
jp.add(rectangle);
drawingFrame.setVisible(true);
rectangle.repaint();
System.out.println("The width is: "+width);
at first I thought it was because there was no pause between each ¨frame¨ but it still just shows a white screen, then it shows the rectangle.
try {
Thread.sleep(20);
} catch (Exception exp) {
}
}
}
}
}
});
// =====================================================================================================
// Finishes up both the windows
panel.setLayout(null);
panel.setVisible(true);
}
}
I am trying to play a video from the lists of MRL provided as a String.
The problem is when I try to run the class, a list of panels shows with button, with only one panel working, but the play button does not work and that of other panels.
Although I intentionally left the stop button out because I have not added action listeners to them.
What I want to achieve is, when I run the class, a single video plays, and when I click on the play button of another video, the current video stops and moves to the next video.
I don't know where I have gone wrong.
Here is my code:
public class MediaPlayer extends JPanel {
//Declares our media player component
private EmbeddedMediaPlayerComponent[] mediaplayer;
private String[] mediapath = {""};
private final String vlcpath = "C:\\Program Files (x86)\\VideoLAN\\VLC";
private JPanel video_pnl, control_pnl;
private JButton[] play_btn, stop_btn;
private int but = 0;
public MediaPlayer(String mediapath[]) {
this.mediapath = mediapath;
play_btn = new JButton[1];
stop_btn = new JButton[1];
mediaplayer = new EmbeddedMediaPlayerComponent[1];
int increment = 0;
while (increment < mediapath.length) {
video_pnl = new JPanel();
video_pnl.setLayout(new BorderLayout());
control_pnl = new JPanel();
control_pnl.setLayout(new FlowLayout(FlowLayout.CENTER));
for (int i = 0; i < 1; i++) {
NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), vlcpath);
mediaplayer[i] = new EmbeddedMediaPlayerComponent();
play_btn[i] = new JButton("play");
stop_btn[i] = new JButton("stop");
video_pnl.add(mediaplayer[i], BorderLayout.CENTER);
control_pnl.add(play_btn[i]);
control_pnl.add(stop_btn[i]);
video_pnl.add(control_pnl, BorderLayout.SOUTH);
Handler handler = new Handler();
play_btn[i].addActionListener(handler);
}
add(video_pnl);
increment++;
}
}
private class Handler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == play_btn){
play();
}
}
}
public void play() {
for (int i = 0; i < mediapath.length; i++) {
mediaplayer[i].getMediaPlayer().playMedia(mediapath[i]);
}
}
public static void main(String[] args) {
//Declare and initialize local variables
String[] mediaPath = {"C:\\\\Users\\\\goldAnthony\\\\Desktop\\\\Videos\\\\Whistle.mp4", "C:\\\\Users\\\\goldAnthony\\\\Desktop\\\\Videos\\\\Beyonce_Hello.mp4",
"C:\\Users\\goldAnthony\\Desktop\\Videos\\HansRosling_2012S_480p.mp4","C:\\Users\\goldAnthony\\Desktop\\Videos\\oow2010_2.mp4",
"C:\\Users\\goldAnthony\\Desktop\\Videos\\The_Economic_Environment.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.setLayout(new GridLayout(5, 1));
ourframe.setSize(300, 560);
ourframe.setVisible(true);
mediaplayer.play();
ourframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
control_pnl.add(play_btn[i]);
control_pnl.add(stop_btn[i]);
video_pnl.add(control_pnl, BorderLayout.SOUTH);
Handler handler = new Handler();
play_btn[i].addActionListener(handler);
}
add(video_pnl);
increment++;
}
}
private class Handler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == play_btn){
play();
}
}
}
public void play() {
for (int i = 0; i < mediapath.length; i++) {
mediaplayer[i].getMediaPlayer().playMedia(mediapath[i]);
}
}
public static void main(String[] args) {
//Declare and initialize local variables
String[] mediaPath = {"C:\\\\Users\\\\goldAnthony\\\\Desktop\\\\Videos\\\\Whistle.mp4", "C:\\\\Users\\\\goldAnthony\\\\Desktop\\\\Videos\\\\Beyonce_Hello.mp4",
"C:\\Users\\goldAnthony\\Desktop\\Videos\\HansRosling_2012S_480p.mp4","C:\\Users\\goldAnthony\\Desktop\\Videos\\oow2010_2.mp4",
"C:\\Users\\goldAnthony\\Desktop\\Videos\\The_Economic_Environment.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.setLayout(new GridLayout(5, 1));
ourframe.setSize(300, 560);
ourframe.setVisible(true);
mediaplayer.play();
ourframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
The BorderLayout.CENTER of your JPanel video_pnl can only hold a single component. After your constructor's loop concludes, it references the last mediaplayer[i] added. In your listener, you can use CardLayout to change panels or update a single panel.
Your event handler has this:
if(e.getSource() == play_btn){
e.getSource() will return the button that was clicked. However, play_btn is an array not a button. You are therefore comparing an array instance and a button instance for equality and that will always be false.
One way to achieve what you want is to use action commands:
play_btn[i] = new JButton("play");
play_btn[i].setActionCommand("play");
You can then change the test in your event handler to this:
if(e.getActionCommand().equals("play") {
By the way, this problem is really nothing at all to do with vlcj.
i am trying to access global variable of a class from another class the glass is giving me null value instead of enter value during action performed`
package com.audit;
public class panel extends JPanel {
String shost;
String suser;
String spass;
int sport;
public int getsport() {
return this.sport;
}
public String getshost() {
return this.shost;
}
public String getsuser() {
return this.suser;
}
public String getspass() {
return this.spass;
}
public panel(){
Dimension size = getPreferredSize();
size.width = 680;
size.height = 600;
setPreferredSize(size);
setBorder(BorderFactory.createTitledBorder("Linux Audit"));
setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
JLabel labelhost = new JLabel("Host ");
JLabel labeluser = new JLabel("User name ");
JLabel labelpass = new JLabel("Password ");
JLabel labelport = new JLabel("Port ");
final JTextField host = new JTextField(15);
final JTextField user = new JTextField(15);
final JTextField pass=(JTextField)new JPasswordField(15);
final JTextField port = new JTextField(15);
final JButton start = new JButton("Start Audit");
//layout design
gc.anchor = GridBagConstraints.LINE_END;
gc.weightx = 0.5;
gc.weighty = 0.5;
gc.gridx=0;
gc.gridy=0;
add(labelhost,gc);
gc.gridx=0;
gc.gridy=1;
add(labeluser,gc);
gc.gridx=0;
gc.gridy=2;
add(labelpass,gc);
gc.gridx=0;
gc.gridy=3;
add(labelport,gc);
gc.anchor = GridBagConstraints.LINE_START;
gc.gridx=1;
gc.gridy=0;
add(host,gc);
gc.gridx=1;
gc.gridy=1;
add(user,gc);
gc.gridx=1;
gc.gridy=2;
add(pass,gc);
gc.gridx=1;
gc.gridy=3;
add(port,gc);
gc.anchor = GridBagConstraints.FIRST_LINE_START;
gc.weighty=10;
gc.gridx=1;
gc.gridy=4;
add(start,gc);
//startaudit action
start.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
String shost = host.getText();
String suser = user.getText();
String spass = pass.getText();
String sportb = port.getText();
int sport = Integer.parseInt(sportb);
sshConnection s = new sshConnection();
s.Connection();
/*System.out.println(shost);
System.out.println(suser);
System.out.println(spass);
System.out.println(sport);*/
}
});
}
}
in above i am trying to fetch the value of global variables
String shost;
String suser;
String spass;
int sport;
in another class
///another class
public class sshConnection {
public void Connection(){
String sshhost = new panel().getshost();
String sshuser = new panel().getsuser();
int sshport = new panel().getsport();
String sshpass = new panel().getspass();
System.out.println(sshhost);
System.out.println(sshuser);
System.out.println(sshport);
System.out.println(sshpass);
}
}
i am getting null values instead of inserted values at the time of execution.please solve the problem, i know its very basic but i m beginer.so plz help
thanks
In the panel class, shost, suser, etc., aren't set to anything until you click on the Start Audit button. But Connection constructs a 4 new panel objects. Those won't be the same panel objects that you clicked the button on. I think what you want to do is change your Connection method so that it takes a panel argument:
public void Connection(panel p){
String sshhost = p.getshost();
String sshuser = p.getsuser();
...
and change the s.Connection call inside your listener to
s.Connection (panel.this);
so that Connection knows what panel it's supposed to be working with.
Or, a better design might be to have Connection take the three strings and the integer as arguments, and not bother with getshost(), etc., at all.
You're creating multiple instances of panel in sshConnection#Connection whose fields are null.
The values from the existing instance of panel need to be used. I suggest simply pass them as parameters instead
public void performConnection(String sshHost, String sshUser, int sshPort, String sshPass){
...
}
Java Naming Conventions show that classes start with a uppercase letter, e.g. SshConnection while methods start with a lowecase letter, e.g. performConnection. Read Naming Conventions
I'm creating a program that reads data from a file, displays it on a GUI that has a JList and JButtons. I am trying to write it with CardLayout so the appropriate JPanel can be displayed when an item is selected from the JList or a JButton is clicked (i.e. next, previous, first and last). I am able to successfully read from the file and display data to the GUI. I've run into 2 problems and I've tried searching online for answers but cant seem to figure it out:
1) How do I get the JPanels to switch using CardLayout?
2) How do I get the data to be displayed in the GUI in text fields when a user clicks an item from the JList? The JList does appear and my ListSelectionListener is working because when I click on a particular item, it will print to the console (as a test).
If I comment out all of the JPanels except for 1, then it is correctly displayed but when I place all of them, then it does not switch.
So far, I have this for my ListSelectionListener (as an inner class):
public class CancerSelectionListener implements ListSelectionListener {
#Override
public void valueChanged(ListSelectionEvent e) {
Integer selection = (Integer)(((JList) e.getSource()).getSelectedIndex());
if(selection == 0) {
System.out.println("blah"); // works
// switch to the corresponding JPanel in CardLayout
}
}
}
String[] tester;
String teste;
listModel = new DefaultListModel();
for(int i = 0; i < 36; i++) {
tester = _controller.readCancer(i); // reads from the file, this part works!
teste = tester[0];
listModel.addElement(teste);
}
cancerList = new JList(listModel);
cancerList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
cancerList.setSelectedIndex(-1);
cancerList.setVisibleRowCount(5);
cancerListScroller = new JScrollPane(cancerList);
CardLayout myCardLayout;
myCardLayout = new CardLayout();
mainPanel2.setLayout(myCardLayout);
myCardLayout.show(mainPanel2, "test");
CancerPanels.aplPanel apl = new CancerPanels.aplPanel();
CancerPanels.fcPanels fc = new CancerPanels.fcPanels();
CancerPanels.vhlsPanels vhls = new CancerPanels.vhlsPanels();
CancerPanels.pdgPanels pdg = new CancerPanels.pdgPanels();
CancerPanels.cebpaPanels cebpa = new CancerPanels.cebpaPanels();
mainPanel2.add(apl.aplReturn(), "test");
mainPanel2.add(fc.fcReturn());
mainPanel2.add(vhls.vhlsReturn());
mainPanel2.add(pdg.pdgReturn());
mainPanel2.add(cebpa.cebpaReturn());
// I have 37 JPanels that are placed in the JPanel that uses CardLayout but I didn't post all of them as it would take up lots of space
The data for each JPanel is populated from static inner classes in the CancerPanels class (only showing 1 as each is very long!)
public class CancerPanels extends CancerGUI {
static JPanel cards;
static CancerController _cons = new CancerController();
static String[] cancerData;
static JScrollPane treatmentsScroller = new JScrollPane(txtTreatments, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
static JScrollPane causesScroller = new JScrollPane(txtCauses, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
static JScrollPane symptomsScroller = new JScrollPane(txtSymptoms, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
public static class aplPanel extends JPanel {
public JPanel aplReturn() {
treatmentsScroller.setViewportView(txtTreatments);
txtTreatments.setEditable(false);
causesScroller.setViewportView(txtCauses);
txtCauses.setEditable(false);
symptomsScroller.setViewportView(txtSymptoms);
txtSymptoms.setEditable(false);
cards = new JPanel(new GridLayout(6,1));
cancerData = _cons.readCancer(0);
resultName.setText(cancerData[0]);
txtSymptoms.setText(cancerData[1]);
txtCauses.setText(cancerData[2]);
txtTreatments.setText(cancerData[3]);
resultRate.setText(cancerData[4]);
resultPrognosis.setText(cancerData[5]);
cards.add(resultName);
cards.add(symptomsScroller);
cards.add(causesScroller);
cards.add(treatmentsScroller);
cards.add(resultRate);
cards.add(resultPrognosis);
return cards;
}
}
Edit:
Here is my most recent attempt. I can scroll through the JList but it doesn't properly display the correct corresponding JPanel (in fact it doesn't display anything, except whenever I click the last button, I don't know why that button works). I successfully managed to place an ItemListener on a JComboBox but ultimately, I want the CardLayout to work. Our instructor provided us with sample code to use but when I try it, the JPanels do not switch (or if they do they're hidden, not sure why).
Each of my listeners are public inner classes in the overall CancerGUI class.
public CancerGUI() {
CancerPanels.aplPanel apl = new CancerPanels.aplPanel();
CancerPanels.fcPanels fc = new CancerPanels.fcPanels();
CancerPanels.vhlsPanels vhls = new CancerPanels.vhlsPanels();
// more than 30 JPanels that I add to the JPanel that uses CardLayout, so I only posted 3
// each of them uses the GridLayout
mainPanel2 = new JPanel(new CardLayout());
mainPanel2.add(apl.aplReturn(), "1");
mainPanel2.add(fc.fcReturn(), "2");
mainPanel2.add(vhls.vhlsReturn(), "3");
CancerActionButtons _cab = new CancerActionButtons();
btnNext = new JButton("Next");
btnPrevious = new JButton("Previous");
btnFirst = new JButton("First");
btnLast = new JButton("Last");
btnClear = new JButton("Clear");
btnNext.addActionListener(_cab);
btnPrevious.addActionListener(_cab);
btnFirst.addActionListener(_cab);
btnLast.addActionListener(_cab);
CancerItemListener _item = new CancerItemListener(); // this listener works!
renalC.addItemListener(_item);
skinC.addItemListener(_item);
brainC.addItemListener(_item);
bladderC.addItemListener(_item);
ovarianC.addItemListener(_item);
pancC.addItemListener(_item);
breastC.addItemListener(_item);
String[] tester;
String teste;
listModel = new DefaultListModel();
for(int i = 0; i < 36; i++) {
tester = _controller.readCancer(i);
teste = tester[0];
listModel.addElement(teste);
}
cancerList = new JList(listModel);
cancerList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
cancerList.setSelectedIndex(-1);
cancerList.setVisibleRowCount(5);
cancerListScroller = new JScrollPane(cancerList);
ListSelection _list = new ListSelection();
cancerList.addListSelectionListener(_list);
JScrollPane treatmentsScroller = new JScrollPane(txtTreatments, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
treatmentsScroller.setViewportView(txtTreatments);
JScrollPane causesScroller = new JScrollPane(txtCauses, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
causesScroller.setViewportView(txtCauses);
JScrollPane symptomsScroller = new JScrollPane(txtSymptoms, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
symptomsScroller.setViewportView(txtSymptoms);
public class ListSelection implements ListSelectionListener {
#Override
public void valueChanged(ListSelectionEvent e) {
String selection = (String)(((JList)e.getSource()).getSelectedValue());
((CardLayout) mainPanel2.getLayout()).show(mainPanel2, selection);
((CardLayout) mainPanel2.getLayout()).show(mainPanel2, selection);
}
}
public class CancerActionButtons implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
switch(e.getActionCommand()) {
case "First":
((CardLayout) mainPanel2.getLayout()).first(mainPanel2);
cancerCount = 1;
break;
case "Last":
((CardLayout) mainPanel2.getLayout()).last(mainPanel2);
cancerCount = 11;
break;
case "Previous":
((CardLayout) mainPanel2.getLayout()).previous(mainPanel2);
cancerCount--;
cancerCount = cancerCount < 1 ? 11 : cancerCount;
break;
case "Next":
((CardLayout) mainPanel2.getLayout()).next(mainPanel2);
cancerCount++;
cancerCount = cancerCount > 11 ? 1 : cancerCount; //
break;
}
cancerList.setSelectedIndex(cancerCount-1);
}
}
/**
* Inner class that responds to any user interaction with a JComboBox for
* general types of cancers.
*/
public class CancerItemListener implements ItemListener {
#Override
public void itemStateChanged(ItemEvent e) {
JPanel showPanel = new JPanel();
if(e.getStateChange() == ItemEvent.SELECTED) {
String selection = (String) e.getItem();
if(selection.equalsIgnoreCase("skin cancer")) {
CancerPanels.skin skin = new CancerPanels.skin();
showPanel = skin.skinReturn();
} else if (selection.equalsIgnoreCase("bladder cancer")) {
CancerPanels.bladder bladder = new CancerPanels.bladder();
showPanel = bladder.bladderReturn();
} else if (selection.equalsIgnoreCase("pancreatic cancer")) {
CancerPanels.pancreatic pancreatic = new CancerPanels.pancreatic();
showPanel = pancreatic.returnPancreatic();
} else if (selection.equalsIgnoreCase("renal cancer")) {
CancerPanels.renal renal = new CancerPanels.renal();
showPanel = renal.returnRenal();
} else if (selection.equalsIgnoreCase("ovarian cancer")) {
CancerPanels.ovarian ovarian = new CancerPanels.ovarian();
showPanel = ovarian.ovarianReturn();
} else if (selection.equalsIgnoreCase("breast cancer")) {
CancerPanels.breast breast = new CancerPanels.breast();
showPanel = breast.returnBreast();
} else if (selection.equalsIgnoreCase("brain cancer")) {
CancerPanels.brain brain = new CancerPanels.brain();
showPanel = brain.returnBrain();
} else if (selection.equalsIgnoreCase("von hippel-lindau syndrome")) {
CancerPanels.vhlsPanels vhls = new CancerPanels.vhlsPanels();
showPanel = vhls.vhlsReturn();
}
JOptionPane.showMessageDialog(null, showPanel);
}
}
}
Seperate class where the JPanels are made before being added to CardLayout:
public class CancerPanels extends CancerGUI {
static String name;
static JPanel cards;
static CancerController _cons = new CancerController();
static String[] cancerData;
static JScrollPane treatmentsScroller = new JScrollPane(txtTreatments, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
static JScrollPane causesScroller = new JScrollPane(txtCauses, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
static JScrollPane symptomsScroller = new JScrollPane(txtSymptoms, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
public static class aplPanel extends JPanel {
public JPanel aplReturn() {
treatmentsScroller.setViewportView(txtTreatments);
txtTreatments.setEditable(false);
causesScroller.setViewportView(txtCauses);
txtCauses.setEditable(false);
symptomsScroller.setViewportView(txtSymptoms);
txtSymptoms.setEditable(false);
cards = new JPanel(new GridLayout(6,1));
cancerData = _cons.readCancer(0);
resultName.setText(cancerData[0]);
txtSymptoms.setText(cancerData[1]);
txtCauses.setText(cancerData[2]);
txtTreatments.setText(cancerData[3]);
resultRate.setText(cancerData[4]);
resultPrognosis.setText(cancerData[5]);
cards.add(resultName);
cards.add(symptomsScroller);
cards.add(causesScroller);
cards.add(treatmentsScroller);
cards.add(resultRate);
cards.add(resultPrognosis);
return cards;
}
In essence what you are trying to do is to change the state of one class from another.
How this is done with Swing GUI's is no different for how it is done for non-GUI programs: one class calls the public methods of another class.
One key is to have wiring to allow this to occur which means references for one class needs to be available to the other class so that appropriate methods can be called on appropriate references. The devil as they say is in the details.
"1) How do I get the JPanels to switch using CardLayout?" -- So the class that holds the CardLayout could for instance have the public methods, next(), previous(), and perhaps show(SOME_STRING_CONSTANT) or some other swapView(...) method.
"2) How do I get the data to be displayed in the GUI in text fields when a user clicks an item from the JList?" -- This will involve the use of listeners -- the class holding the JTextFields will listen for notification from the class that holds the JList, and when notified gets the necessary information from the list-displaying class. A PropertyChangeListener could work well here.
e.g.,
public class CancerSelectionListener implements ListSelectionListener {
private CardDisplayingView cardDisplayingView = null;
public CancerSelectionListener(CardDisplayingView cardDisplayingView) {
this.cardDisplayingView = cardDisplayingView;
}
#Override
public void valueChanged(ListSelectionEvent e) {
int selection = ((JList) e.getSource()).getSelectedIndex();
if(selection == 0) {
if (cardDisplayingView != null) {
cardDisplayingView.swapView(...);
}
}
}
}
I have an array of ImageIcons, and I can drag and drop other Icons onto them to replace them. When I hit a button a new JFrame is created from the array of ImageIcons.
If I do this without dragging any other Icons on to the original array, it works. However once I drop a different imageicon into the array, I get an error when I hit the button.
I'm just wondering if this is even possible at all?
I've considered other approaches of using a JTable for the top panel, or trying to use an ArrayList, but I'm not too comfortable using them. If anyone has any opinion on how this should be done, please let me know!
I shortened this example as much as possible(at 200 lines it's not exactly short). But this is exactly what my problem is...
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Properties;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.*;
import java.lang.String.*;
public class test extends JFrame {
JPanel storyPanel, rightStoryPanel, leftStoryPanel,centerStoryPanel, imageSelectPanel, CreatePanel, storyFramePanel, storycard;
TransferHandler handler;
MouseListener listener;
CardLayout cl3;
JLabel[] storyLabel = new JLabel[20];
JButton playStory, nextStory,addtargetbutton;
int count, start, i, j,stop, start1;
public test(){
CreatePanel = new JPanel(new BorderLayout());
storyPanel = new JPanel(new BorderLayout());
rightStoryPanel = new JPanel(new GridLayout(6,1));
leftStoryPanel = new JPanel(new GridLayout(6,1));
centerStoryPanel = new JPanel();
JScrollPane centerscroll = new JScrollPane(centerStoryPanel);
addtargetbutton = new JButton("Add Another Image Slot");
addtargetbutton.addActionListener(new createbuttons());
playStory = new JButton("Play your story!");
leftStoryPanel.add(playStory);
playStory.addActionListener(new createbuttons());
leftStoryPanel.add(addtargetbutton);
imageSelectPanel = new JPanel(new FlowLayout());
storyPanel.add(rightStoryPanel,BorderLayout.EAST);
storyPanel.add(leftStoryPanel, BorderLayout.WEST);
storyPanel.add(centerscroll, BorderLayout.CENTER);
CreatePanel.add(storyPanel, BorderLayout.NORTH);
CreatePanel.add(imageSelectPanel, BorderLayout.CENTER);
count= 3;
start= 0;
stop = 0;
start1= 0;
ImageSelection();
targetpanel();
getContentPane().add(CreatePanel);
}//End Create}
public void ImageSelection(){
int i = 0;
int j = 0;
TransferHandler handler = new TransferHandler("icon") {
#Override
public boolean canImport(TransferSupport support) {
return super.canImport(support)
&& support.getComponent().getParent() != imageSelectPanel;}
};
MouseListener listener = new MouseAdapter(){
public void mousePressed(MouseEvent e){
JComponent c = (JComponent) e.getSource();
TransferHandler handler = c.getTransferHandler();
handler.exportAsDrag(c, e, TransferHandler.COPY);
System.out.println(e);}
}; // Drag & Drop mouse
try{
String imagePath = "";
BufferedImage[] CreateImagesFromDB = new BufferedImage[40];
JLabel[] ImageLabel = new JLabel[40];
while (count > start1) {
i = 1;
CreateImagesFromDB[i] = ImageIO.read(new File("one.jpg"));
ImageLabel[i] = new JLabel(new ImageIcon(CreateImagesFromDB[i]));
imageSelectPanel.add(ImageLabel[i]);
ImageLabel[i].addMouseListener(listener);
ImageLabel[i].setTransferHandler(handler);
i++;
start1++;
}
}//EndTRY
catch(Exception e){
System.out.println("CATCH"+ e);
}//end catch
}
public void targetpanel(){
TransferHandler handler = new TransferHandler("icon") {
#Override
public boolean canImport(TransferSupport support) {
return super.canImport(support)
&& support.getComponent().getParent() != imageSelectPanel;
}
};
MouseListener listener = new MouseAdapter(){
public void mousePressed(MouseEvent e){
JComponent c = (JComponent) e.getSource();
TransferHandler handler = c.getTransferHandler();
handler.exportAsDrag(c, e, TransferHandler.COPY);
}
};
BufferedImage[] storyImages = new BufferedImage[20];
try{
while(count > start){
storyImages[j] = ImageIO.read(new File("TargetImg.jpg"));
storyLabel[j] = new JLabel(new ImageIcon(storyImages[j]));
centerStoryPanel.add(storyLabel[j]);
storyLabel[j].addMouseListener(listener);
storyLabel[j].setTransferHandler(handler);
j++;
start++;
centerStoryPanel.revalidate();
//validate();
System.out.println("J in Loop is: "+j );
}//end while Loop
//System.out.println("J is equalto: "+j);
} catch(Exception e) {};
}// End TargetPanel
public void storyFrame (JLabel[] storyArray){
int i = 0;
storyFramePanel = new JPanel(new BorderLayout());
nextStory = new JButton("Next Image");
nextStory.addActionListener(new createbuttons());
storycard = new JPanel();
cl3 = new CardLayout();
storycard.setLayout(cl3);
JPanel[] storyImgPanel = new JPanel[20];
JLabel[] imglab = new JLabel[20];
storyImgPanel[i]= new JPanel();
while( i < j){
storyImgPanel[i].add(new JLabel(storyArray[i].getIcon()));
storycard.add(storyImgPanel[i], ""+i);
i++;
}
JFrame story = new JFrame("Story");
story.setSize(500,500);
storyFramePanel.add(storycard, BorderLayout.CENTER);
storyFramePanel.add(nextStory, BorderLayout.EAST);
story.add(storyFramePanel);
cl3.show(storycard, "1");
story.setVisible(true);
}
public static void main(String[] args){
System.out.println("Application Running");
JFrame mainframe = new test();
mainframe.setTitle("Let Me Know!");
mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainframe.setSize(1000,1000);
mainframe.setVisible(true);
}
class createbuttons implements ActionListener{
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == addtargetbutton){
count++;
targetpanel();
System.out.println("Trying to add another TargetImg, count = "+count);
}
if(e.getSource() == playStory){
storyFrame(storyLabel);
}
if(e.getSource() == nextStory){
cl3.next(storycard);
System.out.println("button pressed");
}
}
}
}
I figured it out:
Firstly, each time you call targetpanel(), you create a new instance of storyLabel, but then you are behaving like you have it already populated from the previous calls. So the result is:
first call:
storyLabel[0] = something;
storyLabel[1] = something;
storyLabel[2] = something;
storyLabel[3] = null;
storyLabel[4] = null.... etc
second call (you added another image slot):
storyLabel[0] = null;
storyLabel[1] = null;
storyLabel[2] = null;
storyLabel[3] = something;
storyLabel[4] = null.... etc
So when you use this array in the storyboard, you get NullPointerException.
You need to create the array only once. So remove storyLabel = new JLabel[20] from targetpanel() and initialize the array in the constructor, or even better in the declaration:
...
CardLayout cl3;
JLabel[] storyLabel = new JLabel[20];
JButton playStory, nextStory, addtargetbutton;
...
Secondly, when displaying the images using the storyFrame(), you change the parent of the supplied JLabels and they subsequently disappear from the storyPanel. You must create new instances of JLabel for the storyboard.
In storyFrame(), instead of
storyImgPanel[i].add(storyArray[i]);
write
storyImgPanel[i].add(new JLabel(storyArray[i].getIcon()));
If I do all this the program is working.
There's not enough in your code to really give you a good answer. One of these two lines:
storyImgPanel[i].add(storyArray[i]);
storycard.add(storyImgPanel[i], ""+i);
would be my guess. The component you're adding in is null (either storyArray[i] or storyImgPanel[i]. Probably the first, since you're creating the second in the loop.
If you could post all your code, it would be easier. Or, (preferably) post a self-contained small example.