How to insert a JList into a JTable

as the title suggests, I have a JList (well, my extension of it, which changes very little so is essentially the same) and I would like to insert it into a JTable. Does anyone have any ideas as to how to do this?

I have the column for the table by doing this:

TableColumn col = _table.getColumnModel().getColumn(a);
where _table is a Table and a is the column number.

Thanks for your help.
yeggstryAsked:
Who is Participating?
 
armoghanCommented:
That is how you can add a JButton to JTable
similar approach is required for JList

http://www.devx.com/getHelpOn/10MinuteSolution/20425
0
 
TimYatesCommented:
You wil have to go through the TableModel, not the column

JList and JTable are on two different branches of the swing class tree, so it's not as easy as you might think

Go through the items in your ListModel, and add them to the TableModel at the column you want...

Tim
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

 
yeggstryAuthor Commented:
ok, I dont think I explained the question very well.

I have a JTable with other items in it (JComboBox, JText etc.) and want a JList in a particular cell (as in a drop down that I can select multiple items from. I know that I cant use a combo box for this, so I wanted to use a List, but I cant find an easy way of adding this component to the table.

Do I use the thing you've suggested above, or do I have to use another solution?
0
 
zzynxSoftware engineerCommented:
>> want a JList in a particular cell (as in a drop down that I can select multiple items from.
Multiple items? So as a result you want your table cell to contain multiple values?
I think that's rather impossible.
0
 
yeggstryAuthor Commented:
the result of the cell will actually be a comma seperated list of ids of objects in the system I am using (as I said, I had to extend the JList a little to create my own method for that).
0
 
zzynxSoftware engineerCommented:
>> the result of the cell will actually be a comma seperated list of ids of objects in the system I am using
I see. That's possible indeed.
Then, I think you should indeed look at armoghan's link.
When pressing the button popup a dialog containing a JList + an <OK> and a <Cancel> button.
When <OK> is pressed the value is set according to the selected list items.
0
 
zzynxSoftware engineerCommented:
I do something similar for a column containing a bit mask.
But in my case I popup a dialog containing a check box for each possible bit (description)
They can select/unselect the check boxes as wanted and press <Set>.
That sets the mask value.
0
 
yeggstryAuthor Commented:
ok, I tried to use the code for the button thing to use the JList inside the table (which is what is wanted, not a seperate popup) and I can create one, but it only shows one line and I cant select a value. The JButton example is rather vague for what I want to do :(
0
 
zzynxSoftware engineerCommented:
>>the JList inside the table (which is what is wanted, not a seperate popup)
So you are going to squeeze that JList in just one table cell?
>> but it only shows one line
You see? ;°)
Or did you expect the table cell to change it's height accordingly?
The popup window is the way to go.
0
 
yeggstryAuthor Commented:
>>So you are going to squeeze that JList in just one table cell?
Yes, I have been told that it doesn't matter about the height of the rows if they are 3-4 rows high, meaning I can put a JList into it.
0
 
zzynxSoftware engineerCommented:
Don't get that.
Do you mean to say that the rows of your table are 3-4 row heights high?
0
 
yeggstryAuthor Commented:
no, but I have been told I can set them to 3-4 rows high if I need to
0
 
zzynxSoftware engineerCommented:
>>no, but I have been told I can set them to 3-4 rows high if I need to
That's right.
But, don't you think it will be surprisingly (and ugly) to see that row grow when you click on that column?
And shrink again when editing is done?

PS.
Putting a JList in that cell is not enough. You need at least one extra button to say you've done selecting.
Otherwise how will the JList "know" you've done selecting items?

What are your objections against popping up a small window containing the JList and <Set>/<Cancel> buttons?
0
 
yeggstryAuthor Commented:
>> What are your objections against popping up a small window containing the JList and <Set>/<Cancel> buttons?

Its not what the user wants if it can be avoided.

I never said I wasn't going to use the popup, I've been told that if I can do put a JList directly into the table then do it regardless of how "ugly" it may look.

i've been trying to doing it and am becoming more convinced that a popup is the option. The user aint gonna be happy, but they'll just have to accept it.
0
 
zzynxSoftware engineerCommented:
>> The user aint gonna be happy, but they'll just have to accept it
Often users can't estimate the (ugly) results of their (sometimes absurd, first thought) specifications

>> i've been trying to doing it and am becoming more convinced that a popup is the option
Sure it is.
The time you win by following that path, you can use to convince your user ;°)
0
 
objectsCommented:
> and want a JList in a particular cell (as in a drop down that I can select multiple items from.
>  I know that I cant use a combo box for this, so I wanted to use a List

Why don't you think you can use a combo?
JList's don't drop down, combo's do.
0
 
zzynxSoftware engineerCommented:
>>I do something similar for a column containing a bit mask.
>>But in my case I popup a dialog containing a check box for each possible bit (description)

I adapted that one to work as you want.
In case you're interested in a working example:

[1]

/*
 * MyValueCellEditor.java
 *
 */

import javax.swing.table.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
import java.util.List;

public class MyValueCellEditor extends DefaultCellEditor
                               implements ActionListener {
   
    private String value;
    private ListPanel contentPnl;
    private JComponent component;
    private JButton button;
    private JButton setButton;
    private JButton cancelButton;
   
    private class LocalEscDialog extends JDialog {
        private boolean bEscPressed = false;
        public LocalEscDialog(Frame frame, boolean modal) {
            super(frame, modal);
        }
        public void keyPressed(KeyEvent e)
        {
            if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                bEscPressed = true;
                setVisible(false);
            }
            else if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                setVisible(false); // pressing Enter is like pressing 'Set'
            }
        }
        public boolean isEscapePressed() {
            return bEscPressed;
        }
        public void setEscapePressed(boolean value) {
            bEscPressed = value;
        }
    };
   
    private class MyActionListener implements ActionListener {
        LocalEscDialog dlg = null;
        public MyActionListener(LocalEscDialog dlg) {
            this.dlg = dlg;
        }
        public void actionPerformed(ActionEvent e) {
            if (e.getSource()==cancelButton)
                dlg.setEscapePressed(true);
            else
                value = contentPnl.getValue();
            dlg.setVisible(false);
        }
    };
   
    public MyValueCellEditor() {
        super(new JTextField());
       
        component = new JPanel();
        component.setLayout(new BorderLayout());
       
        contentPnl = new ListPanel();
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(1,0,6,0));
        setButton = new JButton("Set");
        setButton.setMnemonic(KeyEvent.VK_S);
        buttonPanel.add(setButton);
        cancelButton = new JButton("Cancel");
        buttonPanel.add(cancelButton);
        JPanel southPanel = new JPanel();
        southPanel.add(buttonPanel);
       
        component.add(contentPnl, BorderLayout.CENTER);
        component.add(southPanel, BorderLayout.SOUTH);
        component.setBorder(BorderFactory.createMatteBorder(1,1,1,1,Color.black));
       
        button = new JButton();
        button.addActionListener(this);
       
        setClickCountToStart(2);
    }
   
    public Object getCellEditorValue() {
        return value;
    }
   
    // interface TableCellEditor
    public Component getTableCellEditorComponent(JTable table, Object value,
                                                 boolean isSelected,
                                                 int row, int column) {
       this.value = (String)value;
       contentPnl.setValue(this.value);
       return button;
    }

    // interface ActionListener
    public void actionPerformed(ActionEvent e) {
        LocalEscDialog dialog = new LocalEscDialog(JOptionPane.getFrameForComponent(button),true);
        MyActionListener listener = new MyActionListener(dialog);
        setButton.addActionListener(listener);
        cancelButton.addActionListener(listener);
        dialog.getRootPane().setDefaultButton(setButton);
        dialog.setUndecorated(true);
        dialog.setContentPane(component);
        dialog.pack();
        dialog.setLocationRelativeTo(button);
        dialog.show();
        if ( dialog.isEscapePressed() )
            fireEditingCanceled();
        else
            fireEditingStopped();
    }
   
    public class ListPanel extends JPanel {
        private JList theList;
        private List selected = new ArrayList();
       
        public ListPanel() {
            MyData data[] = { new MyData("One", 1),
                              new MyData("Two", 2),
                              new MyData("Three", 3),
                              new MyData("Four", 4),
                              new MyData("Five", 5) };
            theList = new JList(data);
            setLayout(new BorderLayout());
            add(new JScrollPane(theList));
        }
       
        public String getValue() {
            StringBuffer value = new StringBuffer();
            // Assemble the String according to the selection
            Object data[] = theList.getSelectedValues();
            for (int i=0; i<data.length; i++)
                value.append( ((i==0)?"":";") + ((MyData)data[i]).getValue() );
            return value.toString();
        }
        public void setValue(String value) {
            // Interpret the string and set the selection accordingly:
            String values[] = value.split(";");
            theList.clearSelection();
            ListModel model = theList.getModel();
            MyData data = null;
            for (int i=0; i<values.length; i++) {
                for (int j=0; i<model.getSize(); j++) {
                    data = (MyData) model.getElementAt(j);
                    if (data.getValue()==Integer.parseInt(values[i])) {
                        theList.addSelectionInterval(j,j);
                        break;
                    }
                }
            }
        }
    }
   
    public class MyData {
        private String name;
        private int value;
       
        public MyData(String name, int value) {
            this.name = name;
            this.value = value;
        }
        public int getValue() { return value; }
        public String getName() { return name; }
        public String toString() { return name; }
    }
}

[2] Program to demo the working of it:

/*
 * TableDemo.java
 *
 */

public class TableDemo extends javax.swing.JFrame {
   
    public TableDemo() {
        initComponents();
        setLocationRelativeTo(null); // center on screen
       
        theTable.getColumnModel().getColumn(1).setCellEditor( new MyValueCellEditor() );
    }
   
    private void initComponents() {
        jScrollPane1 = new javax.swing.JScrollPane();
        theTable = new javax.swing.JTable();

        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt);
            }
        });

        theTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {"Item 1", "1", "Whatever"},
                {"Item 2", "2", "You say it"},
                {"Item 3", "3", "Go ahead"},
                {"Item 4", "4", "example"}
            },
            new String [] {
                "Column 1", "MyValue", "Column 3"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class, java.lang.String.class
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }
        });
        jScrollPane1.setViewportView(theTable);

        getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);

        pack();
    }
   
    private void exitForm(java.awt.event.WindowEvent evt) {
        System.exit(0);
    }
   
    public static void main(String args[]) {
        try {
            javax.swing.UIManager.setLookAndFeel(
                javax.swing.UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception e) { }
        new TableDemo().show();
    }
   
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable theTable;
}

Remarks:
-----------
1) The code was originally written to make the popup dialog disappear when <ESC> is pressed.
    In the code above I ommitted that part. You see
           private class LocalEscDialog extends JDialog {
    while it was
           private class LocalEscDialog extends EscDialog {
    I changed that to not have to post the code of that EscDialog too.

2) I included the classes ListPanel and MyData in the class MyValueCellEditor for ease of posting.
    I recommend to make that separate classes.
0
 
yeggstryAuthor Commented:
Thanks to both armoghan and zzynx for your help, those two comments were the most helpful, so you get the points between you :)

thanks again
0
 
zzynxSoftware engineerCommented:
Thanks for accepting.

P.S.
Just for my interest:
1) Do you use the popup or the JList-in-the-cell approach at last? User convinced or not?
2) How did you expect our comments to be like for deserving an A grade?
0
 
yeggstryAuthor Commented:
1) I used the popup - the user aint happy, but I'll convince them :)
2) I dunno, I accepted it early in the morning for me and just clicked on anything that came to hand :P I guess I did B because it was a work-around solution to my problem rather than a direct solution (yes I know it is the only way to do it, but if other ppl will look at this and say "ah, its a B grade" then think that it isn't exactly what they had in mind but it will do.)
0
 
armoghanCommented:
Thanks for accepting.
0
 
objectsCommented:
I would have thought the list in a cell would have been easier than a popup.
Anyways let me know if you need any further help :)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.