繁体   English   中英

无需先单击即可在JTable中显示JComboBox

[英]Getting a JComboBox to Display in a JTable without Clicking it First

我试图了解如何将JComboBox放入JTable中,因此我正在使用JTable教程中的演示。

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;

/** 
 * TableRenderDemo is just like TableDemo, except that it
 * explicitly initializes column sizes and it uses a combo box
 * as an editor for the Sport column.
 */
public class TableRenderDemo extends JPanel {
private boolean DEBUG = false;

public TableRenderDemo() {
    super(new GridLayout(1,0));

    JTable table = new JTable(new MyTableModel());
    table.setPreferredScrollableViewportSize(new Dimension(500, 70));
    table.setFillsViewportHeight(true);

    //Create the scroll pane and add the table to it.
    JScrollPane scrollPane = new JScrollPane(table);

    //Set up column sizes.
    initColumnSizes(table);

    //Fiddle with the Sport column's cell editors/renderers.
    setUpSportColumn(table, table.getColumnModel().getColumn(2));

    //Add the scroll pane to this panel.
    add(scrollPane);
}

/*
 * This method picks good column sizes.
 * If all column heads are wider than the column's cells'
 * contents, then you can just use column.sizeWidthToFit().
 */
private void initColumnSizes(JTable table) {
    MyTableModel model = (MyTableModel)table.getModel();
    TableColumn column = null;
    Component comp = null;
    int headerWidth = 0;
    int cellWidth = 0;
    Object[] longValues = model.longValues;
    TableCellRenderer headerRenderer =
        table.getTableHeader().getDefaultRenderer();

    for (int i = 0; i < 5; i++) {
        column = table.getColumnModel().getColumn(i);

        comp = headerRenderer.getTableCellRendererComponent(
                             null, column.getHeaderValue(),
                             false, false, 0, 0);
        headerWidth = comp.getPreferredSize().width;

        comp = table.getDefaultRenderer(model.getColumnClass(i)).
                         getTableCellRendererComponent(
                             table, longValues[i],
                             false, false, 0, i);
        cellWidth = comp.getPreferredSize().width;

        if (DEBUG) {
            System.out.println("Initializing width of column "
                               + i + ". "
                               + "headerWidth = " + headerWidth
                               + "; cellWidth = " + cellWidth);
        }

        column.setPreferredWidth(Math.max(headerWidth, cellWidth));
    }
}

public void setUpSportColumn(JTable table,
                             TableColumn sportColumn) {
    //Set up the editor for the sport cells.
    JComboBox comboBox = new JComboBox();
    comboBox.addItem("Snowboarding");
    comboBox.addItem("Rowing");
    comboBox.addItem("Knitting");
    comboBox.addItem("Speed reading");
    comboBox.addItem("Pool");
    comboBox.addItem("None of the above");
    sportColumn.setCellEditor(new DefaultCellEditor(comboBox));

    //Set up tool tips for the sport cells.
    DefaultTableCellRenderer renderer =
            new DefaultTableCellRenderer();
    renderer.setToolTipText("Click for combo box");
    sportColumn.setCellRenderer(renderer);
}

class MyTableModel extends AbstractTableModel {
    private String[] columnNames = {"First Name",
                                    "Last Name",
                                    "Sport",
                                    "# of Years",
                                    "Vegetarian"};
    private Object[][] data = {
    {"Kathy", "Smith",
     "Snowboarding", new Integer(5), new Boolean(false)},
    {"John", "Doe",
     "Rowing", new Integer(3), new Boolean(true)},
    {"Sue", "Black",
     "Knitting", new Integer(2), new Boolean(false)},
    {"Jane", "White",
     "Speed reading", new Integer(20), new Boolean(true)},
    {"Joe", "Brown",
     "Pool", new Integer(10), new Boolean(false)}
    };

    public final Object[] longValues = {"Jane", "Kathy",
                                        "None of the above",
                                        new Integer(20), Boolean.TRUE};

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

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

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

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

    /*
     * JTable uses this method to determine the default renderer/
     * editor for each cell.  If we didn't implement this method,
     * then the last column would contain text ("true"/"false"),
     * rather than a check box.
     */
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }

    /*
     * Don't need to implement this method unless your table's
     * editable.
     */
    public boolean isCellEditable(int row, int col) {
        //Note that the data/cell address is constant,
        //no matter where the cell appears onscreen.
        if (col < 2) {
            return false;
        } else {
            return true;
        }
    }

    /*
     * Don't need to implement this method unless your table's
     * data can change.
     */
    public void setValueAt(Object value, int row, int col) {
        if (DEBUG) {
            System.out.println("Setting value at " + row + "," + col
                               + " to " + value
                               + " (an instance of "
                               + value.getClass() + ")");
        }

        data[row][col] = value;
        fireTableCellUpdated(row, col);

        if (DEBUG) {
            System.out.println("New value of data:");
            printDebugData();
        }
    }

    private void printDebugData() {
        int numRows = getRowCount();
        int numCols = getColumnCount();

        for (int i=0; i < numRows; i++) {
            System.out.print("    row " + i + ":");
            for (int j=0; j < numCols; j++) {
                System.out.print("  " + data[i][j]);
            }
            System.out.println();
        }
        System.out.println("--------------------------");
    }
}

/**
 * Create the GUI and show it.  For thread safety,
 * this method should be invoked from the
 * event-dispatching thread.
 */
private static void createAndShowGUI() {
    //Create and set up the window.
    JFrame frame = new JFrame("TableRenderDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //Create and set up the content pane.
    TableRenderDemo newContentPane = new TableRenderDemo();
    newContentPane.setOpaque(true); //content panes must be opaque
    frame.setContentPane(newContentPane);

    //Display the window.
    frame.pack();
    frame.setVisible(true);
}

public static void main(String[] args) {
    //Schedule a job for the event-dispatching thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });
}
}

通常,JComboBox直到单击后才会显示。 我想让它一直显示,以便用户知道该列中有一个组合框。 我尝试使用自定义渲染器(在此论坛上找到了一些渲染器)来解决此问题,但是遇到了使我走错了路的问题。 是否有示例显示如何使组合框显示而不先单击即可。 TIA。

渲染器看起来像:

class ComboBoxRenderer extends JComboBox implements TableCellRenderer
{
    public ComboBoxRenderer()
    {
        setBorder(null);
    }

    public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    {
        removeAllItems();
        addItem( value );

        return this;
    }
}

您可以使用以下代码在首次单击时调用Combobox编辑器。

JTable table = new JTable(new MyTableModel()) {
    @Override
    public boolean editCellAt(int row, int column, EventObject e){
        boolean result = super.editCellAt(row, column, e);
        if( result ) {
            Component comp = getEditorComponent();
            if( comp instanceof JComboBox ) {
                final JComboBox combo = ( JComboBox ) comp;
                SwingUtilities.invokeLater( new Runnable() {

                    @Override
                    public void run() {
                        combo.showPopup();
                        // TODO Auto-generated method stub

                    }
                });
            }
        }
        return result;
    }
};  

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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