How to implement auto complete functionality in a cell in JTable?

后端 未结 2 820
感动是毒
感动是毒 2020-12-04 03:19

My JTable has a cell editor implemented as an instance of the DefaultCellEditor(JComboBox) class. I\'ve tried a couple of different things (Adding Auto-Completion Support to

相关标签:
2条回答
  • 2020-12-04 03:50

    no issue with my favorite AutoComplete JComboBox / JTextField, still there second choice use AutoComplete JTextField instead of AutoComplete JComboBox,

    enter image description here

    enter image description here

    added to the code from Oracle JTable tutorial

    import javax.swing.DefaultCellEditor;
    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;
    import java.util.ArrayList;
    
    /**
     * 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 static final long serialVersionUID = 1L;
    
        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.
            ArrayList<String> listSomeString = new ArrayList<String>();        
            listSomeString.add("Snowboarding");
            listSomeString.add("Rowing");
            listSomeString.add("Knitting");
            listSomeString.add("Speed reading");
            listSomeString.add("Pool");
            listSomeString.add("None of the above");
            Java2sAutoComboBox comboBox = new Java2sAutoComboBox(listSomeString);
            comboBox.setDataList(listSomeString);
            comboBox.setMaximumRowCount(3);
            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 static final long serialVersionUID = 1L;
            private String[] columnNames = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"};
            private Object[][] data = {{"Kathy", "Smith", "Snowboarding", new Integer(5), false},
                {"John", "Doe", "Rowing", new Integer(3), true}, {"Sue", "Black", "Knitting", new Integer(2), false},
                {"Jane", "White", "Speed reading", new Integer(20), true}, {"Joe", "Brown", "Pool", new Integer(10), false}};
            public final Object[] longValues = {"Jane", "Kathy", "None of the above", new Integer(20), Boolean.TRUE};
    
            @Override
            public int getColumnCount() {
                return columnNames.length;
            }
    
            @Override
            public int getRowCount() {
                return data.length;
            }
    
            @Override
            public String getColumnName(int col) {
                return columnNames[col];
            }
    
            @Override
            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.
             */
            @Override
            public Class<?> getColumnClass(int c) {
                return getValueAt(0, c).getClass();
            }
    
            /*
             * Don't need to implement this method unless your table's
             * editable.
             */
            @Override
            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.
             */
            @Override
            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() {
    
                @Override
                public void run() {
                    createAndShowGUI();
                }
            });
        }
    }
    
    0 讨论(0)
  • 2020-12-04 04:01

    try this

        JTable table = new JTable(data, columns);
        table.putClientProperty("terminateEditOnFocusLost", true);
        JScrollPane scrollPane = new JScrollPane(table);
        final JXComboBox editorComboBox = new JXComboBox(array);
        editorComboBox.addAncestorListener(new AncestorListener() {
            public void ancestorAdded(AncestorEvent event) {
                //make sure combobox handles key events
                editorComboBox.requestFocusInWindow();
            }
            public void ancestorMoved(AncestorEvent event) {}
            public void ancestorRemoved(AncestorEvent event) {}
        });
        AutoCompleteDecorator.decorate(editorComboBox);
        TableColumn column = table.getColumnModel().getColumn(0);
        column.setCellEditor(new ComboBoxCellEditor(editorComboBox));
    
    0 讨论(0)
提交回复
热议问题