JComboBox: setting the editable text

B

Ben Phillips

It should be possible to set the editable text in a JComboBox
programmatically, for instance if it's a text box with a drop down list
of recently used files, with a Browse... button nearby that pops up a
JFileChooser to select a file; when the file chooser is used, the combo
box text should be set to the chooser-selected file's path.

This isn't covered in the Java Tutorial. After studying the API docs, I
came up with:

myComboBox.getEditor().setItem(theFile.getPath());

Is this the best/a correct way to do it?
 
B

Ben Phillips

Ben said:
It should be possible to set the editable text in a JComboBox
programmatically, for instance if it's a text box with a drop down list
of recently used files, with a Browse... button nearby that pops up a
JFileChooser to select a file; when the file chooser is used, the combo
box text should be set to the chooser-selected file's path.

This isn't covered in the Java Tutorial. After studying the API docs, I
came up with:

myComboBox.getEditor().setItem(theFile.getPath());

Is this the best/a correct way to do it?

Nope. I have tried it now, and it behaves in a very interesting but
generally useless way.

If the combobox editor is empty, this seems to assign it some text. If
the combobox editor is non-empty, it seems to do absolutely nothing.

Getting the item out of the combobox is equally troublesome: the
combobox method returns null sometimes, even when there is text in the
box! There, myComboBox.getEditor().getItem().toString() seems to do the
trick.

But there doesn't seem to be a simple way of changing the text
programmatically in a way that is indistinguishable in its semantics to
the user pasting a line of text into the edit field!

Or if there is, it's not obvious what it is from the API, or explained
in the tutorial.

(And in the meantime you may have noticed that my other post has now
appeared twice. Stupid news server apparently got "clogged" somehow, and
until I posted again the first post wouldn't appear, but as soon as I
did post again it apparently pushed out the existing post that was ahead
of it in the up-to-then stalled queue.

In other words, there was no way to avoid double-posting ... don't post
again and it never appears, do post again and it promptly appears twice.
Arrrgh. Who designs these things?)
 
B

Ben Phillips

Larry said:
I don't think there is any "good" way to do it. You can set the
editor to your own subclass of BasicComboBoxEditor that does
what you need. It is a bit tricky to get it to work and to keep the
Look & Feel of the editor (you can copy relevant properties from
a reference combo box editor that is under the current Look &
Feel, and doing this just for the border gives a pretty good result).

What???

This should be exceedingly simple, no more complex than programmatically
setting the text in an editable JTextField, for Christ's sake.

I want a second opinion.
 
R

RedGrittyBrick

Ben said:
What???

This should be exceedingly simple, no more complex than programmatically
setting the text in an editable JTextField, for Christ's sake.

I want a second opinion.

String fileName = theFile.getPath();
myComboBox.setItem(fileName);
myComboBox.setSelectedItem(fileName);

Does the above not work for you?
 
N

Nigel Wade

Ben said:
Nope. I have tried it now, and it behaves in a very interesting but
generally useless way.

If the combobox editor is empty, this seems to assign it some text. If
the combobox editor is non-empty, it seems to do absolutely nothing.

It works here.
Getting the item out of the combobox is equally troublesome: the
combobox method returns null sometimes, even when there is text in the
box! There, myComboBox.getEditor().getItem().toString() seems to do the
trick.

But there doesn't seem to be a simple way of changing the text
programmatically in a way that is indistinguishable in its semantics to
the user pasting a line of text into the edit field!

Maybe you could post your code and/or explain better exactly what you're doing
and how it fails.

This code thrown together very quickly in Netbeans does what I expect. I press
jButton1 and it sets the editable text to ONE, press jButton2 and it sets the
text to TWO, regardless of what I have entered into the editable field:

public class TestSetCombo extends javax.swing.JFrame {
public TestSetCombo() {
initComponents();
}

private void initComponents() {

jComboBox1 = new javax.swing.JComboBox();
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new java.awt.FlowLayout());

jComboBox1.setEditable(true);
jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[]
{ "Item 1", "Item 2", "Item 3", "Item 4" }));
getContentPane().add(jComboBox1);

jButton1.setText("jButton1");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
getContentPane().add(jButton1);

jButton2.setText("jButton2");
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});
getContentPane().add(jButton2);

pack();
}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
jComboBox1.getEditor().setItem("ONE");
}

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
jComboBox1.getEditor().setItem("TWO");
}

public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new TestSetCombo().setVisible(true);
}
});
}

private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JComboBox jComboBox1;

}
 
B

Ben Phillips

Nigel said:
Maybe you could post your code and/or explain better exactly what you're doing
and how it fails.

The code is basically just comboBox.setSelectedItem(string).

The particular observations:

Initially empty combo box with empty item list.

The editable part is altered with comboBox.setSelectedItem(string).

A JButton is clicked that submits the dialog. It hides but doesn't
dispose, and the item that was entered is added to the combo box's item
list. (It's meant as an mru list.)

Subsequently the dialog is redisplayed and the combo box contains the
previous string (as intended); the drop-down list has only the one item.

Then comboBox.setSelectedItem(anotherString).

The new string does not replace the old in the editable part of the
combo box. It remains showing the previous string, equal to the one
drop-down item.

The same thing happens with comboBox.getEditor().setItem(). Which
comboBox.setSelectedItem() probably calls anyway.

This and the ImagingOpException issue not happening to you guys suggest
that my copy of Java has some oddities.

I get this from java -version:

Java HotSpot(TM) Client VM (build 1.6.0-rc-b104, mixed mode)
 
B

Ben Phillips

RedGrittyBrick said:
String fileName = theFile.getPath();
myComboBox.setItem(fileName);
myComboBox.setSelectedItem(fileName);

Does the above not work for you?

Nope. No such method setItem(String).

The Javadocs for setSelectedItem, up to the end of the second paragraph
of description:

public void setSelectedItem(Object anObject)

Sets the selected item in the combo box display area to the object
in the argument. If anObject is in the list, the display area shows
anObject selected.

If anObject is not in the list and the combo box is uneditable, it
will not change the current selection. For editable combo boxes, the
selection will change to anObject.



**If anObject is not in the list ... for editable combo boxes, the
selection will change to anObject.**

This behavior is not apparently actually occurring if a list item is
currently selected.

It's possible I've found a bug.
 
B

Ben Phillips

Actually, I did not write that. Please pay more attention to quoting and
attribution when you post replies to usenet posts.

Regardless, addItem() has the problem that I don't want to expand the
combo box's list by everything that ever gets selected and displayed in
it; only by those that are in the edit box when the user clicks OK (and
to a maximum number of items).

In fact, I've solved this problem now anyway. The combo box constructors
that accept a prepopulated list of selections take either a
ComboBoxModel, array, or Vector (no List?!); and there don't seem to be
any methods to get the list back out or do a wholesale replacement,
except for ComboBoxModel, and I didn't feel like learning yet another
chunk of new API to get this up and running. So the choice was between
the array and Vector versions. An array would have the problem of having
several nulls at the end until it was fully populated, so I picked
Vector, archaic though that collection class is. (No ArrayList?!)

So the Vector is populated and shuffled as needed, but the only way to
completely replace the combobox's list with a new one in this case is
apparently to completely replace the combobox.

Unfortunately, the combobox the code referenced was being switched with
the new one, but it wasn't being added (or the old one removed) to the
JPanel containing it.

The user (so far, that means me, in testing mode) ended up manipulating
the old combo box, so on the second and subsequent showings of the
dialog, changing this didn't change the value the dialog returned. Hence
some problems I was having with the getItem(). And the setItem() was
altering an invisible extra combo box, not the one shown in the UI.

Argh.

At some later date, I'm going to refactor this class and probably learn
ComboBoxModel and even subclass the darn thing to make one that subsumes
the MRU-list functionality, shuffling and all that, into itself and
leaves the main dialog class code to focus on the UI stuff.

For now, I've added in code to change out the combo box being displayed
by the JPanel and tested it, and it works.

Case closed.

Send all insults, off-topic ramblings, conspiracy theories, and other
nonsense to /dev/null, please.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top