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.
Related
The two methods listed below are from two separate classes, one that builds a GUI and the other that handles the game logic (as per request). My question is am I able to interact with the buttons created in the for loop from the other class?
public void colorChange()
{
if (play() == true){
button.setBackground(Color.red);
}
else {
button.setBackground(Color.black);
}
}
public JPanel makeInnerJPanel()
{
JPanel inner = new JPanel((new GridLayout(5, 5)));
String[] items = new String[] {"","","","","","","","","","","","","","","","","","",
"","","","","","",""};
for (int i = 0; i<items.length; i++){
JButton button = new JButton(items[i]);
button.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e){
}
}
);
inner.add(button);
}
return inner;
}
You could make the variables public
public JButton[] button;
access them from another class
CLASSNAME.button;
I have 20 loop-generated JToggleButtons and I need to count how many of them are active.
private void generarBotones(){
JToggleButton b;
this.panelCuerpo.setLayout(new GridLayout(4,5));
for(int i = 1; i<=20; i++){
b = new JToggleButton();
b.setText(String.valueOf(i));
this.panelCuerpo.add(b);
b.addActionListener(new ActionListener() {
int clicks = 0;
#Override
public void actionPerformed(ActionEvent ae2){
clicks = clicks + 1;
System.out.println(clicks);
}
public void setCantidadBoletas(int clicks){
cantidadBoletas = clicks;
}
});
}
}
The problem here is that it counts how many times is EACH ONE of them clicked instead of count how many of them are selected.
PS. I tried to use (b.isSelected()) but b needs to be final to access it so it wasn't the solution.
If you declare the JToggleButton inside the loop, you can make it final:
for (int i = 1; i<=20; i++) {
JToggleButton b = new JToggleButton();
Then you can use b.isSelected:
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (b.isSelected())
clicks++;
else
clicks--;
}
});
}
clicks would have to be a class variable.
Suggestions:
Create a field, JToggleButton[] toggleButtons = new JToggleButton[20]
Or use an ArrayList if you so choose
In your for loop create your JToggleButton and assign it to the proper array item.
In the ActionListener simply iterate through the array, counting how many of its JToggleButton items are selected.
You're done.
Create a class attribute that will count the selected toggles:
private int selectedCount;
Initialize the counter to 0 in your constructor:
this.selectedCount = 0;
Increment or decrement the counter every time the state of a toggle changes:
b.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent ev) {
if (ev.getStateChange() == ItemEvent.SELECTED){
YourClass.this.selectedCount++;
} else if (ev.getStateChange() == ItemEvent.DESELECTED){
YourClass.this.selectedCount--;
}
System.out.println(YourClass.this.selectedCount);
}
});
There are many ways to get this done and the best way depends on the rest of your code. I tried to keep it as close to yours.
You can just declare the buttons as final inside the loop and keep a global count of the number of buttons selected, which will be modified in the ActionListener:
public class ButtonsCount extends JFrame {
int clicks = 0;
ButtonsCount() {
JLabel label = new JLabel("0");
JPanel buttonsPanel = new JPanel(new GridLayout(4,5));
for(int i = 1; i <= 20; i++) {
final JToggleButton b = new JToggleButton();
b.setText(String.valueOf(i));
buttonsPanel.add(b);
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae2){
if (b.isSelected())
label.setText(String.valueOf(++clicks));
else
label.setText(String.valueOf(--clicks));
}
});
}
add(buttonsPanel);
add(label, BorderLayout.PAGE_END);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
new ButtonsCount();
}
}
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'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.