Getting selected Items from Jlist - java

I have seen many posts & tried different ways to solve this problem but still I dont get my list of selected items. Here's the code which I use.
public List<String> getSelectedDeviceList()
{
return list;
}
/**
* Create the frame.
*/
public JLogicDesign(Frame frame, List<String> listDevices) {
super();
setTitle("Device Names");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setBounds(100, 100, 331, 316);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
jlistModel = new DefaultListModel();
for(String s: listDevices)
{
jlistModel.addElement(s);
}
final JList jlist = new JList(jlistModel);
jlist.setVisibleRowCount(5);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
btnOk = new JButton("OK");
btnOk.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
list = new ArrayList<String>();
Object[] values = jlist.getSelectedValues();
for(Object o: values)
{
list.add(o.toString());
}
dispose();
}
});
The JList is being properly populated. When I try to get the selected Items, I get a NPE.
This is another class where I'm calling the above class
JLogicDesign jld = new JLogicDesign(f,listOfDevices);
devices = new ArrayList<String>();
devices = jld.getSelectedDeviceList();
Thanks in advance !!

You get NPE at this line:
JLogicDesign jld = new JLogicDesign(f,listOfDevices);
devices = new ArrayList<String>();
devices = jld.getSelectedDeviceList(); // NPE here
Because list variable in JLogicDesign is only initialized when btnOk is pressed. So the pointed line is executed before this button is pressed and that's why it throws NPE.
To avoid NPE you shoud initialize list in JLogicDesign. However it doesn't solve the problem. You wont get NPE but you'll get an empty list. This is because JLogicDesign is not modal and even if these sentences are being executed on the Event Dispatch Thread jld.getSelectedDeviceList() will return the list before btnOk is pressed.
If you need the selected devices before continue then consider use a modal JDialog.

Related

How can I pass an ArrayList between two separate JTabbedPanes

I have a program utilizing JTabbedPane. On one pane I have a button that updates an arrayList of objects based on input from the same pane.
What I would like to happen is have the second pane update itself with the object information based on the arrayList in the first pane.
However, I am not sure how to pass the list between the panes. Is there some way to push the array to pane #2 when the update button on the first pane is pressed?
Here is the main file. Instantiating the two tabs
public class Assignment6 extends JApplet
{
private int APPLET_WIDTH = 650, APPLET_HEIGHT = 350;
private JTabbedPane tPane;
private StorePanel storePanel;
private PurchasePanel purchasePanel;
private ArrayList computerList;
public void init()
{
computerList = new ArrayList();
storePanel = new StorePanel(computerList, purchasePanel);
purchasePanel = new PurchasePanel(computerList);
tPane = new JTabbedPane();
tPane.addTab("Store Inventory", storePanel);
tPane.addTab("Customer Purchase", purchasePanel);
getContentPane().add(tPane);
setSize (APPLET_WIDTH, APPLET_HEIGHT); //set Applet size
}
}
The first panel instantiates a button listener that applies all of the logic to the array list "compList"
private class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
//Add Computer to list
Computer comp = new Computer();
comp.setBrandName(brandField.getText());
comp.setPrice(Double.parseDouble(priceField.getText()));
comp.setMemory(Integer.parseInt(memoryField.getText()));
comp.setCPU(typeField.getText(), Integer.parseInt(speedField.getText()));
compList.add(comp);
}
stringField.setText(listString);
alertLabel.setText("Computer Added");
}
}
Here is the other pane. The for loop at the end is what I need to push the arrayList to. After it receives the list, it populates a box with a checkbox for each object in the list
public PurchasePanel(ArrayList compList)
{
west = new JPanel();
east = new JPanel();
totalField = new JTextField();
this.compList = compList;
setLayout(new GridLayout(0,2));
add(west);
add(east);
east.setLayout(new BorderLayout());
east.add(currentTotalLabel, BorderLayout.NORTH);
east.add(totalField, BorderLayout.CENTER);
west.setLayout( new BoxLayout(west, BoxLayout.Y_AXIS));
for(Object c : compList){
System.out.println("Made it");
NumberFormat fmt = NumberFormat.getCurrencyInstance();
String str = ("BrandName:" + (((Computer) c).getBrandName() +"CPU:" + (((Computer) c).getCPU() +"Memory:" + ((Computer) c).getMemory() + "M" +"Price:" + fmt.format(((Computer) c).getPrice()))));
JCheckBox chk = new JCheckBox(str);
west.add(chk);
}
}
}
You can use the same listener used to update the first ArrayList, to update the second pane. Something like:
jButton1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Update the first ArrayList
// Update the second pane
}

JAVA Display item from JList in JLabel

public class ListComboBox extends JFrame {
private String MIS = "MULTIPLE_INTERVAL_SELECTION";
private String SIS = "SINGLE_INTERVAL_SELECTION";
private String SS = "SINGLE_SELECTION";
final int COUNTRIES = 9;
private String[] countries = {"Canada", "China", "Denmark",
"France", "Germany", "India", "Norway", "United Kingdom",
"United States of America"};
private JList<String> jlst = new JList<String>(countries);
private JLabel comboLabel = new JLabel("Choose Selection Mode: ");
private JComboBox jcbo = new JComboBox();
//to hold country labels
private JLabel countryLabel = new JLabel();
public static void main(String[] args) {
ListComboBox frame = new ListComboBox();
frame.setSize(400, 200);
frame.setTitle("Exercise 17.14");
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public ListComboBox() {
//Adding selection option to combobox
jcbo.addItem(MIS);
jcbo.addItem(SIS);
jcbo.addItem(SS);
// Register listener combobox
jcbo.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (e.getItem() == MIS) {
jlst.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
}
if (e.getItem() == SIS) {
jlst.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
}
if (e.getItem() == SS) {
jlst.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
}
});
//Combobox panel
JPanel combopanel = new JPanel(new FlowLayout());
combopanel.add(comboLabel);
combopanel.add(jcbo);
add(combopanel, BorderLayout.NORTH);
//List panel
JScrollPane listpanel = new JScrollPane(jlst);
add(listpanel, BorderLayout.CENTER);
//Bottom label panel
final JPanel labelpanel = new JPanel();
labelpanel.add(countryLabel);
add(labelpanel, BorderLayout.SOUTH);
//List listener
jlst.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
StringBuilder sb = new StringBuilder(64);
int[] indices = jlst.getSelectedIndices();
int i;
for (i = 0; i < indices.length; i++) {
if (sb.length() > 0) {
sb.append(", ");
}
sb.append(countries[indices[i]]);
}
countryLabel.setText(sb.toString());
}
});
}
}
Good day, I need your help.
What I need code to do: Add selected country names from the list with scroll bar to the label below the list, remove them as they are unselected in the list.
List selection mode can be switched in JComboBox on top.
Everything works fine, but I cannot figure out the way for country names to properly appear inside the label.
Any tips on how I might accomplish that?
Thanks!
UPDATED!
setName is used for internal identification of the component. Imagin you've been give a list of components, all you know is you need to find the one with some unique identifier, that identifier is supplied via the name property. It has no effect on the output of the component.
You need to use the setText method to change what is displayed on the screen.
The next problem you'll have is setText is a replacement method. That is, it will replace what ever was previously applied with the new value. What might need to do is build a temporary String of the values you want to display and then apply that value to the label, for example...
StringBuilder sb = new StringBuilder(64);
for (i = 0; i < indices.length; i++) {
if (sb.length() > 0) {
sb.append(", ");
}
sb.append(countries[indices[i]]);
}
countryLabel.setText(sb.toString());
To set text on JLabel use countryLabel.setText instead of countryLabel.setName. Another issue is that in the posted code countryLabel is not added to the frame. I assume it should go into labelpanel, but this part is commented out.
Some other observations:
Do not mix light weight and heavy weight components. See Mixing Heavyweight and Lightweight Components. Instead of ScrollPane use JScrollPane, for example:
JScrollPane listpanel = new JScrollPane(jlst);
Also there is no need to revalidate() the container when you set text on JLabel. The label will be refreshed as a result of setText() method.

JCombo Box not updating selected item / Innerclass access

I am making a simple calculator in Java, I'm pretty new to Java but I've done a lot of work with languages like it.
The problem is, I need to have the combo box select an item and have it kept up to date, either in a place holder, or in the box itself.
This is the basic class that sets up the frame and everything.
private void initComponents()
{
//TODO:make controls here
//TODO:DONE
JFrame calculator = new JFrame("Steven Seppälä");
calculator.setLayout(new GridLayout(2, 2, 0, 0));
calculator.setSize(400,300);
//"calculator" is the holder for which all the
//items must attach to
calculator.add(new JLabel("Enter the first fraction('1/2')"));
// calculator.add(new JToolBar.Separator(new Dimension(0,10)));
calculator.add(field1);
// calculator.add(new JToolBar.Separator(new Dimension(0,10)));
//TODO: ADD COMBO BOX HERE
String[] operationList = {"+","-","*","/"};
JComboBox operationBox = new JComboBox(operationList);
calculator.add(operationBox);
/*Tried doing the following as well, but it just gave the index 0 consistantly
without changeing, regaurdless of if it did change or not */
// String thing = operationBox.getSelectedItem().toString();
// System.out.println("Selected Operation is: " + thing);
// operationCall = operationBox.getSelectedItem();
operationBox.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//DEBUGGING
operationBox.getSelectedItem().toString();
}
});
calculator.add(new JLabel("Enter the next fraction('3/4')\n",1));
// calculator.add(new JToolBar.Separator(new Dimension(0,0)));
calculator.add(field2);
// calculator.add(new JToolBar.Separator(new Dimension(0,0)));
JButton Cal = new JButton("Calculate");
calculator.add(Cal);
Cal.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//DEBUGGING
System.out.println("Finalizing Calculations...");
calculations();
}
});
//sets exit conditions and the visibility of the window
calculator.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
calculator.setVisible(true);
calculator.add(new JLabel(results));
//TODO: add to(?) frame
//TODO:DONE
}
The action listener for the Calculate button works fine, but when I compile as it is now, I get the error message :
FractionFrame.java:53: error: local variable operationBox is accessed from within inner class; needs to be declared final
System.out.println(operationBox.getSelectedItem().toString());
^
In the ActionListener you can access the combo box by using:
JComboBox comboBox = (JComboBox)e.getSource();
Instead of:
JComboBox operationBox = new JComboBox(operationList);
Make it:
final JComboBox operationBox = new JComboBox(operationList);

Opening contents of a JList in new window

I'm very new to Java.
I've created two JLists in which you can add and remove 'shopping cart' items.
Once the user has added all their items they can click a submit button to view their selected items in a new window.
My first list is itemList (populated with items from array), the second list is shoppinglist which gets populated with whatever the user selects with a JButton.
Additional arrays are created to handle the actions of the buttons moving the items to and from the JLists. I've tried a few things, but haven't been successful in showing the items that get selected and shown in shopinglist to appear in a new window once submit is hit.
Any help is much appreciated.
//Create itemList
itemList = new JList(shopping);
contentPane.add(itemList);
itemList.setVisibleRowCount(10);
itemList.setFixedCellHeight(20);
itemList.setFixedCellWidth(140);
itemList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
//Add JScrollPane to maintain size
JScrollPane list1 = new JScrollPane(itemList);
//contentPane.add(list1);
//Create shoppingList
shoppingList = new JList(items);
contentPane.add(shoppingList);
shoppingList.setVisibleRowCount(10);
shoppingList.setFixedCellHeight(20);
shoppingList.setFixedCellWidth(140);
shoppingList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
//Add JScrollPane to maintain size
JScrollPane list2 = new JScrollPane(shoppingList);
JPanel buttonPanel = new JPanel();
//contentPane.add(list2);
Buttonin = new JButton(">>");
//Buttonin.setBounds(144, 46, 60, 23);
Buttonin.addActionListener(this);
buttonPanel.add(Buttonin);
ButtonOut = new JButton("<<");
//ButtonOut.setBounds(144, 80, 60, 23);
ButtonOut.addActionListener(this);
buttonPanel.add(ButtonOut);
JPanel submitPanel = new JPanel();
submitButton = new JButton("Submit");
submitPanel.add(submitButton);
submitButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent az) {
JFrame frame = new JFrame ("Go Shopping!");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new MyPanel2());
frame.pack();
frame.setVisible(true);
}
});
contentPane.add(list1);
contentPane.add(buttonPanel);
contentPane.add(list2);
contentPane.setOpaque(true);
contentPane.add(submitPanel);
return contentPane;
}
public void actionPerformed(ActionEvent e)
{
int i = 0;
//When in buttonin is pressed index and value of selected item is output to array
if (e.getSource() == Buttonin)
{
int[] fromindex = itemList.getSelectedIndices();
Object[] from = itemList.getSelectedValues();
//add items to the shoppingList
for (i = 0; i < from.length; i++)
{
items.addElement(from[i]);
}
//Must remove items that are selected from the itemList
for (i = (fromindex.length-1); i >= 0; i--)
{
shopping.remove(fromindex[i]);
}
}
//When out button is pressed index and value of selected item is output to new array
else if (e.getSource() == ButtonOut)
{
Object[] to = shoppingList.getSelectedValues();
int [] toindex = shoppingList.getSelectedIndices();
//add items to previous list
for(i = 0; i < to.length; i++)
{
shopping.addElement(to[i]);
}
//Must remove what's deselected
for (i = (toindex.length-1); i >= 0; i--)
{
items.remove(toindex[i]);
}
}
Ok, bear with me (very very new to java) is this how I would set up the constructor to reference to ProfileFrame objects? And if so how do I change my main to reflect the new constructor?
public class GoShopping extends JPanel {
private JList shopList;
public GoShopping(ProfileFrame slist) {
//construct components
shopList = new JList(slist.getListModel());
shopList.setBounds(6, 6, 123, 166);//don't worry I'm changing the layout
add(shopList);
}
public static void main (String[] args) {
JFrame frame = new JFrame ("MyPanel");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
//I need new GoShopping to reflect the new constructor, but not sure how to make it work
frame.getContentPane().add (new GoShopping());
frame.pack();
frame.setVisible (true);
}
}
You're creating a new ProfileFrame object in your MyPanel2 constructor, and since this is not the same instance as the visualized ProfileFrame object, then its JList's model will be null. A bad solution is to use static variables -- just don't do this please. A better solution is to pass a reference to the true visualized ProfileFrame object into your MyPanel2 constructor and call the public methods off of this instance.
And again, don't use null layout and setBounds(...), but instead use the layout managers unless you like making things more difficult than they need to be.

How to refresh JScrollPane

My main frame contains JScrollPane which lists some objects. Through menu (pop up frame) I create new object and I want to list this object in the JScrollPane (which is created in a constructor of DemoFrame class). How can I do it?
Part of my constructor in DemoFrame
ArrayList<Item> i = g.getAllItems();
Vector allItemsVector = new Vector(i);
JList items = new JList(allItemsVector);
panel.add( new JScrollPane( items ))
In pop up frame I add new object to 'g' object in that case. Have I designed it wrong?
A lot depends on information that you haven't told us, for instance just what is the JScrollPane holding? A JTable? A JList? The key will be to update the component being held by the JScrollPane and then revalidate and repaint this component.
Edit
You need to have a reference to the JList, so it should be declared outside of your constructor. For instance:
// GUI class
public class GuiClass {
private JList items; // declare this in the *class*
// class's constructor
public GuiClass() {
ArrayList<Item> i = g.getAllItems();
Vector allItemsVector = new Vector(i);
// JList items = new JList(allItemsVector); // don't re-declare in constructor
items = new JList(allItemsVector);
panel.add( new JScrollPane( items ))
}
Then later in your menu's listener code you can add an item to the items JList as needed.
This was a problem for me as well. A quick workaround is remove the JScrollPane from the panel, make your changes then readd it. Many may deem it inefficient, but it works with no significant change to runtime
JPanel panel = new Jpanel();
JList list = new JList({"this", "is", "a test", "list"});
JScrollPane sPane = new JScrollPane();
public void actionPerformed(ActionEvent e) {
if (resultsPane!=null){
panel.remove(sPane);
}
sPane = updatePane(list);
panel.add(sPane);
}
public void updatePane(String[] newListItems) {
DefaultListModel model = new DefaultListModel();
for(int i = 0; i < newListItems.length; i++) {
model.addElement(newListItems[i]);
}
JList aList = new JList(model);
JScrollPane aPane = new JScrollPane(aList);
}
Assuming I understood the question correctly:
You have a JFrame with a JScrollPane. And the JScrollPane has a JList.
The JList has a set of strings in it and this shows fine, but later you want to update the list and have it update in the JFrame view, but when you do update the list nothing happens to visualisation?
I had the same problem and how I got it to work was to set the content of the JList using a DefaultListModel. Instead of updating the contents of the JList, I update the contents in the DefaultListModel and then set the JList content to the model content when everything has been added. Then call the JScrollPane repaint function
//Declare list and pane variables up here so that we have a reference
JList<String> list;
JScrollPane pane;
//Set up the frame content
void SetupFrame() {
//instantiate the list
list = new JList();
//sets up the scroll pane to take the list
pane = new JScrollPane();
pane.setViewportView(list);
pane.setBounds(10, 10, 200, 80);
//adds the scrollpane to the frame
add(pane);
//update the list of strings
UpdateList();
}
//Updates the contents of the list (call this whenever you want to update the list)
void UpdateList() {
//model used to update the list
DefaultListModel model = new DefaultListModel();
//Update the contents of the model
for (int i = 0; i < 10; i++)
model.addElement("Test value");
//update the list using the contents of the model
connectionLabels.setModel(model);
//repaint the scrollpane to show the new list content
pane.repaint();
}

Categories

Resources