如何在 JTable 的单元格中实现自动完成功能? [英] How to implement auto complete functionality in a cell in JTable?

查看:15
本文介绍了如何在 JTable 的单元格中实现自动完成功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 JTable 有一个作为 DefaultCellEditor(JComboBox) 类实例实现的单元格编辑器.我尝试了几种不同的方法(为 Swing 组合框添加自动完成支持) 但它仍然不起作用.

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 Swing Comboboxes ) but it still doesn't work.

1:

//
JComboBox combo = new JComboBox(new Object[] { "Ester", "Jordi", "Jordina", "Jorge", "Sergi" });
AutoCompleteDecorator.decorate(combo);
DefaultCellEditor cellEditor = new DefaultCellEditor(combo);
TableColumn column = myTable.getColumnModel().getColumn(2);
column.setCellEditor(cellEditor);
//

2:

//
Object[] elements = new Object[] { "Ester", "Jordi", "Jordina", "Jorge", "Sergi" };
JComboBox c = new JComboBox(elements);
c.setEditable(true);
AutoCompleteSupport support = AutoCompleteSupport.install(c, GlazedLists.eventListOf(elements));
support.setSelectsTextOnFocusGain(false);
support.setHidesPopupOnFocusLost(false);
support.setStrict(false);
ComboBoxCellEditor combo = new ComboBoxCellEditor(c);
TableColumn column = myTable.getColumnModel().getColumn(2);
ComboTableCellRenderer renderer = new ComboTableCellRenderer();
column.setCellRenderer(renderer);
column.setCellEditor(combo);
//

3:

//
Object[] elements = new Object[] { "Ester", "Jordi", "Jordina", "Jorge", "Sergi" };
JComboBox comboBox = new JComboBox(elements);
comboBox.setEditable(true);
AutoCompletion ac = new AutoCompletion(comboBox);
ac.setStrict(false);
DefaultCellEditor cellEditor = new DefaultCellEditor(comboBox);
TableColumn column = myTable.getColumnModel().getColumn(2);
column.setCellEditor(cellEditor);
//

我面临的问题是,一旦用户开始在组合框中键入内容,它就会退出编辑模式,从而有效地防止输入任何值.

The problem I am facing is that as soon as the user starts typing in the combo box, it comes out of the editing mode, and thus effectively preventing entering any value.

推荐答案

我最喜欢的 AutoComplete JComboBox/JTextField 没有问题, 仍然有第二个选择使用 AutoComplete JTextField 而不是 AutoComplete JComboBox,

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

添加到 Oracle JTable 教程中的代码

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();
            }
        });
    }
}

这篇关于如何在 JTable 的单元格中实现自动完成功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆