My case is very specific here:
First, I have an already-defined array of Strings that contains the default options (which are always the same for all users) of a JComboBox:
private static final String[] JOB_TYPE = {options go here};
These options are loaded into the JComboBox as follows:
private JComboBox jobType = new JComboBox(JOB_TYPE);
Then, there are other options that can vary from one user to another that I have to load inside the JComboBox as well. Since arrays have a fixed number of elements, I had to find another way to add the specific options besides the default ones into the JComboBox. And so what I did was, I created a LinkedList and used the asList method from Arrays to load the default options of the array inside it, then add the other options which vary from one user to another:
private List<String> allJobs = new LinkedList<String>(Arrays.asList(JOB_TYPE));
allJobs can now be passed on as an argument for the JCombobox using the toArray() method:
private JComboBox jobType = new JComboBox(allJobs.toArray());
Now, I have all the default options in allJobs, and since it's no longer an array, I can also add to it the specific options which will be loaded as follows:
for (int j = 0; j < modelJobCustomType.getSize(); j++) {
allJobs.add(((XmlJobCustomElem) modelJobCustomType.getElementAt(j)).getName());
}
Now, here's my problem:
When I check the content of the JComboBox, I only find the default options, and not the specific ones even though I can see using the debugger that the list size has increased and it contains the specific options as well.
My guess is, since jobType, JOB_TYPE and allJobs are global variables, the ComboBox is being populated way before the compiler gets to the part of the code where it loads the specific options as well, and that's probably why I can only see the default options.
Is this correct? And if so, how can I fix this problem. Keep in mind that those global variables have to stay global because they are also being used in many other parts of the class.
Thanks for your help
The combobox is given the array derived from a list. Afterwards adding to the list will not change the array value (arrays are fixed length values),
There also is a JComboBox with a Vector parameter, that allows adding (as opposed to an array).
However the nicest is a JComboBox with a ComboBoxModel<E> parameter that is the most high-level. There is a default implementation DefaultComboBoxModel:
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>(JOB_TYPE);
model.addElement("custom0");
model.addElement("custom1");
combobox = new JComboBox(model);
You can initialize your class like this to let you keep all the jobs in allJobs at initialization rather than the custom ones only existing in the JComboBox as in Jamie's solution. You could also do all the initializing of the instance fields inside the constructors:
class Main {
private static final List<String> FIXED_OPTIONS = Arrays.asList("fixed0", "fixed1", "fixed2");
private List<String> allJobs = new ArrayList<>(FIXED_OPTIONS);
{
int count = 6;
for (int i = 0; i < count; i++) {
allJobs.add("custom" + i);
}
}
private JComboBox jobType = new JComboBox(allJobs.toArray());
}
You can look at the source: JComboBox
181: /**
182: * Constructs JComboBox with specified list of items.
183: *
184: * #param itemArray array containing list of items for this JComboBox
185: */
186: public JComboBox(Object[] itemArray)
187: {
188: this(new DefaultComboBoxModel(itemArray));
189:
190: if (itemArray.length > 0)
191: setSelectedIndex(0);
192: }
The constructor creates a new instance of the DefaultComboBoxModel.
Related
I am developing an application in Netbeans using Java and have been told to use the GUI creation features that Netbeans offer. Due to this I cannot edit the initComponents(); method to edit the creation of the JList and add a default list model to it.
I have tried creating a new JList but that resulted in an infinite loop. I haven't ever created controls through coding them myself, only by an IDE's GUI creation tools.
This is what I have currently:
private void formWindowActivated(java.awt.event.WindowEvent evt) {
//String to hold current patients data
String patientDetails;
//Take the arraylist from the model
ArrayList<IAccountStrategy> unapprovedPatients;
unapprovedPatients = model.getObservers();
//Create default list model to store the patients details
DefaultListModel<String> unapprovedPatientModel = new DefaultListModel<>();
IAccountStrategy xx;
//For loop to iterate through each element of unapprovedPatients
for(int i = 0; i < unapprovedPatients.size(); i++){
//get the current patients details and store them in a string variable
xx = unapprovedPatients.get(i);
patientDetails = xx.getAccountID() + xx.getUsername() + xx.getFirstname() + xx.getLastname();
//Add string variable to list model
unapprovedPatientModel.addElement(patientDetails);
}
//add list model to existing JList
listPatients.addElement(unapprovedPatientModel);
}
I would like to output all the elements from the list model into the actual JList and then let the user interact with the list itself.
Thanks in advance!
is it not possible to use the list as I want
You just wrote code to create the DefaultListModel.
So now all you need is to add:
list.setModel( unapprovedPatientModel );
so the JList can use the newly created model.
Although the problem with this code is that the code will be executed every time the window is activated.
But the point is that all you need to do is update the list using the setModel() method. How you do this in the IDE is up to you.
I've put together a few methods that are suppose to delete a searched item from an array and the data from the array is also being put into a JTable through a method called createLoginTable().
When my delete button actionListener Method is carried out the element or login is successfully deleted from the array: 'listOfLogins' but the element does not appear to be deleted from the JTable as it is still there.
Here are the methods starting with the actionListener:
if(e.getSource()==deleteLoginButton)
{
int loopNo = list.nextLogin; ///Variables used in the 'removeLogin' Method
String foundLogin = list.listOfLogins[foundLocation].toString();
Login[] loginList = list.listOfLogins;
LoginList list = new LoginList(); //The 'list' is wiped
list.removeLogin(loginList, foundLogin, loopNo);
list.writeLoginsToFile(); //Writes logins to file (not integral to the array)
String[][] loginTableLogins = new String[50][2]; //Wipes the JTable Array
createLoginsTable(); //Creates the JTable
searchLoginButton.setEnabled(true);
editLoginButton.setEnabled(false);
deleteLoginButton.setEnabled(false);
addLoginButton.setEnabled(true);
}
This is the 'removeLogin' Method (This is in a seperate 'list' class):
public void removeLogin(Login[] array, String unwantedLogin, int loop)
{
for(int i=0;i<loop;i++)
{
String currentLogin = array[i].toString();
if(!currentLogin.equals(unwantedLogin))
{
Login login = new Login();
addLogin(array[i]);
}
}
}
plus 'addLogin' Method (although i am assured this is not the source of my issue):
public void addLogin(Login tempLogin)
{
listOfLogins[nextLogin] = tempLogin;
System.out.println(listOfLogins[nextLogin]);
nextLogin++;
System.out.println(nextLogin);
}
And the 'createLoginsTable' method:
public void createLoginsTable()
{
for(int i=0;list.nextLogin>i;i++)
{
loginTableLogins[i] = list.listOfLogins[i].toArray();
System.out.println(list.listOfLogins[i].toString());
}
JTable loginsTable = new JTable(loginTableLogins, loginTableTitles);
JScrollPane loginsScrollPane = new JScrollPane(loginsTable);
loginsScrollPane.setBounds(400, 200, 200, 250);
testPanel.add(loginsScrollPane);
}
I have used 'System.out.println's so I am 99% certain that the element has been removed from the array (it is also apparent through my writeLoginsToFile Method) So I hope this information helps.
Your code is a little bit hard to decipher, next time maybe put in also the enclosing class, or some details about that class. What does the following line do:
LoginList list = new LoginList(); //The 'list' is wiped
You say the list is wiped, I think what is does is: it declares a list local variable and assigns a new object to it (and it masks the other list variable which you used a few lines earlier). Now, in the createLoginsTable() method you don't have this local variable, you have the "list" which I guess is a public field in your class. Now what you can do, is or pass the local list variable to the above function as a parameter createLoginsTable(list) or try the wiping line without the declaration so only:
list = new LoginList(); //The 'list' is wiped
Anyway, your code seams a little bit troubled it, maybe you should refactor it a little bit. Hope it helps.
You're not returning the table after you delete the item.
When you call the method to delete it and write out the table, that table is not returned after you remake the table.
Take this:
JScrollPane loginsScrollPane = new JScrollPane(loginsTable);
Bring it outside of your method. What I think might be happening is when you create your loginsScrollPane locally inside the method, it's not being added properly to your testPanel.
I think what might be happening is when you add it, and the method ends it's loosing that data that is contained. Declare your scrollpane, and your jtable where you declare your frame.
Maybe this just isn't possible but what I'm trying to do is change the visibility of multiple elements in a GUI at the same time using an ArrayList to reference to them sort of dynamically. The objects are created by themselves in another method.
Both oldScreen.setVisible(false); and oldScreen<1>.setVisible(false); statements cause errors. I had a hunch my idea wouldn't work out so well.
Here is basically what i have, any way i can achieve this?
private void initScreens() {
// I create some ArrayLists as "screensets" of sorts and put some GUI elements in there
ArrayList startScreen = new ArrayList();
ArrayList lostScreen = new ArrayList();
ArrayList playScreen = new ArrayList();
startScreen.add(startB);
startScreen.add(exitB);
lostScreen.add(yl1);
lostScreen.add(yl2);
lostScreen.add(yl3);
lostScreen.add(yl4);
lostScreen.add(yl5);
}
private void changeScreen(ArrayList oldScreen,ArrayList newScreen) {
// now i try to create a handy method to handle the length of the arrays itself, so if
i need to make changes to screens I just add them to there array. They are then easily
displayed, and hidden when told.
int os = oldScreen.size();
int ns = newScreen.size();
for (int i = os; i > 0; i--){
oldScreen<i>.setVisible(false);
oldScreen<1>.setVisible(false);
}
That's invalid syntax.
You're trying to write
oldScreen.get(i)
You should also use generics (ArrayList<Screen>) to avoid casting.
I have used linked lists before with Strings, doubles, etc., and they always worked exactly as expected. But now I am forming a linked list of items, and whenever I add a new element to the list, all objects in the list apparently become equal to the last object.
The essential code is as below:
import java.util.*;
public class Global
{
static public LinkedList<StockInfo> DiaryStocks = new LinkedList<StockInfo>();
static public class StockInfo //info related to each stock in diary
{
String recordDate;
String ticker;
int status;
String buyDate;
String sellDate;
double buyPrice;
double sellPrice;
double nmbrShares;
}//StockInfo
//The following function places the Diary data for a stock in the arraylist
static public void AddDiaryData(StockInfo thisdata)
{
String tckr;
int i;
DiaryStocks.add(thisdata);
for (i = 0; i < DiaryStocks.size(); i++) //this is debug code
{
tckr = DiaryStocks.get(i).ticker;
}
}
}
As I said, when single stepping through the debug code near the bottom, each time I add a new item to the list, the list size grows as it should, but the tckr item only corresponds to the last item added.
Any insights into this puzzle would be greatly appreciated.
John Doner
The problem is outside the code your provide. It is most likely that you are adding the same instance of StockInfo. Perhaps you have something like:
StockInfo info = new StockInfo();
for (...) {
info.setFoo(..);
info.setBar(..);
AddDiaryData(info);
}
You should not reuse instances like that. You should create a new instance each time.
As a sidenote - method names in Java should start with lowercase letter.
From the symptoms you are describing, it seems as if you are always adding a reference to the same StockInfo object instance to your list, rather than a reference to a new copy each time.
When that object is updated with the contents of the new entry, all list entries appear to change to reflect that latest entry.
This problem lies outside the code snippet that you posted, perhaps in the caller of the AddDiaryData method.
Ooops.
Deep Copy please search it
DiaryStocks.add(thisdata);
you should create new StockInfo() then add to the list otherwise you add the reference and it equalize all the reference of items to the last one
I am using LWUIT for getting a search facility for selection in the List.
Now I want to know how can I display the list with CheckBoxes?
list=new List(vector);
cform.addComponent(list);
cform.addComponent(t);
cform.show();
I don't know if there is a more simple solution then mine, but mine is highly customizable and can serve for a lot of purposes.
List l = new List;
Vector v = new Vector();
for(int i = 0; i < 10; ++i){
v.addElement(new CheckItem("itemtekst"));
}
l.setListCellRenderer(new CheckItemRenderer());
l.setModel(new CheckItemModel(v));
the code above makes it work. As you can guess you have to make a new class and override two to make it work.
CHECKITEM: this class has a string and an image. as well as setters and getters. it also has a boolean that shows if it is checked or not.
CHECKITEMRENDERER: has a label for the string and the image of the checkitem it extends Container and implements ListCellRenderer
CHECKITEMMODEL: this extends the defaultlistmodel. it has methods to get the checkeditems and setthem checked or unchecked.
to recap:
set the correct items in the vector
set the correct renderer
set the correct model
and to use it add an actionlistener or it will al be for nothing.