Using JComboBoxes in a JTable

  • Follow


I am trying to make a list of JComboBoxes. My first try was to put the
JComboBoxes in a JList but my solution did never really work. I
managed to get them in the JList, but I could not interact with the
JComboBoxes.

My current solution for getting a list of JComboBoxes is to put them
in a JTable. As before I manage to get them in there, but they dont
behave as they should. In this solution I can interact with the
JComboBoxes but the problem is that when I select a value from one
JComboBox, then the JComboBoxes that I have not interacted with all
get that value selected in their JComboBoxes too.

In the sample below I have 4 JComboBoxes, here is the code:

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JTable;
import javax.swing.WindowConstants;
import javax.swing.JFrame;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

public class NewJPanel extends javax.swing.JPanel {
	public class MyComboBoxRenderer extends JComboBox implements
TableCellRenderer {
        public MyComboBoxRenderer(String[] items) {
            super(items);
        }

        public java.awt.Component getTableCellRendererComponent(JTable
table, Object value,
                boolean isSelected, boolean hasFocus, int row, int
column) {
            if (isSelected) {
                setForeground(table.getSelectionForeground());
                super.setBackground(table.getSelectionBackground());
            } else {
                setForeground(table.getForeground());
                setBackground(table.getBackground());
            }

            // Select the current value
            setSelectedItem(value);
            return this;
        }
    }

	/**
	* Auto-generated main method to display this
	* JPanel inside a new JFrame.
	*/
	public static void main(String[] args) {
		JFrame frame = new JFrame();
		frame.getContentPane().add(new NewJPanel());
		frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		frame.pack();
		frame.setVisible(true);
	}

	public NewJPanel() {
		super();
		initGUI();
	}

	private void initGUI() {
		try {
			this.setLayout(new FlowLayout());
			setPreferredSize(new Dimension(400, 300));
			JTable table = new JTable();
		    DefaultTableModel model = (DefaultTableModel)table.getModel();

		    // Add some columns
		    model.addColumn("A");
		    model.addRow(new String[]{""});
		    model.addRow(new String[]{""});
		    model.addRow(new String[]{""});
		    model.addRow(new String[]{""});

		    // These are the combobox values
		    String[] values = new String[]{"item1", "item2", "item3"};

		    // Set the combobox editor on the 1st visible column
		    int vColIndex = 0;
		    TableColumn col = table.getColumnModel().getColumn(vColIndex);
		    col.setCellEditor(new DefaultCellEditor(new JComboBox(values)));

		    // If the cell should appear like a combobox in its
		    // non-editing state, also set the combobox renderer
		    col.setCellRenderer(new MyComboBoxRenderer(values));

		    add (table);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


Can someone tell me how I could correct my code to make it work?
Or have someone incorporated JComboBoxes in a JList or in a JTable and
feel like sharing the code I would be very happy.




0
Reply marcussilfver 12/10/2007 1:49:01 PM

marcussilfver@gmail.com wrote:
> I am trying to make a list of JComboBoxes. My first try was to put the
> JComboBoxes in a JList but my solution did never really work. I
> managed to get them in the JList, but I could not interact with the
> JComboBoxes.
> 
> My current solution for getting a list of JComboBoxes is to put them
> in a JTable. As before I manage to get them in there, but they dont
> behave as they should. In this solution I can interact with the
> JComboBoxes but the problem is that when I select a value from one
> JComboBox, then the JComboBoxes that I have not interacted with all
> get that value selected in their JComboBoxes too.
> 
> In the sample below I have 4 JComboBoxes, here is the code:

[snip]

> 		    // Set the combobox editor on the 1st visible column
> 		    int vColIndex = 0;
> 		    TableColumn col = table.getColumnModel().getColumn(vColIndex);
> 		    col.setCellEditor(new DefaultCellEditor(new JComboBox(values)));

You appear to have used a single new JComboBox as the cell editor for 
every row in the column.

[snip]

> 
> Can someone tell me how I could correct my code to make it work?
> Or have someone incorporated JComboBoxes in a JList or in a JTable and
> feel like sharing the code I would be very happy.
> 

I don't see why you are embedding these JComboBoxes in a JList or 
JTable. I'd just use a BoxLayout or GridLayout. Presumably there's some 
reason other than layout?
0
Reply RedGrittyBrick 12/10/2007 3:03:05 PM


I have working combo boxes in a table.  My code looks like yours but I 
don't set the cell renderer.

If you omit setting the cell renderer it will work.  The cell will look 
like a string except when you are editing it.  Nothing wrong with that.  
You have to click in the cell to see that it is a drop down list.

I thought it would be interesting to see if your cell editor is ever 
invoked.  I added your code for MyComboBoxRenderer with an added action 
listener, plus an action listener on the combo box used as a cell editor.  
I found that when you change the value using the mouse, the cell editor 
combo box action listener is invoked once but the cell renderer combo box 
action listener is invoked multiple times.

I found that when you change the value using the mouse, all the other rows 
that have not been set with the mouse change also.  All the other rows that 
have been set at least once with the mouse behave as desired.  Once all 
rows have been set with the mouse, it works as desired.  You could possibly 
exploit this to get the behaviour you want but it would be a hack and would 
probably break in the future.

I have some suggestions.

1. don't set the cell renderer.

2. render the cell to look like a combo box but not actually *be* a combo 
box (using the default renderer which is a JLabel iirc).

3. make the rendering combo box uneditable.  Might work.  Perhaps you could 
change the rendering combo box to all ignore all mouse clicks or reroute 
them to editing combo box.

I tried the following without success (but they might be made to work).
a. overriding validate, revalidate, repaint, and firePropertyChange (as 
DefaultTableCellRenderer does) in the rendering combo box to be no-ops (see 
javadoc for DefaultTableCellRenderer).

b. make the renderer to be a DefaultTableCellRenderer and override paint to 
call paint on a combo box.
0
Reply Tom 12/11/2007 3:16:29 AM

On Dec 10 2007, 10:16=A0pm, Tom N <t...@tom.n> wrote:
> I have working combo boxes in a table. =A0My code looks like yours but I
> don't set the cell renderer.
>
> If you omit setting the cell renderer it will work. =A0The cell will look
> like a string except when you are editing it. =A0Nothing wrong with that. =
=A0
> You have to click in the cell to see that it is a drop down list.
>
> I thought it would be interesting to see if your cell editor is ever
> invoked. =A0I added your code for MyComboBoxRenderer with an added action
> listener, plus an action listener on the combo box used as a cell editor. =
=A0
> I found that when you change the value using the mouse, the cell editor
> combo box action listener is invoked once but the cell renderer combo box
> action listener is invoked multiple times.
>
> I found that when you change the value using the mouse, all the other rows=

> that have not been set with the mouse change also. =A0All the other rows t=
hat
> have been set at least once with the mouse behave as desired. =A0Once all
> rows have been set with the mouse, it works as desired. =A0You could possi=
bly
> exploit this to get the behaviour you want but it would be a hack and woul=
d
> probably break in the future.
>
> I have some suggestions.
>
> 1. don't set the cell renderer.
>
> 2. render the cell to look like a combo box but not actually *be* a combo
> box (using the default renderer which is a JLabel iirc).
>
> 3. make the rendering combo box uneditable. =A0Might work. =A0Perhaps you =
could
> change the rendering combo box to all ignore all mouse clicks or reroute
> them to editing combo box.
>
> I tried the following without success (but they might be made to work).
> a. overriding validate, revalidate, repaint, and firePropertyChange (as
> DefaultTableCellRenderer does) in the rendering combo box to be no-ops (se=
e
> javadoc for DefaultTableCellRenderer).
>
> b. make the renderer to be a DefaultTableCellRenderer and override paint t=
o
> call paint on a combo box.

I have the same problem.  I took out the renderer and it works as
desired.  However I would like to implement you option #2.  My user
needs to know that there is an option there.  How would I go about
making the cell look like a comboBox but not be a comboBox?  Thanks
for the help.

~Clark
0
Reply lisaspamster 1/2/2008 8:30:11 PM

lisaspamster wrote:

> Tom N wrote:
>> I have some suggestions.
>>
>> 1. don't set the cell renderer.
>>
>> 2. render the cell to look like a combo box but not actually *be* a
>> combo box (using the default renderer which is a JLabel iirc).
>>
>> 3. make the rendering combo box uneditable. �Might work. �Perhaps you
>> could change the rendering combo box to all ignore all mouse clicks
>> or reroute them to editing combo box.
>>
>> I tried the following without success (but they might be made to
>> work). a. overriding validate, revalidate, repaint, and
>> firePropertyChange (as DefaultTableCellRenderer does) in the
>> rendering combo box to be no-ops (see
>> javadoc for DefaultTableCellRenderer).
>>
>> b. make the renderer to be a DefaultTableCellRenderer and override
>> paint to call paint on a combo box.
>
> I have the same problem.  I took out the renderer and it works as
> desired.  However I would like to implement you option #2.  My user
> needs to know that there is an option there.  How would I go about
> making the cell look like a comboBox but not be a comboBox?  Thanks
> for the help.

The simplest way would be to draw both an icon and a label on the 
DefaultTableCellRenderer - since it is a JLabel subclass, that should be 
straightforward.  The icon would be the same as the one on a comboBox.  
You *might* have a problem to get a DefaultTableCellRenderer to look 
exactly the same as a comboBox.

You might also be able to do it by setting up a DefaultTableCellRenderer 
subclass to override paint to call paint on a combo box.

In any case, it won't work the same.   In some circumstances, you have to 
click on the cell with the combo box to give it focus then click on the 
down-arrow icon to get the drop-down list.  If it looks like a combo box 
to start with, the user would expect to be able to click on the down-arrow 
icon once to get the drop down list, not twice.

It doesn't seem to be consistent (I'm using JRE 1.6.0_01).  If you click 
on a combo box cell and the focus was on already on a different combo-box 
cell in the same column, you have to click twice to get the drop-down 
list.  If you click on a combo box cell and the focus was not as above, 
you get the drop-down list immediately.

A hack that might work is to exploit the fact that if you click on an 
combo-box empty cell, you immediately get a drop-down list (whereas if you 
click on a combo box cell with no value, you have to click again to get 
the drop-down list).

You could set up the table model to be always empty in the cell, but have 
the renderer for that cell fetch the displayed value from elsewhere, and 
set up the table model so that when the value was set, it stashed the new 
value elsewhere and reset the model value to be empty.

0
Reply Tom 1/17/2008 10:23:41 AM

4 Replies
609 Views

(page loaded in 0.121 seconds)

Similiar Articles:













7/24/2012 11:25:34 AM


Reply: