I have a problem with the JList. Whenever i remove items from it, the list does not update it's appearance so items remain there and become uncheckable.
Here is code:
DefaultListModel listModel = new DefaultListModel();
JList figureListBox = new JList(listModel);
figureListBox.setBounds(5, 20, 240, 300);
figureListBox.setBackground(Color.WHITE);
figureListBox.setBorder(BorderFactory.createLineBorder(Color.BLACK));
figureListBox.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
figureListBox.setLayoutOrientation(JList.VERTICAL);
figureListBox.setVisibleRowCount(10);
JButton deleteFigureButton = new JButton("Delete");
deleteFigureButton.setBounds(5, 305, 240, 25);
deleteFigureButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent actionEvent) {
if(currentFigure != -1) {
listModel.remove(currentFigure);
currentFigure = -1;
}
}
});`
Repaint and revalidate doesn't work, as well as updateUI()
Here is a screenshot of how it looks like
Here is the NetBeans code -->
//set data to jlist
public void setList() {
String[] listData = {"list1", "list2", "list3", "list3", "list3", "list3", "list3", "list3"};
jList1.setListData(listData);
}
//delete data from jlist
public String[] delList() {
ListModel<String> beforDeleteDataList = jList1.getModel();
String[] newDataList = new String[beforDeleteDataList.getSize() - 1];
int beforDeleteDataListIndex = 1;
try {
for (int i = 0; i < (beforDeleteDataList.getSize()); i++) {
newDataList[i] =
beforDeleteDataList.getElementAt(beforDeleteDataListIndex);
beforDeleteDataListIndex++;
}
} catch (Exception e) {
e.printStackTrace();
}
return newDataList;}
//delete button action
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
jList1.setListData(delList());
}
From your comment:
list does update after moving a window.
Verify whether you call setVisible() after adding components to the JPanel(if using it).
Check this if it relates to your problem.
JPanel doesn't update until resize Jframe
Also post your full code.
Related
I have created 2 JLists 'addGroupList' and 'addApkList'. I am adding elements to addGroupList using model.addElement(arrayList1.get(arrayList1.size()-1)); the thing is, I want to update addApkList based on selected value of addGroupList. For this, I'm trying to add event listener so that I can act upon something when list item is selected but the event is not trigerring.
What do I do to accomplish this?
following is the code I'm using.
model1 = new DefaultListModel();
model2 = new DefaultListModel();
addApkList = new JList(model1);
addGroupList = new JList(model2);
scrollPane1 = new JScrollPane();
scrollPane1.setViewportView(addApkList);
scrollPane2 = new JScrollPane();
scrollPane2.setViewportView(addGroupList);
this way i've defined JList.
in following way i've added elements to addGroupList
model1.addElement(arrayList1.get(arrayList1.size()-1));
and in following way I've added listener to it.
addGroupList.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent lse) {
if (!lse.getValueIsAdjusting()) {
System.out.println("Selection trigerred");
}
}
});
There doesnt seem to happen any change with this code. what m i doing wrong?
I've also tried following
model1.addListDataListener(new ListDataListener() {
#Override
public void intervalAdded(ListDataEvent lde) {
System.out.println("ddddddddddd");
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public void intervalRemoved(ListDataEvent lde) {
System.out.println("ddddddddddd");
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public void contentsChanged(ListDataEvent lde) {
System.out.println("ddddddddddd");
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
});
In following way i've added elements to addGroupList
model1.addElement(arrayList1.get(arrayList1.size()-1));
No you haven't. model1 is the list model for addApkList not addGroupList:
addApkList = new JList(model1);
It should be model2.addElement(arrayList1.get(arrayList1.size()-1)).
In any case I suspect you're expecting for a ListSelectionEvent being fired when you just simply add an item to list model. That won't happen. You need to set the added item as the selected one:
Object item = arrayList1.get(arrayList1.size()-1);
model2.addElement(item);
addGroupList.setSelectedValue(item, true);
Take a look to JList.setSelectedValue(Object anObject, boolean shouldScroll) for further details.
I have created 2 JLists 'addGroupList' and 'addApkList'. I am adding
elements to addGroupList using
model.addElement(arrayList1.get(arrayList1.size()-1)); the thing is, I
want to update addApkList based on selected value of addGroupList. For
this, I'm trying to add event listener so that I can act upon
something when list item is selected but the event is not trigerring.
What do I do to accomplish this? following is the code I'm using.
for example
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class Testing extends JFrame {
private static final long serialVersionUID = 1L;
private DefaultListModel listModel = new DefaultListModel();
private DefaultListModel listModelEmpty = new DefaultListModel();
private JList list = new JList(listModel);
private JList listEmpty = new JList(listModelEmpty);
private JPanel panel = new JPanel(new GridLayout(1, 1));
private int currentSelectedRow = 0;
private int xX = 0;
public Testing() {
setLocation(400, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
for (int x = 0; x < 9; x++) {
listModel.addElement("" + x);
xX++;
}
JScrollPane sp = new JScrollPane(list);
list.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent lse) {
if (!lse.getValueIsAdjusting()) {
System.out.println("Selection trigerred");
}
}
});
JScrollPane spEmpty = new JScrollPane(listEmpty);
panel.add(spEmpty);
panel.add(sp);
add(panel, BorderLayout.CENTER);
JButton btn1 = new JButton("Reset Model CastingModel");
add(btn1, BorderLayout.NORTH);
btn1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
//list.clearSelection();
DefaultListModel model = (DefaultListModel) list.getModel();
model.removeAllElements();
for (int x = 0; x < 9; x++) {
model.addElement("" + (x + xX));
xX++;
}
list.setModel(model);
}
});
JButton btn2 = new JButton("Reset Model directly from Model");
add(btn2, BorderLayout.SOUTH);
btn2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
//list.clearSelection();
listModel.removeAllElements();
for (int x = 0; x < 9; x++) {
listModel.addElement("" + (x + xX));
xX++;
}
}
});
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Testing().setVisible(true);
}
});
}
}
I have the following piece of code to create a JList:
rightPanel.add(Box.createRigidArea(new Dimension(20, 20)));
final JList list = new JList(nameData);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setLayoutOrientation(JList.VERTICAL);
list.setVisibleRowCount(5);
JScrollPane listScroller = new JScrollPane(list);
listScroller.setPreferredSize(new Dimension(250, 80));
listScroller.setAlignmentX(LEFT_ALIGNMENT);
rightPanel.add(listScroller);
And I have this code for a listSelectionListener() to disable a button, when an item in the list isn't selected:
list.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == false) {
if (list.getSelectedIndex() == -1) {
//No selection.
deleteConfirmButton.setEnabled(false);
} else {
//Selection.
deleteConfirmButton.setEnabled(true);
index = list.getSelectedIndex();
}
}
}
});
But whether an item in the list is selected or not, the state for the button doesn't change. What should I do?
Your deleteConfirmButton disable-enable logic is not correct. At first you need to disable. At the selection of list you should enable and at the click on deleteConfirmButton button you shoudl again disable. Read the comment of following code.
final JButton deleteConfirmButton = new JButton("Kustuta");
deleteConfirmButton.setEnabled(false); //Disable here
deleteConfirmButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
deleteConfirmButton.setEnabled(false);//Disable here
}
});
list.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
deleteConfirmButton.setEnabled(true);//Enable here
}
});
Assuming deleteConfirmButton is inside a JPanel named rightPanel, call the repaint and revalidate methods to paint the button again.
if (list.getSelectedIndex() == -1) {
//No selection.
deleteConfirmButton.setEnabled(false);
} else {
//Selection.
deleteConfirmButton.setEnabled(true);
index = list.getSelectedIndex();
}
rightPanel.repaint();
rightPanel.revalidate();
I've 2 panels. One where the user inserts the data and the other with a JTable where the results will be shown.
My problem is when the user press's the ok (in my case apply) JButton the data is computed but is not shown on the JTable, nothing changes in the JTable.
For my JTable I'm using the Bean Table Model from tips4Java (http://tips4java.wordpress.com/2008/11/27/bean-table-model/).
One weird thing is if I send data (lets call this data 'A') to the table when the program starts it is shown on the table and if later on I try to update the table, the table does not update. But when I don't send data to the table at start up but try to update/send the table with data 'A' it does not update.
So my question is, why is not the JTable showing whatever data I send to?
Here's my code:
JButton listenere that starts the processing and sends the data to the table:
crashForm.setFormListener(new FormListener() {
#Override
public void formEvent(OptionsFormEvent oe) {
String readTable = oe.getReadFromTable();
int access = oe.getAccess();
int transition = oe.getTransition();
boolean smooth = oe.isTrainCrash();
ArrayList<String> allTrains = new ArrayList<>();
List crashedTrainList = new ArrayList<>();
try {
allTrains = controller.getUniqueTrains(controller.connectServer(), readTable, "trainid");
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "An error occured while getting trains data\n"
+ "Error description: " + ex.getMessage(), "Error",
JOptionPane.ERROR_MESSAGE);
}
try {
for (int i = 0; i < allTrains.size(); i++)
{
ArrayList<Train> trainDataList = new ArrayList<>();
ArrayList<Train> crashedProccessedData = new ArrayList<>();
String query = "the sql query...";
trainDataList = controller.getTrainData(controller.connectServer(), readTable, query);
crashedProccessedData = controller.detectCrash(access, transition, trainDataList);
crashedTrainList.addAll(crashedProccessedData);
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "An error occured while detecting a crash.\n"
+ "Error description: " + ex.getMessage(), "Error",
JOptionPane.ERROR_MESSAGE);
}
System.out.println("Total crashes detected:" + crashedTrainList.size());
tablePanel.createTable(Train.class, crashedTrainList, true, false, tableLabels);
tablePanel.fireTableDataChanged();
}
});
}
And here's my tablePanel class:
public TablePanel() {
}
public void createTable(Class c, List data, boolean toolBarUp,
boolean toolBarBottom, ArrayList<String> labelsCheckBox) {
beanTableModel = new BeanTableModel(c, data);
columnModel = new XTableColumnModel();
table = new JTable(beanTableModel);
table.setColumnModel(columnModel);
table.createDefaultColumnsFromModel();
if(toolBarUp == true)
{
final JToolBar toolBarTop = new JToolBar();
// Create the Show ALL
JButton reset = new JButton("Reset");
reset.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for(Component c : toolBarTop.getComponents()){
if(c instanceof JCheckBox){
JCheckBox checkBox = (JCheckBox) c;
checkBox.setSelected(false);
columnModel.setAllColumnsVisible();
}
}
int numberOfColumn = columnModel.getColumnCount();
for(int aux = 0; aux < numberOfColumn; aux++)
{
int num = columnModel.getColumnCount();
TableColumn column = columnModel.getColumnByModelIndex(aux);
columnModel.setColumnVisible(column, true);
}
}
});
toolBarTop.add(reset);
// Create a JCheckBox for each column
for(int i = 0; i < labelsCheckBox.size(); i++)
{
final int index = i;
toolBarTop.add(new JCheckBox(new AbstractAction(labelsCheckBox.get(i)) {
#Override
public void actionPerformed(ActionEvent e) {
TableColumn column = columnModel.getColumnByModelIndex(index);
boolean visible = columnModel.isColumnVisible(column);
columnModel.setColumnVisible(column, !visible);
}
}));
}
setLayout(new BorderLayout());
add(toolBarTop, BorderLayout.NORTH);
add(new JScrollPane(table), BorderLayout.CENTER);
// add(toolBarDown, BorderLayout.SOUTH);
}
final JToolBar toolBarDown = new JToolBar();
toolBarDown.add(new JButton(new AbstractAction("Save Table") {
#Override
public void actionPerformed(ActionEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
}));
}
public void createTable(Class c, Class cAncestor) {
beanTableModel = new BeanTableModel(c, cAncestor);
table = new JTable(beanTableModel);
setLayout(new BorderLayout());
add(new JScrollPane(table), BorderLayout.CENTER);
}
public void createTable(Class c, Class cAncestor, List data) {
beanTableModel = new BeanTableModel(c, cAncestor, data);
table = new JTable(beanTableModel);
setLayout(new BorderLayout());
add(new JScrollPane(table), BorderLayout.CENTER);
beanTableModel.fireTableDataChanged();
}
public void createTable(Class c) {
beanTableModel = new BeanTableModel(c);
table = new JTable(beanTableModel);
setLayout(new BorderLayout());
add(new JScrollPane(table), BorderLayout.CENTER);
}
public void createTable(Class c, List data)
{
beanTableModel = new BeanTableModel(c, data);
table = new JTable(beanTableModel);
setLayout(new BorderLayout());
add(new JScrollPane(table), BorderLayout.CENTER);
}
//to refresh the table everytime there is an update
public void fireTableDataChanged()
{
beanTableModel.fireTableDataChanged();
}
So again, my question is: Isn't my JTable not updated with the new results every time I send new data to it?
You should never invoke fireTableDataChanged manually. Only the TableModel is responsible for invoking this event.
From your code it looks like you are creating a new TableModel, JTable and JScrollPane every time you make a change. Any time you add a component to a visible GUI the basic code should be:
panel.add(....);
panel.revalidate();
panel.repaint();
By default all components have a size of zero so since you don't invoke revalidate() then never get a proper size and there is nothing to paint. Also, it is never a good idea to simply keep adding components to the CENTER of your panel since the old component are still part of the container.
However, there is a better solution. There is no need to keep creating new components. All you need to do is create an new TableModel and then use:
table.setModel( newlyCreatedModel );
and the model will be added to the table and the table will repaint itself automatically.
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(...);
}
}
}
}
My code is quite simple actually. I saw a simple and similar code was from this article.
At first, I have 1 combobox. I have a listener on it called itemStateChanged(). My purpose to add into this listener is that; "to execute some code when user click (select) an item from its dropbox".
Cmb_ItemCategory = new javax.swing.JComboBox();
Cmb_ItemCategory.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Loading..." }));
Cmb_ItemCategory.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
Cmb_ItemCategoryItemStateChanged(evt);
}
});
private void Cmb_ItemCategoryItemStateChanged(java.awt.event.ItemEvent evt) {
if(evt.getStateChange() == java.awt.event.ItemEvent.SELECTED){
System.err.println("Sombody click or change my model content");
}
}
Behind the code, I grab some data, and then calling a method of removeAllItems() .
And then I set a new Model (from new data) into it.
-- at another line of code ---
Cmb_ItemCategory.removeAllItems();
Cmb_ItemCategory.setModel(newModel);
I juz realized that my itemStateChanged() is called when i do the removeAllItem() method. called once.
So, How to make it only called once user Click (select) only AND not when removeAllItems() called?
it similar to this article. But it's not removingItems case. CMIIW.
Here check this code out, this works flawlessly, might be you doing something wrong where you calling removeAllItems() :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ComboState
{
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("Combo State Testing : ");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
final JComboBox cbox = new JComboBox();
cbox.addItem("One");
cbox.addItem("Two");
cbox.addItem("Three");
cbox.addItem("Four");
cbox.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent ie)
{
if (ie.getStateChange() == ItemEvent.SELECTED)
{
System.out.println("Item Selected is : " + ie.getItem());
}
/*else
{
System.out.println("I am called for other reasons.");
}*/
}
});
/*
* Click me to remove JComboBox's items.
*/
JButton removeButton = new JButton("REMOVE");
removeButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
cbox.removeAllItems();
}
});
frame.add(cbox, BorderLayout.CENTER);
frame.add(removeButton, BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new ComboState().createAndDisplayGUI();
}
});
}
}
As nIcE cOw already illustrated in his example, it should certainly work when you use a DefaultComboBoxModel (which is the case in his sample code, although it happens behind the screens).
I could explain the behavior you encounter for the non-DefaultComboBoxModel case, although your code snippet suggests you use one. Looking at the source code for JComboBox#removeAllItems there is a different code path since the removeAllElements method is not part of the MutableComboBoxModel interface
public void removeAllItems() {
checkMutableComboBoxModel();
MutableComboBoxModel<E> model = (MutableComboBoxModel<E>)dataModel;
int size = model.getSize();
if ( model instanceof DefaultComboBoxModel ) {
((DefaultComboBoxModel)model).removeAllElements();
}
else {
for ( int i = 0; i < size; ++i ) {
E element = model.getElementAt( 0 );
model.removeElement( element );
}
}
selectedItemReminder = null;
if (isEditable()) {
editor.setItem(null);
}
}
So with a non-DefaultComboBoxModel you are going to remove the items one by one. This means that at a certain point in time, you will remove the selected element. A possible implementation of your model might change the selected element at that point. If you look for example at the implementation in DefaultComboBoxModel (although this code will not be triggered) you can clearly see it changes the selection.
public void removeElementAt(int index) {
if ( getElementAt( index ) == selectedObject ) {
if ( index == 0 ) {
setSelectedItem( getSize() == 1 ? null : getElementAt( index + 1 ) );
}
else {
setSelectedItem( getElementAt( index - 1 ) );
}
}
objects.removeElementAt(index);
fireIntervalRemoved(this, index, index);
}
Perhaps your model does something similar, which explains the event. Just for making this post complete, the code behind the DefaultComboBoxModel#removeAllElements where you can clearly see it sets the selection to null and does not select another object. Only weird thing in that code is that it does not fire a DESELECTED event first, although you know the selection has changed if you listen for the intervalRemoved event ... but that is not really relevant to your problem
public void removeAllElements() {
if ( objects.size() > 0 ) {
int firstIndex = 0;
int lastIndex = objects.size() - 1;
objects.removeAllElements();
selectedObject = null;
fireIntervalRemoved(this, firstIndex, lastIndex);
} else {
selectedObject = null;
}
}
So to conclude: I say the solution for your problem is located in your model, and not in the code you posted
One quick way to do is to have a bool set to true before you call removeAllItem() and back false after. Execute the code in your itemStateChanged() only if the bool variable is false.
Ideally you could override the removeAllItem() function.
not clear from whole discusion,
you have to remove all Listener(s) from JComboBox before removing all Items, after Items are removed you can add Listener(s) back,
still not sure if you want to add & remove Items dynamically, or you can set whatever value for another JComponent(s),
(against complicating simple things) did you see there remove,
.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class ComboBoxTwo extends JFrame implements ActionListener, ItemListener {
private static final long serialVersionUID = 1L;
private JComboBox mainComboBox;
private JComboBox subComboBox;
private Hashtable<Object, Object> subItems = new Hashtable<Object, Object>();
public ComboBoxTwo() {
String[] items = {"Select Item", "Color", "Shape", "Fruit"};
mainComboBox = new JComboBox(items);
mainComboBox.addActionListener(this);
mainComboBox.addItemListener(this);
//prevent action events from being fired when the up/down arrow keys are used
//mainComboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
getContentPane().add(mainComboBox, BorderLayout.WEST);
subComboBox = new JComboBox();// Create sub combo box with multiple models
subComboBox.setPrototypeDisplayValue("XXXXXXXXXX"); // JDK1.4
subComboBox.addItemListener(this);
getContentPane().add(subComboBox, BorderLayout.EAST);
String[] subItems1 = {"Select Color", "Red", "Blue", "Green"};
subItems.put(items[1], subItems1);
String[] subItems2 = {"Select Shape", "Circle", "Square", "Triangle"};
subItems.put(items[2], subItems2);
String[] subItems3 = {"Select Fruit", "Apple", "Orange", "Banana"};
subItems.put(items[3], subItems3);
// mainComboBox.setSelectedIndex(1);
}
#Override
public void actionPerformed(ActionEvent e) {
String item = (String) mainComboBox.getSelectedItem();
Object o = subItems.get(item);
if (o == null) {
subComboBox.setModel(new DefaultComboBoxModel());
} else {
subComboBox.setModel(new DefaultComboBoxModel((String[]) o));
}
}
#Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
if (e.getSource() == mainComboBox) {
if (mainComboBox.getSelectedIndex() != 0) {
FirstDialog firstDialog = new FirstDialog(ComboBoxTwo.this,
mainComboBox.getSelectedItem().toString(), "Please wait, Searching for ..... ");
}
}
}
}
private class FirstDialog extends JDialog {
private static final long serialVersionUID = 1L;
FirstDialog(final Frame parent, String winTitle, String msgString) {
super(parent, winTitle);
setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
JLabel myLabel = new JLabel(msgString);
JButton bNext = new JButton("Stop Processes");
add(myLabel, BorderLayout.CENTER);
add(bNext, BorderLayout.SOUTH);
bNext.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
setVisible(false);
}
});
javax.swing.Timer t = new javax.swing.Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
});
t.setRepeats(false);
t.start();
setLocationRelativeTo(parent);
setSize(new Dimension(400, 100));
setVisible(true);
}
}
public static void main(String[] args) {
JFrame frame = new ComboBoxTwo();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
The method removeAllItems does not call ItemStateChanged, but it call actionPerformed, you can check it by running this simple code:
public class Tuto {
public static void main(String[] args) {
//create the main frame
JFrame frame = new JFrame();
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.setLocation(new Point(10, 10));
frame.setPreferredSize(new Dimension(400, 300));
JComboBox<String> combo = new JComboBox();
combo.addItem("item 1");
combo.addItem("item 2");
combo.addItem("item 3");
combo.setBounds(50, 30, 300, 20);
combo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
System.out.println(" action Performed ");
}
});
frame.add(combo);
JButton button = new JButton("Remove");
button.setBounds(50, 100, 100, 30);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
combo.removeAllItems();
}
});
frame.add(button);
frame.pack();
frame.setVisible(true);
}
}