简体   繁体   中英

JComboBox added in specific JTable cell does not render

I'm developping a game lobby with swing. I have a JTable with all the different players logged in the room, and I want to add a JComboBox in only one cell. My problem is that the comboBox doesn't render correctly.

在此处输入图片说明

I know there are plenty of other Threads about this subject but I couldn't find someone with the same problem.

JComboBox box = new JComboBox();
box.addItem("Warrior");
/* Adds few other items (strings)*/
this.box.addActionListener (new ActionListener () {
    public void actionPerformed(ActionEvent e) {
        /* sends message to server to change character when the combobox's chosen element is changed*/
    }
});
TableUserModel model = new TableUserModel(localUser,this.box); //Specifying the local user as I don't want a JComboBox in the others user's rows.
JTable table = new JTable(this.model);
table.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(this.box));

Table Model class

public class TableUserModel extends AbstractTableModel{

    private String[] columnNames = {"Username","Class","TeamColor","Action"};
    private Object[][] data = {{null,null,null,null}};
    private User localUser;
    private JComboBox box;

    public TableUserModel(User u,JComboBox box) {
        this.localUser = u;
        this.box = box;
    }

    @Override
    public int getColumnCount() {
        return this.columnNames.length;
    }

    @Override
    public int getRowCount() {
        return this.data.length;
    }

    @Override
    public Object getValueAt(int row, int col) {
        return this.data[row][col];
    }

    public String getColumnName(int col) {
        return columnNames[col];
    }

    public Class getColumnClass(int column) {
        for (int row = 0; row < getRowCount(); row++) {
            Object o = getValueAt(row, column);
            if (o != null) {
                return o.getClass();
            }
        }
        return Object.class;
    }

    //The following method updates my data array when the informations are refreshed from the server
    public void refreshUsers(ArrayList<User> users) {
        int elementNumber = 0;
        //clears the data[][] array
        this.data = new Object[][];
        for (User usr : users) {
            this.data[elementNumber][0] = usr.getUsername();
            /*if it's the GriffinBabe's (local user) row */
                this.data[elementNumber][1] = this.box; //HERE!!! I add the JComboBox into the specific cell
            /*else adds a simple string information (for users other than localplayer) */
            this.data[elementNumber][2] = usr.getTeamColor();
            this.data[elementNumber][3] = null;
            elementNumber++;
        }
    }

User Class

Is just a class containing some informations, the problem is certainly not here

and I want to add a JComboBox in only one cell.

This has nothing to do with the TableModel. It is the view (ie. the table) that displays the editor so you need to customize the table.

One way to do this is to override the getCellEditor(...) method of the JTable . For example:

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

public class TableComboBoxByRow extends JPanel
{
    List<String[]> editorData = new ArrayList<String[]>(3);

    public TableComboBoxByRow()
    {
        setLayout( new BorderLayout() );

        // Create the editorData to be used for each row

        editorData.add( new String[]{ "Red", "Blue", "Green" } );
        editorData.add( new String[]{ "Circle", "Square", "Triangle" } );
        editorData.add( new String[]{ "Apple", "Orange", "Banana" } );

        //  Create the table with default data

        Object[][] data =
        {
            {"Color", "Red"},
            {"Shape", "Square"},
            {"Fruit", "Banana"},
            {"Plain", "Text"}
        };
        String[] columnNames = {"Type","Value"};

        DefaultTableModel model = new DefaultTableModel(data, columnNames);
        JTable table = new JTable(model)
        {
            //  Determine editor to be used by row
            public TableCellEditor getCellEditor(int row, int column)
            {
                int modelColumn = convertColumnIndexToModel( column );

                if (modelColumn == 1 && row < 3)
                {
                    JComboBox<String> comboBox1 = new JComboBox<String>( editorData.get(row));
                    return new DefaultCellEditor( comboBox1 );
                }
                else
                    return super.getCellEditor(row, column);
            }
        };

        JScrollPane scrollPane = new JScrollPane( table );
        add( scrollPane );
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("Table Combo Box by Row");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new TableComboBoxByRow() );
        frame.setSize(200, 200);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM