java - Jtable jcombobox 和单元格编辑

标签 java swing combobox jtable

我想要一个包含 4 列的 jtable。 一列必须是组合框。 其他列是字符串。

当我在一个单元格上单击一次时,我希望该单元格可以使用闪烁的插入符号/光标进行编辑。此外,如果我单击组合框,我希望组合框设置弹出窗口可见。

我已经阅读并测试了“如何使用表格”教程,如果我只需单击单元格中的组合框,它就会打开。我的第一个问题是我不明白为什么教程中的代码在我们实现抽象表模型而不是 DefaultTableModel 时有效。

我的代码是:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

public class JtabletestOK {

    public static void main(String[] args) {

        JtabletestOK test = new JtabletestOK();
        test.go();
    }

    public void go() {

        //create the frame
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);



        //create a table and add it to a scroll pane in a new tab
        JTable jTable1 = new JTable()
        {
            //  Place cell in edit mode when it 'gains focus'

            public void changeSelection(
                    int row, int column, boolean toggle, boolean extend)
            {
                super.changeSelection(row, column, toggle, extend);

                if (editCellAt(row, column))
                {
                    Component editor = getEditorComponent();
                    editor.requestFocusInWindow();
                    // System.out.println("ffin focus gagne");
                    if (editor instanceof JTextField) {

                        JTextField jf = (JTextField) editor;
                        jf.select(0, jf.toString().length());
                    }}
            }
        };


        jTable1.setPreferredScrollableViewportSize(new Dimension(800,100));
        jTable1.setFillsViewportHeight(true);

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

        Object columnNames[] = { "DataCombo", "Data 2", "Data 3", "Data 4"  };
        DefaultTableModel model = new DefaultTableModel(columnNames, 0);

        Object rowData[] = { "", "Row1-Column2", "Row1-Column3", "Row1-Column3" };
        model.addRow(rowData);
        jTable1.setModel(model);


        String[] comboBoxArray = {"proem1","veitem2","atem3"};
        JComboBox jcb = new JComboBox(comboBoxArray);
        jcb.setEditable(true);


        TableColumn colCombo = jTable1.getColumnModel().getColumn(0);
        colCombo.setCellEditor(new DefaultCellEditor(jcb));

        jcb.setEditable(true);



        frame.getContentPane().add(scrollPane);
        frame.pack();
        frame.setVisible(true);

    }

抽象模型的来源在这里: http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/components/TableRenderDemoProject/src/components/TableRenderDemo.java

只是找到问题所在:注释语句 jcb.setEditable(true); 时,如果我单击 comboxcell,它会打开单元格。 但我不知道为什么它效果更好。另外,我希望组合框可编辑。

我如何才能让其他单元格具有相同的行为。

您好,我已经更新了代码以便 - 如果我通过覆盖方法在单元格上单击一次,单元格将变得可编辑 - 如果我通过覆盖方法在单元格上单击一次,组合框将变为可编辑

我把我的新代码放在这里,它可能对其他人有帮助:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.AbstractAction;
import javax.swing.AbstractCellEditor;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.InputMap;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
import javax.swing.text.JTextComponent;

public class JtabletestOK {

    public static void main(String[] args) {

        JtabletestOK test = new JtabletestOK();
        test.go();
    }

    public void go() {

        //create the frame
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);



        //create a table and add it to a scroll pane in a new tab
        JTable jTable1 = new JTable()

        {
            //  Place cell in edit mode when it 'gains focus'

            public void changeSelection(
                    int row, int column, boolean toggle, boolean extend)
            {
                super.changeSelection(row, column, toggle, extend);

                if (column > 0)
                {

                    if (editCellAt(row, column))
                    {
                        Component editor = getEditorComponent();
                        editor.requestFocusInWindow();
                        // System.out.println("ffin focus gagne");
                        if (editor instanceof JTextField) {

                            JTextField jf = (JTextField) editor;
                            jf.select(0, jf.toString().length());
                        }}
                }
            }
        };



        jTable1.setPreferredScrollableViewportSize(new Dimension(800,100));
        jTable1.setFillsViewportHeight(true);
        replaceTabByEnter(jTable1);

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

        Object columnNames[] = { "DataCombo", "Data 2", "Data 3", "Data 4"  };
        DefaultTableModel model = new DefaultTableModel(columnNames, 0);

        Object rowData[] = { "", "Row1-Column2", "Row1-Column3", "Row1-Column3" };
        model.addRow(rowData);
        jTable1.setModel(model);


        String[] comboBoxArray = {"proem1","veitem2","atem3"};
        JComboBox jca = new JComboBox(comboBoxArray);
        jca.setSelectedItem("");
        JTextComponent editor = (JTextComponent) jca.getEditor().getEditorComponent();

        jca.addPopupMenuListener(new PopupMenuListener() {

            @Override
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                JComponent ja = (JComponent) e.getSource();
            }

            @Override
            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                JComponent ja = (JComponent) e.getSource();
                JTable jtb = (JTable) ja.getParent();
                jtb.changeSelection(0,1,false,false);
            }

            @Override
            public void popupMenuCanceled(PopupMenuEvent e) {
            }
        });



        editor.addMouseListener(new MouseListener() {

            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("Not mouseClicked yet.");
            }

            @Override
            public void mousePressed(MouseEvent e) {
                System.out.println("Not mousePressed yet.");
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                JComponent ja = (JComponent) e.getSource();
                JComponent jcbloc = (JComponent) ja.getParent();
                JComboBox jcb = (JComboBox) jcbloc;
                jcb.setPopupVisible(true);
                System.out.println("Not mouseReleased yet.");

            }

            @Override
            public void mouseEntered(MouseEvent e) {
                System.out.println("Not mouseEntered yet.");
            }

            @Override
            public void mouseExited(MouseEvent e) {
                System.out.println("Not mouseExited yet.");
            }
        });

        autocompletecombo jcb =new autocompletecombo(jca);
        TableColumn colCombo = jTable1.getColumnModel().getColumn(0);
        jca.setEditable(true);
        comboboxEditor cbe = new comboboxEditor(jca);
        colCombo.setCellEditor(cbe);

        frame.getContentPane().add(scrollPane);
        frame.pack();
        frame.setVisible(true);

    }


    public void replaceTabByEnter(JTable  jtane) {

        KeyStroke tab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
        KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
        InputMap im = jtane.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        im.put(enter, im.get(tab));
    }


    class comboboxEditor extends AbstractCellEditor implements TableCellEditor{

        JComboBox comboBox;
        JTextField jtf;

        S11InitialSelection sjcb;
        @Override
        public Object getCellEditorValue() {
            return comboBox.getSelectedItem();
        }

        public comboboxEditor(JComboBox jcb) {

            comboBox = jcb;
            jtf.selectAll();
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {

            comboBox.setSelectedItem(value);
            return comboBox;
        }

        public boolean stopCellEditing() {


            fireEditingStopped();
            //     jt.EditNextCell();
            return true;

        }


    }










}
  • 当我单击组合框时,我想通过选择它来突出显示文本。 我不记得如何从 jcombobox 获取文本字段以便使用 selectAll() 方法或类似方法。

我已经找到了解决方案:

            public void mouseReleased(MouseEvent e) {
                JComponent ja = (JComponent) e.getSource();
                JComponent jcbloc = (JComponent) ja.getParent();
                JComboBox jcb = (JComboBox) jcbloc;
                jcb.setPopupVisible(true);
                JTextComponent editor = (JTextComponent) jcb.getEditor().getEditorComponent();
                editor.setSelectionStart(0);
                editor.setSelectionEnd(editor.getText().length());
                System.out.println("Not mouseReleased yet.");

            }

感谢您的帮助。

最佳答案

我终于找到了解决所有问题的方法。我发布了所有代码。 我希望它能帮助别人。如果您找到解决问题的更好方法,我愿意。

它仍然是两个奇怪的东西,但它按我想要的方式工作,所以如果有人作为一个想法:

  • 如果我移动代码

            if(e.getKeyChar() == KeyEvent.VK_ENTER){
                JComponent ja = (JComponent) e.getSource();
                JComboBox jcbloc = (JComboBox) ja.getParent();
                JTable jtb = (JTable) jcbloc.getParent();
                jtb.changeSelection(0,1,false,false);
            }
    

在 keyReleased 而不是 keyPressed 中,它不起作用。

  • 当我在基本单元格文本上按回车键时,程序会单独转到下一个单元格。我不明白它是如何在输入键时单独进入下一个单元格的。

所有代码在这里:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.AbstractAction;
import javax.swing.AbstractCellEditor;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.InputMap;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.basic.BasicTextUI;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
import javax.swing.text.JTextComponent;


public class JtabletestOKStackOver {

public static void main(String[] args) {

    JtabletestOKStackOver test = new JtabletestOKStackOver();
    test.go();
}

public void go() {

    //create the frame
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //create a table and add it to a scroll pane in a new tab
    JTable jTable1 = new JTable()

    {
        //  Place cell in edit mode when it 'gains focus'

        public void changeSelection(
                int row, int column, boolean toggle, boolean extend)
        {
            super.changeSelection(row, column, toggle, extend);


            if (column > -1)
            {

                if (editCellAt(row, column))
                {
                    Component editor = getEditorComponent();
                    editor.requestFocusInWindow();
                    if (editor instanceof JTextField) {

                        JTextField jf = (JTextField) editor;
                        jf.select(0, jf.toString().length());
                    }
                    if (editor instanceof JComboBox) {
                        JComboBox jcb = (JComboBox) editor;
                        jcb.setPopupVisible(true);
                        JTextComponent editorCombo = (JTextComponent) jcb.getEditor().getEditorComponent();
                        editorCombo.setSelectionStart(0);
                        editorCombo.setSelectionEnd(editorCombo.getText().length());
                    }



                }
            }
        }
    };





    jTable1.setPreferredScrollableViewportSize(new Dimension(800,100));
    jTable1.setFillsViewportHeight(true);
    jTable1.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

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

    Object columnNames[] = { "DataCombo", "Data 2", "Data 3", "Data 4"  };
    DefaultTableModel model = new DefaultTableModel(columnNames, 0);

    Object rowData[] = { "", "Row1-Column2", "Row1-Column3", "Row1-Column3" };
    model.addRow(rowData);
    jTable1.setModel(model);


    String[] comboBoxArray = {"proem1","veitem2","atem3"};
    JComboBox jca = new JComboBox(comboBoxArray);
    jca.setSelectedItem("");
    JTextComponent editor = (JTextComponent) jca.getEditor().getEditorComponent();

    editor.addKeyListener(new KeyListener() {

        @Override
        public void keyTyped(KeyEvent e) {
        }

        @Override
        public void keyPressed(KeyEvent e) {
            if(e.getKeyChar() == KeyEvent.VK_ENTER){
                JComponent ja = (JComponent) e.getSource();
                JComboBox jcbloc = (JComboBox) ja.getParent();
                JTable jtb = (JTable) jcbloc.getParent();
                jtb.changeSelection(0,1,false,false);
            }
        }

        @Override
        public void keyReleased(KeyEvent e) {

        }
    });


    editor.addFocusListener(new FocusListener() {

        @Override
        public void focusGained(FocusEvent e) {
            JComponent ja = (JComponent) e.getSource();
            JComponent jcbloc = (JComponent) ja.getParent();
            JComboBox jcb = (JComboBox) jcbloc;
            jcb.setPopupVisible(true);
            JTextComponent editor = (JTextComponent) jcb.getEditor().getEditorComponent();
            editor.setSelectionStart(0);
            editor.setSelectionEnd(editor.getText().length());
        }

        @Override
        public void focusLost(FocusEvent e) {
        }
    });





    TableColumn colCombo = jTable1.getColumnModel().getColumn(0);
    jca.setEditable(true);
    comboboxEditor cbe = new comboboxEditor(jca);
    colCombo.setCellEditor(cbe);


    TableColumn colAutre = jTable1.getColumnModel().getColumn(1);
    TableColumn colAutre2 = jTable1.getColumnModel().getColumn(2);
    TableColumn colAutre3 = jTable1.getColumnModel().getColumn(3);
    textCellEditor dce = new textCellEditor(new JTextField());

    colAutre.setCellEditor(dce);
    colAutre2.setCellEditor(dce);
    colAutre3.setCellEditor(dce);



    frame.getContentPane().add(scrollPane);
    frame.pack();
    frame.setVisible(true);

}







class comboboxEditor extends AbstractCellEditor implements TableCellEditor{

    JComboBox comboBox;



    public comboboxEditor(JComboBox jcb) {

        comboBox = jcb;
    }


    public Object getCellEditorValue() {
        return comboBox.getSelectedItem();
    }


    @Override
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {

        comboBox.setSelectedItem(value);
        return comboBox;
    }

    public boolean stopCellEditing() {
        fireEditingStopped();
        return true;

    }


}

class textCellEditor extends AbstractCellEditor implements TableCellEditor{
    JTextField jtextfield;

    public textCellEditor(JTextField jtf) {
        jtextfield = jtf;
    }


    public Object getCellEditorValue() {
        return jtextfield.getText();
    }


    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        if (isSelected) {
            // cell (and perhaps other cells) are selected
        }
        if (value== null)
        {
            value="";
        }
        value = value.toString();
        if (value instanceof Integer) {
            value = value.toString();
        }
        jtextfield.setText((String) value);

        // Return the configured component
        return jtextfield;
    }

    public boolean stopCellEditing() {
        fireEditingStopped();
        return true;

    }

}



}

感谢您的帮助。

关于java - Jtable jcombobox 和单元格编辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23823794/

相关文章:

Java Swing GUI 应用程序完全空白,没有任何内容,而按钮添加到面板中

c# - 无法启用组合框

java - 从组合框获取值(value)到jsp中的servlet

java - 多种 AlgorithmSuite 策略 WS-SecurityPolicy CXF

java - Swing:旋转风格化文本?

java - 在 Swing 中子类化 JPanel 的最佳方法

javascript - ExtJs 将不同数据从一个存储加载到多个选择

java - 在 Controller 方法中的方法上使用 @PreAuthorize 注释

java.io.IOException : Not in GZIP format with class. getResourceAsStream() 异常

java - Spring Security 在本地主机上工作,但在服务器上的 docker 中给出 '403 Forbidden'