Need help figuring out JComboBox too small

Wondering if the brilliant GUI minds here can help me understand behaviour and sizing of JComboBox objects. Looked everywhere for good explanations to my questions and I turn up nothing so this is the next step.

My problem is that we upgraded to JRE 1.5 from 1.3 and comboboxes are remaining static and consistent to a certain mediocre size. The drop down list cuts off the remaining text, in other words it is not wide enough.

It used to behave in a manner where the ComboBox's preffered size adjusted to the contents of its DefaultComboBoxModel.

Am I right to assume this is the appropriate functionality?

Keep in mind I did not write this code but I am merely trying to fix this problem.

The author extended DefaultComboBoxModel and its public Object getElementAt(int i) method.

Am I right to assume that the JComboBox calls this method in its model, to retrieve data for display, and for resizing its width appropriately, or does it call a different method like getItem?

I suspect that the problem lies with the overriden getElementAt method.

[1096 byte] By [maple_shafta] at [2007-11-27 11:06:32]
# 1

I believe it uses the first item for the size.... unless you call setPrototypeDisplayValue() with a value that the renderer can use to define the preferred size. That could be the longest string in the combobox, or whatever.

Overriding the method getElementAt doesn't have anything to do with it, it has to return a value to work otherwise.

bsampieria at 2007-7-29 13:16:03 > top of Java-index,Desktop,Core GUI APIs...
# 2

> I believe it uses the first item for the size....

Nope, it uses the size of the largest item.

The OP has a problem in the custom code.

If you need further help then you need to create a "Short, Self Contained, Compilable and Executable, Example Program (SSCCE)",

see http://homepage1.nifty.com/algafield/sscce.html,

that demonstrates the incorrect behaviour, because I can't guess exactly what you are doing based on the information provided.

Don't forget to use the "Code Formatting Tags",

see http://forum.java.sun.com/help.jspa?sec=formatting,

so the posted code retains its original formatting.

camickra at 2007-7-29 13:16:03 > top of Java-index,Desktop,Core GUI APIs...
# 3

Thank you both for your replies!

I am going to try using the getPrototypeDisplay method to see what object is being used to set this combobox's preferred size.

If this method works the way you say it will, I should be able to retrieve the largest string from a collection and pass that as the prototype!

I will let you know how it works.

Unfortunately due to the complexity of this application, it would be a serious effort to try and SSCE this problem. That will be my last resort.

maple_shafta at 2007-7-29 13:16:03 > top of Java-index,Desktop,Core GUI APIs...
# 4

If camickr is right (and he usually is), setPrototypeDisplay won't matter.

Actually the exception I can think of is if the data model for the combobox contains only some values when the combobox is created, then is updated with longer ones. Then it might not get resized, and that's where the set prototype thing comes in to preset it to what you know will be the largest at some point.

Message was edited by:

bsampieri

bsampieria at 2007-7-29 13:16:03 > top of Java-index,Desktop,Core GUI APIs...
# 5

Well believe it or not though the setPrototypeDisplay method ACTUALLY WORKED.

Added this simple little Data Object inner class:

private class StringIntegerDataObject implements Comparable {

String text;

Integer num;

StringIntegerDataObject(String text, Integer num) {

this.text = text;

this.num = num;

}

public int compareTo(Object o) {

if (o instanceof StringIntegerDataObject) {

StringIntegerDataObject dataObject = (StringIntegerDataObject)o;

return num.compareTo(dataObject.num);

} else {

return num.compareTo((Integer)o);

}

}

}

Then added this nifty little code in the contentsChanged method of my DefaultComboBoxModel class so that everytime the model changes, my comboBox size gets updated with the largest String...

List availableVals = getModel().getAvailableValues();

if (availableVals.size() != 0) {

StringIntegerDataObject largest = new StringIntegerDataObject(((MapDatabaseObject)availableVals.get(0)).getText(),

new Integer(((MapDatabaseObject)availableVals.get(0)).getText().length()));

for (Iterator i = availableVals.iterator(); i.hasNext();) {

MapDatabaseObject mdo = (MapDatabaseObject)i.next();

String text = mdo.getText();

StringIntegerDataObject currValue = new StringIntegerDataObject(text, new Integer(text.length()));

if (largest.compareTo(currValue) < 0)

largest = currValue;

}

//Set the largest string (+1 because some characters are bigger than others) as the combobox prototype.

comboBox.setPrototypeDisplayValue(largest.text + " ");

}

Hack?

Maybe... but you are both right. There very well maybe something wrong with the custom code in getElementAt but this just happens to remedy the GUI issues I have been having and since I was tasked with solving 30 of these durn issues by Friday, I am beyond the point of caring about the PROPER way to fix these problems.

Besides... just found out that the company is switching over to .NET (the Dark Side) so this application will likely be scrapped and rewritten next year anyway.

Thanks for your help, I likely may start some more topics here before the end of the week.

maple_shafta at 2007-7-29 13:16:03 > top of Java-index,Desktop,Core GUI APIs...
# 6

> Then added this nifty little code in the contentsChanged method of my

> DefaultComboBoxModel class so that everytime the model changes,

I didn't understand from the original question that this is a dynamically changing combo box.

The size of the component is first determined when the component is added to the GUI and the frame is made visible. Dynamically changing the model may not change the size of the component. You need to invoke the layout manager to lay out the component again if you are potentially changing the size of one or more of the components on the panel. So after setting the model I would try using:

panel.revalidate();

panel.repaint();

Assuming the components have space to grow the components should be layed out at there new preferred sizes.

camickra at 2007-7-29 13:16:03 > top of Java-index,Desktop,Core GUI APIs...
# 7

I am sorry, I should have been more specific...

But thanks for the tip!

maple_shafta at 2007-7-29 13:16:03 > top of Java-index,Desktop,Core GUI APIs...