JComboBox setSelectedItem does not work - java

I am trying to set the setSelectedItem of the JComboBox in the constructor of my JPanel class just after populating the combobox.
I am set the value for textbox, but I can't figure out why setSelectedItem does not seem to work. Any ideas?
public StudentProfilePanel(StudentInfo si) {
yesButton.setBounds(50, 346, 69, 40);
noButton.setBounds(121, 346, 56, 40);
this.add(yesButton);
this.add(noButton);
setLayout(null);
comboBoxYear.setModel(new DefaultComboBoxModel(years()));
comboBoxYear.setBounds(202, 365, 62, 23);
if(si.birthdate!=null){
//System.out.println("year value : ["+dateofbirth(si.birthdate)[2]+"]");
comboBoxYear.setSelectedItem(dateofbirth(si.birthdate)[2]);
}
add(comboBoxYear);
comboBoxMonth.setModel(new DefaultComboBoxModel(new String[]{"01","02","03","04","05","06","07","08","09","10","11","12"}));
comboBoxMonth.setBounds(285, 365, 56, 23);
//set month value
if(si.birthdate!=null){
//comboBoxMonth.setSelectedItem(dateofbirth(si.birthdate)[1]);
comboBoxMonth.setSelectedItem("04");
System.out.println("month value : ["+dateofbirth(si.birthdate)[1]+"]");
}
add(comboBoxMonth);
comboBoxDay.setModel(new DefaultComboBoxModel(days()));
comboBoxDay.setBounds(351, 365, 54, 23);
if(si.birthdate!=null){
//comboBoxDay.setSelectedItem(dateofbirth(si.birthdate)[0]);
comboBoxDay.setSelectedItem(dateofbirth(si.birthdate)[0]);
}
add(comboBoxDay);
textFieldFirstName = new JTextField();
textFieldFirstName.setBounds(21, 321, 171, 21);
add(textFieldFirstName);
textFieldFirstName.setColumns(10);
// set the value of first name
textFieldFirstName.setText(si.firstName);
textFieldLastName = new JTextField();
textFieldLastName.setBounds(242, 321, 163, 21);
add(textFieldLastName);
textFieldLastName.setColumns(10);
//set the value of the last name
textFieldLastName.setText(si.lastName);
JPanel panelPersonPhoto = new ImagePanel(
"C:\\Users\\MDJef\\Pictures\\Wallpaper\\General\\11.jpg");
panelPersonPhoto.setBorder(new TitledBorder(null, "",
TitledBorder.LEADING, TitledBorder.TOP, null, null));
panelPersonPhoto.setBounds(21, 20, 384, 291);
add(panelPersonPhoto);
}
Thanks very much.
helper methods that I used
// jf : helper method
public String[] years() {
String[] results = new String[90];
for (int i = 0; i < 90; i++) {
results[i] = Integer.toString(1900 + i);
}
return results;
}
// jf : helper method
public String[] months() {
String[] results = new String[12];
for (int i = 0; i < 12; i++) {
results[i] = Integer.toString(i + 1);
}
return results;
}
// jf : helper method
public String[] days() {
String[] results = new String[31];
for (int i = 0; i < 31; i++) {
results[i] = Integer.toString(i + 1);
}
return results;
}
// jf : helper method
public String[] dateofbirth(String dob) {
String[] tokens = dob.split("-");
return tokens;
}

The values assigned to the combo box are not the same values you are trying set.
For example, the years are Strings from 1900 - 1990, but if I supply a value 72, there is no matching value in the combo box to match to.
Equally, your days and months methods are only returning values that are not padded (ie 01), where as, in your code, you're trying to set the value using a padded value (ie 04), meaning there is no matching value...
You have a number of options...
You could...
Convert all the values to an int, meaning that the values in the combo box are simply ints. You would then need to convert the date values to ints as well.
This would make your helper code look more like...
public int[] years() {
int[] results = new String[90];
for (int i = 0; i < 90; i++) {
results[i] = 1900 + i;
}
return results;
}
public int[] months() {
int[] results = new String[12];
for (int i = 0; i < 12; i++) {
results[i] = i + 1;
}
return results;
}
public int[] days() {
int[] results = new String[31];
for (int i = 0; i < 31; i++) {
results[i] = i + 1;
}
return results;
}
public int[] dateofbirth(String dob) {
int[] tokens = dob.split("-");
int[] values = new int[tokens.length];
for (int index = 0; index < tokens.length; index++) {
values[index] = Integer.parse(tokens[index]);
}
return index;
}
A better solution
Would be to use a JSpinner, which would take care of date rolling issues and validation automatically.
Check out Using Standard Spinner Models and Editors

Not related to your problem, but:
yesButton.setBounds(50, 346, 69, 40);
noButton.setBounds(121, 346, 56, 40);
setLayout(null);
Don't use a null layout and setBounds(...). Swing was designed to be used with Layout Manager. In the long run you will save time.
if(si.birthdate!=null){
Don't access variables in your class directly. Create a getter method to access the properties of your class.
//System.out.println("year value : ["+dateofbirth(si.birthdate)[2]+"]");
comboBoxYear.setSelectedItem(dateofbirth(si.birthdate)[2]);
Don't always try to force you code into a single statement. Instead do something like:
String birthdate = dateofbirth(si.birthdate[2]);
System.out.println("year value : [" + birthdate +"]");
comboBoxYear.setSelectedItem(birthdate);
This helps with your debugging because now you know that the variable you display is the same variable that you are trying to use in the setSelectedItem() method. It saves typing the statement twice and avoids typing mistakes.

When you call comboBoxMonth.setSelectedItem("04"); you try to select a newly created String which is not equal to the one which is in your JComboBox. Ergo it does not get selected.
You can try something like this instead:
String[] months = new String[] {"01","02","03","04","05","06","07","08","09","10","11","12"};
comboBoxMonth.setModel(new DefaultComboBoxModel(months));
comboBoxMonth.setSelectedItem(months[3]);
Edit: Try this. It uses the index of the item instead. Just make sure you add the months in order to the array.
String[] months = new String[] {"01","02","03","04","05","06","07","08","09","10","11","12"};
comboBoxMonth.setModel(new DefaultComboBoxModel(months));
if(si.birthdate!=null)
{
comboBoxMonth.setSelectedIndex(Integer.parseInteger(dateofbirth(si.birthdate)[1]) - 1);
}

For other developer with the same issue:
A closer look into the implementation of setSelectedItem(Object anObject) from JComboBox might help:
public void setSelectedItem(Object anObject) {
Object oldSelection = selectedItemReminder;
Object objectToSelect = anObject;
if (oldSelection == null || !oldSelection.equals(anObject)) {
if (anObject != null && !isEditable()) {
// For non editable combo boxes, an invalid selection
// will be rejected.
boolean found = false;
for (int i = 0; i < dataModel.getSize(); i++) {
E element = dataModel.getElementAt(i);
if (anObject.equals(element)) {
found = true;
objectToSelect = element;
break;
}
}
if (!found) {
return;
}
}
...
In the loop your object is compared with an object of the dataModel with the specific type E. In the implementation of equals() from String you can see a verification of class/interface, length and each character one after another. That means, our object must have same type and all characters must be the same!
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
And this is the most annoying part if (anObject.equals(element)) in setSelectedItem! You cant override equals method from your element. For example StudentInfo and compare other types like strings or integers to it. Simple example. You implement combobox like this JComboBox<StudentInfo> and you want to select the student with int id = 2;. So it compares now Integer with StudentInfo. Here you have to override equals from Integer...
My proposal is to swap it. Create own class, add boolean selectingItem and override setSelectedItem(Object anObject) and contentsChanged(ListDataEvent e)(this method one-to-one). Nevertheless, I had side effects in one project...

Use the following:
comboBoxMonth.setSelectedItem(index of the array);

The item you wish to set as selected must share the class of the objects stored in the JComboBox.
public static void main(String[] args) {
String[] items = {"1", "2", "3"};
JComboBox jcb = new JComboBox(items);
jcb.setSelectedItem(3);
System.out.println(jcb.getSelectedItem());
jcb.setSelectedItem(3+"");
System.out.println(jcb.getSelectedItem());
}
Output of the above code:
1
3

Related

JCombobox display text according to value

I have combobox which is filled with some items. Each item have display member and value member:
Vector model = new Vector();
model.addElement(new FilterValue("10000 Hz", 0));
model.addElement(new FilterValue("5000 Hz", 1));
model.addElement(new FilterValue("1000 Hz", 5));
model.addElement(new FilterValue("100 Hz", 50));
model.addElement(new FilterValue("10 Hz", 500));
model.addElement(new FilterValue("1 Hz", 5000));
public class FilterValue {
private final String label;
private final int value;
public FilterValue(String label, int value) {
this.label = label;
this.value = value;
}
public String getLabel() {
return label;
}
public int getValue() {
return value;
}
public String toString()
{
return label;
}
}
Initialization of JComboBox
cbFilter1 = new JComboBox(model);
cbFilter1.setBounds(176, 70, 90, 20);
cbFilter1.setSelectedIndex(-1);
pnlOUT1.add(cbFilter1);
cbFilter1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JComboBox comboBox = (JComboBox)e.getSource();
FilterValue item = (FilterValue)comboBox.getSelectedItem();
System.out.println( item.getValue() + " : " + item.getLabel() );
}
});
When I select for example 5000 Hz, display text is 5000 Hz, and value is 1.
The question is how to set value for example 5 and display 1000 Hz?
I have tried with
cbFilter1.setSelectedItem(5);
But there is no effect.
So you basically want to select the items either by their value or by their label.
The first (and simplest) thing I could think of to achieve this, is to create a Map object with the FilterValue as value. With this mapping you can simply use setSelectedItem on the ComboBox.
First copy the elements from your Vector:
Map<Integer, FilterValue> valueMap = new HashMap<>();
Map<String, FilterValue> labelMap = new HashMap<>();
model.forEach(filter -> {
valueMap.put(filter.getValue(), filter);
labelMap.put(filter.getLabel(), filter);
});
Then you could do something like this
String label = "5000 Hz";
cbFilter1.setSelectedItem(labelMap.get(label));
or this
int value = 5;
cbFilter1.setSelectedItem(valueMap.get(value));
It is then your choice how to collect the value (or label) of the FilterValue (maybe a JTextField or whatever)
Change your selected item:
cbFilter1 = new JComboBox(model);
cbFilter1.setBounds(176, 70, 90, 20);
cbFilter1.setSelectedIndex(5); // EDITED
pnlOUT1.add(cbFilter1);
cbFilter1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JComboBox comboBox = (JComboBox)e.getSource();
FilterValue item = (FilterValue)comboBox.getSelectedItem();
System.out.println( item.getValue() + " : " + item.getLabel() );
}
});
So you want the select a row by passing an existing value or label ?
The method setSeletedIndex(int index) expects an int corresponding of the number of the row (here, from 0 to 5).
You could use the method setSelectedItem(Object obj) to select the wanted FilterValue object.
Here is a simple method to help you select the correct FilterValue object from a given value :
/* Could do the same for label, using val.getLabel()
* and passing a String in parameter
*/
public void selectByValue(int value){
FilterValue row = null;
for(FilterValue val : model){ //Searching for the corresponding FilterValue
if(val.getValue() == value){
row = val;
}
}
cbFilter1.setSelectedItem(row); //Select the corresponding row
}
When calling this method like this
this.selectByValue(5);
It will search for the FilterValue in your Vector that have the value "5" and select the row of this object. This expects you don't have any values twice or it would select the first that appears.
Tested, and worked ;)
Hope it helped !
Thanks to all, I've found one solution that works fine in my case:
public static void setSelectedValue(JComboBox comboBox, int value)
{
FilterValue item;
for (int i = 0; i < comboBox.getItemCount(); i++)
{
item = (FilterValue)comboBox.getItemAt(i);
if (item.getValue() == value)
{
comboBox.setSelectedIndex(i);
break;
}
}
}

Find anywhere in jList items?

I can find item in jlist with this code. But I want to find anywhere in item. How can I do this. Thanks a lot. (Sorry my English)
For example: I can find "New or San" but I want to find "York or Diago".
New York
San Diago
jTextField1.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent e) {
String text = "" + e.getKeyChar();
StringBuffer buffer = new StringBuffer(jTextField1.getText().substring(0, jTextField1.getText().length() - 1));
buffer.append(text);
int index = jList1.getNextMatch(buffer.toString(), 0, Position.Bias.Forward);
jList1.setSelectedIndex(index);
}
});
getNextMatch checks if the given string exists at the start position passed as the second param. You can just traverse the jlist to find the index.
jTextField1.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent e) {
String text = "" + e.getKeyChar();
StringBuffer buffer = new StringBuffer(jTextField1.getText().substring(0, jTextField1.getText().length() - 1));
buffer.append(text);
ListModel<String> model = jList1.getModel();
int index;
for(int i = 0; i < model.getSize(); i++) {
if(model.getElementAt(i).contains(buffer.toString())){
index = i;
break;
}
}
jList1.setSelectedIndex(index);
}
});
I believe the method available in JList only searches if the items start with a specific prefix.
public List<Integer> getMatches(ListModel listModel, String text){
List<Integer> indices = new List<Integer>();
for(int i = 0; i < listModel.getSize(); i++){
if(listModel.getElementAt(i).contains(text)){
indices.add(i);
}
}
return indices;
}
The method above iterates the listmodel and checks if each element contains the text provided and returns the indices of matched items.

Bin Packing Algorithm In Need of Speeding-Up

I'm looking for an intelligent way to approach a version of the common bin-packing problem. Given a number of bags (as I'm calling them) with a certain capacity, and list of items that take up a certain amount of space, the task is to determine if all of the items can fit in the bags; and if so, how. I've got an exhaustive DFS working right now, but it takes... forever. My DFS is iterative and requires copying entire states at every step, which is very expensive. Here's my code for a specific problem with 4 bags with 10 capacity (the truly relevant portions of this code are just the pack() method and the State class if you don't want to look at it all):
import java.util.ArrayList;
import java.util.Stack;
public class BagProblem {
int numBags;
int bagCapacity;
ArrayList<Item> items = new ArrayList<Item>();
public static void main(String[] args) {
BagProblem bp = new BagProblem(4, 10);
bp.pack();
}
public BagProblem(int numBags, int bagCapacity) {
this.numBags = numBags;
this.bagCapacity = bagCapacity;
items = new ArrayList<Item>();
items.add(new Item("item0", 6));
items.add(new Item("item1", 6));
items.add(new Item("item2", 6));
items.add(new Item("item5", 3));
items.add(new Item("item6", 3));
items.add(new Item("item7", 3));
items.add(new Item("item8", 2));
items.add(new Item("item9", 2));
items.add(new Item("item10", 2));
items.add(new Item("item11", 2));
items.add(new Item("item12", 2));
items.add(new Item("item13", 2));
items.add(new Item("item14", 1));
}
// find a valid way to pack and print the items in each Bag, or
// print failure
public void pack() {
Stack <State> s = new Stack<State>();
Bag[] currBags = new Bag[numBags];
for (int i = 0; i < numBags; i++) {
currBags[i] = new Bag(bagCapacity);
}
s.push(new State(currBags));
while(!s.isEmpty()) {
State currState = s.pop();
for (Item i : items) {
if (!currState.containsItem(i)) {
State newState = new State(currState.bags);
newState.numItems = currState.numItems;
if (newState.addItem(i)) {
s.push(newState);
if (newState.numItems == items.size()) {
System.out.println("success");
System.out.println(newState);
return;
}
}
}
}
}
System.out.println("failure");
}
private class State {
Bag[] bags;
int numItems;
public State(Bag[] currBags) {
bags = new Bag[numBags];
for (int i = 0; i < numBags; i++) {
bags[i] = new Bag(bagCapacity);
}
// figure out how to actually copy this
for (int j = 0; j < numBags; j++) {
Bag bagToCopy = currBags[j];
for (Item item : bagToCopy.contents) {
Item newItem = new Item(item.name, item.size);
bags[j].size = bagToCopy.size;
bags[j].contents.add(newItem);
}
}
}
public boolean addItem(Item i) {
for (Bag b : bags) {
if (b.addItem(i)) {
numItems++;
return true;
}
}
return false;
}
public boolean containsItem(Item i) {
for (Bag b : bags) {
for (Item item : b.contents) {
if (item.name.equals(i.name))
return true;
}
}
return false;
}
public String toString() {
String output = "";
for (Bag b : bags) {
for (Item j : b.contents) {
output += j.name + " ";
}
output += "\n";
}
return output;
}
}
private class Bag {
int capacity;
int size;
ArrayList<Item> contents;
public Bag(int capacity) {
this.capacity = capacity;
this.size = 0;
contents = new ArrayList<Item>();
}
public boolean addItem(Item i) {
if(size + i.size > capacity)
return false;
contents.add(i);
size += i.size;
return true;
}
public String toString() {
String output = "";
for (Item i : contents) {
output += i.name + " ";
}
return output + "\n";
}
}
private class Item {
String name;
int size;
public Item(String name, int size) {
this.name = name;
this.size = size;
}
public String toString() {
return name;
}
}
}
After approximately one million years, this does spit out a correct answer (you probably won't want to actually wait that long if you try to run this):
success
item14 item7 item6 item5
item13 item12 item2
item11 item10 item1
item9 item8 item0
Each line indicates a separate bag. How can I speed this up? I know there are heuristics about trying to place the largest item first, etc., but what I'm really interested in is getting the basic DFS (or maybe I should try backtracking?) to have less overhead; I'll try to get fancier later.
Any help would be greatly appreciated.
I don't use Java but your implementation seems quite inefficient (as you've mentioned yourself) due to overcomplicating it. The algorithm itself is also very strange, I did not attempt to replicate it and just used the obvious O(bags^items) brute force algorithm that tries to put the first item into each bag, for each of those cases tries to put the second item into each bag, etc...
Instead of replicating the entire state repeatedly on the stack, you can put an item in a bag, explore the branch of the tree with this change, then take the item out of the bag.
Here is an example that completes instantly for your test case in C#.
static int[] itemSize;
static int[] bagFreeSpace;
static bool[,] doesBagContainItem; // in case this looks weird, [,] is a matrix, in java it would be [][]
static bool pack(int item)
{
// output the solution if we're done
if (item == itemSize.Length)
{
for (int i = 0; i < bagFreeSpace.Length; i++)
{
Console.WriteLine("bag" + i);
for (int j = 0; j < itemSize.Length; j++)
if (doesBagContainItem[i, j])
Console.Write("item" + j + "(" + itemSize[j] + ") ");
Console.WriteLine();
}
return true;
}
// otherwise, keep traversing the state tree
for (int i = 0; i < bagFreeSpace.Length; i++)
{
if (bagFreeSpace[i] >= itemSize[item])
{
doesBagContainItem[i,item] = true; // put item into bag
bagFreeSpace[i] -= itemSize[item];
if (pack(item + 1)) // explore subtree
return true;
bagFreeSpace[i] += itemSize[item]; // take item out of the bag
doesBagContainItem[i,item] = false;
}
}
return false;
}
static void Main(string[] args)
{
itemSize = new int[] { 6, 6, 6, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1 };
bagFreeSpace = new int[] { 10, 10, 10, 10 };
doesBagContainItem = new bool[bagFreeSpace.Length, itemSize.Length];
if (!pack(0))
Console.WriteLine("No solution");
}
Note: if you want to parallelize execution, you need to give each worker its own copy of the state (or 1 copy per job), but only at the point of branching, they can still then proceed as above, without replicating the state.

using a JButton actionperformed class how do I add elements from one arraylist to another arraylist?

I have a method that returns an arraylist which i am calling via a buttonListener. I need to be able to store each pushes resulting arraylist in another arraylist. How do I do this? Each time i try, it copies over the existing elements in the arraylist I'm using to keep track of push results.
private class ButtonListener implements ActionListener{
public void actionPerformed (ActionEvent e){
numCounter++;
String reqVal1 = requestor.getText();
int reqVal = Integer.parseInt(reqVal1);
request = reqVal;
requestsArray.get(3).set(0,0);
if(numCounter == 1){//---------------------------numCounter == 1 beginning-------- -------------------------
workingVar = memSize/2;
if(request>workingVar){
requestsArray.get(3).set(0,1);
}
else{
reqCounter++;
while (workingVar>=request){
workingVar = workingVar/2;
holes2.add(workingVar);
}
if(workingVar<request){
workingVar=workingVar*2;
holes2.add(workingVar);
holes2.remove(holes2.size()-2);
holes2.remove(holes2.size()-1);
}
}
e1=workingVar;
}//-----------------------------------------------end of numCounter == 1 section-------------------------------------
if(numCounter > 1){
for (int y = 0; y<requestsArray.get(0).size();y++){
if(requestsArray.get(1).get(y).equals("H")){
holes.add((Integer)requestsArray.get(0).get(y));
}
}
//BubbleSort of holes ArrayList
int in, out;
for(out= holes.size()-1; out>0;out--)
for(in =0; in<out;in++)
if(holes.get(in)<holes.get(in+1)){
int temp1 = holes.get(in+1);
int temp2 = holes.get(in);
holes.set(in, temp1);
holes.set(in+1, temp2);
}
//calculates the value of e1 using holes array
if(holes.isEmpty()){
requestsArray.get(3).set(0, 1);
}
else{
for(element=holes.size()-1;element>-1;element--){//starts at end of holes array loops backwards
e1 = holes.get(element); //assigns value of each element to e1
if(e1>=request) //if value e1 is greater than request stop looping
break;
}
workingVar=e1; //assign the value of e1 to workingVar
if (request>e1){
requestsArray.get(3).set(0, 1);
}
else{
//---------------------code for populating holes2 array---------------------------
reqCounter++;
if(workingVar!=request && workingVar/2>=request){
while (workingVar/2>=request){
workingVar = workingVar/2;
holes2.add(workingVar);
}
if(workingVar<request){
workingVar=workingVar*2;
holes2.add(workingVar);
}
}
}
}
}
//Sort of Holes2 ArrayList - reorder's holes2 for initial set up and subsequent inserts
int in, out;
for(out= holes2.size()-1; out>0;out--)
for(in =0; in<out;in++)
if(holes2.get(in)>holes2.get(in+1)){
int temp1 = holes2.get(in+1);
int temp2 = holes2.get(in);
holes2.set(in, temp1);
holes2.set(in+1, temp2);
}
//-------------------------------requestsArray Setups----------------------------------------------------
//Initial setup of requestsArray
if(numCounter == 1){
if(requestsArray.get(3).get(0).equals(0)){
requestsArray.get(0).set(0,e1);
requestsArray.get(1).set(0,"R");
requestsArray.get(2).set(0, reqCounter);;
for(int i = 0; i<holes2.size();i++){
requestsArray.get(0).add(holes2.get(i));
requestsArray.get(1).add("H");
requestsArray.get(2).add(0);
}
}
else{
requestsArray.get(0).set(0,e1);
requestsArray.get(1).set(0, "H");
requestsArray.get(2).set(0,0);
}
}
//Subsequent setup of requestsArray
int element2;
if(numCounter >1 && requestsArray.get(3).get(0).equals(0)){
for(element2 = 0; element2< requestsArray.get(0).size(); element2++){
if((Integer)requestsArray.get(0).get(element2)==e1 &&requestsArray.get(1).get(element2).equals("H") ){
break;
}
}
if(holes2.isEmpty()){
requestsArray.get(1).set(element2, "R");
requestsArray.get(2).set(element2, reqCounter);
}
else{ //holes2 is not empty
requestsArray.get(0).add(element2, workingVar);
requestsArray.get(2).add(element2,reqCounter);
requestsArray.get(1).add(element2, "R");
requestsArray.get(0).remove(element2+1);
requestsArray.get(2).remove(element2+1);
requestsArray.get(1).remove(element2+1);
for(int i = 1; i<holes2.size()+1;i++){
requestsArray.get(0).add(element2+i,holes2.get(i-1));
requestsArray.get(1).add(element2+i,"H");
requestsArray.get(2).add(element2+i,0);
}
}
}
//-----------------End Section for populating requestsArraywhen numCounter > 1---------------------------
//remove all values from holes1 and holes2
holes.clear();
holes2.clear();
System.out.println(results1);
ok. I have written a similar program that is simpler and easier to understand. Each time the button is pressed, the result is saved as an arrayList to another arrayList. Problem is it's appending it to the previous element. I need to be able to add the results of each press as a separate element. For example:
first press:
[5, 3, 5, 2, 6, 5]
second press would display:
[5, 3, 5, 2, 6, 5][2, 1, 4, 1, 4, 1]
This way I can loop through and get each array result separately. How do I do this?
public class mainClass{
public static void main(String[] args){
JFrame frame1 = new JFrame("testButton");
frame1.setDefaultCloseOperation(JFrame. EXIT_ON_CLOSE);
buttonExample b1 = new buttonExample();
frame1.getContentPane().add(b1);
frame1.pack();
frame1.setVisible(true);
}
}
public class Example {
private int rand1;
private ArrayList<ArrayList> count;
private ArrayList<Integer> count2;
private Random rnd;
private int counter1;
private ArrayList<ArrayList>count3;
public Example(){
count = new ArrayList<ArrayList>();
count2 = new ArrayList<Integer>();
rnd = new Random();
count3 = new ArrayList<ArrayList>();
}
private void addCount2(){
for(int x = 0; x<6;x++){
rand1 = rnd.nextInt(6)+1;
count2.add(rand1);// count2 == Integers
}
}
public void addCount(){
addCount2();
count.add(count2);// count == count3
}
public ArrayList<ArrayList> displayCount(){
return count;
}
}
public class buttonExample extends JPanel {
private JButton button1;
private Example example1;
public buttonExample(){
button1 = new JButton("Submit");
add(button1);
button1.addActionListener(new ButtonListener());
example1 = new Example();
}
private class ButtonListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
example1.addCount();
System.out.println(example1.displayCount().get(0));;
}
}
}
I would think about at least two solutions...
create a List<...> list which will last (global variable or something similar, depends on your needs) and use list.addAll() method
create a Map<String, List<...> map and than you can log your lists separately, your key might be a timestamp for example
Well, now when you posted the code you will have to start with a different thing - refactoring. Your code is very long, difficult to read and error prone. You have to think about it a little bit a rewrite it. And trust me, the more effort you put into your code at the beginning the better it will be at the end. Otherwise you may end up with an unmanagable code full of bugs...

In Java/Swing, is there a way to legally "attempt to mutate in notification"?

I was wondering if there is some sort of magic I can use to get around an IllegalStateException and allow a JTextField to "attempt to mutate in notification", or in other words to set its own text if its listener is triggered.
For your information, I am trying to program an auto-complete function which returns the most likely match in a range of 12 enums in response to a user's input in the JTextField.
Here is the code sample. You'll have to pardon my clumsy algorithm which creaks out enum results. I've highlighted the code which produces the exception with a comment:
jtfElement1.addCaretListener(new CaretListener() {
#Override
public void caretUpdate(CaretEvent e) {
String s = jtfElement1.getText();
int[] attributes = new int[13];
// iterate through each enum
for (BaseEnumAttributes b: BaseEnumAttributes.values()) {
// iterate through the length of the current text in jtfElement1
for (int i = 0; i < s.length(); i++) {
if (s.length() <= b.toString().length()) {
if (b.toString().charAt(i) == s.charAt(i)) {
// increase the number of "hits" noted for that enum
attributes[b.ordinal()] = attributes[b.ordinal()] + 1;
}
}
}
}
int priorC = 0;
int rightC = 0;
// iterate through the "array" of enums to find the highest score
for (int j = 0; j < attributes.length; j++) {
if (attributes[j] > priorC) {
priorC = attributes[j];
rightC = j;
}
}
if (!s.equals("")) {
// assign to b the Enum corresponding to the "array" with highest score
BaseEnumAttributes b = BaseEnumAttributes.values()[rightC];
iController.updateInputElement1String(b.toString());
// THIS TRIGGERS EXCEPTION
jtfElement1.setText(b.toString());
}
}
});
You are probably better off using a document filter or a custom document.
What are other listeners expected to see if the document doesn't stay the same during event dispatch?
Use SwingUtilities.invokeLater() placing all the modifications there
Maybe you can delay the setText() with a Thread to run after caretUpdate() has terminated.
i'm found on the same problem but i found an easy solution:
lock the caretUpdate() by a boolean if(false) while u'r setting the text to the jTextField than unlock it after . . something like this:
boolean caret = true;
private void listValueChanged(javax.swing.event.ListSelectionEvent evt) {
caret = false;
name.setText((String)list.getSelectedValue());
caret = true;
}
private void nameCaretUpdate(javax.swing.event.CaretEvent evt) {
if(caret){
model = new DefaultListModel();
this.fillList(name.getText());
list.setModel(model);
}
}
Create a custom Document and override insertString( )
filenameText = new JTextField(new FilenameDocument(), "", 0);
...
/**
* document which adds .xml extension if not specified
*
*/
private class FilenameDocument extends PlainDocument {
#Override
public void insertString(int offset, String insertedText, AttributeSet set)
throws BadLocationException {
if (offset == 0) {
insertedText = insertedText.trim( );
}
super.insertString(offset, insertedText, set);
if (filenameText != null) {
final int caretPos = filenameText.getCaretPosition();
String text = filenameText.getText().trim();
if (text.indexOf('.') == -1) {
filenameText.setText(text + ".xml");
filenameText.setCaretPosition(caretPos);
}
}
}
}
Note that calling setText will result in a recursive call to insertString( ), so make sure you have a stopping condition.
I'm surprised no one has answered this, but would'nt you have been better off implementing an editable JSpinner with a SpinnerListModel?

Categories