2014-05-23 132 views
2

我想有一个4列jtable。 一列必须是组合框。 其他列是字符串。Jtable jcombobox和单元格编辑

当我单击单元格上的一次时,我希望单元格变得可编辑闪烁插入/光标。另外,如果我点击组合框,我希望combox设置弹出窗口可见。

我已经阅读并测试了教程“如何使用表格”,如果我只是单击单元格中的组合框,就会打开它。我的第一个问题是,我不明白为什么当我们实现抽象表模型而不工作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(真); ,如果我单击一下comboxcell,它会打开单元格。 但我不知道它为什么更好。另外,我希望combox可编辑。

我怎么可以有其他细胞相同的行为。

大家好,我已经更新了代码,以便有 - 细胞变成可编辑的,如果我通过重写方法 点击一次的细胞 - 组合框变成可编辑的,如果我通过重写方法点击一个时间上的细胞

我把自己的新代码在这里,它可以帮助其他:

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."); 

      } 

感谢。

+0

我可以使用AbstractTableModel查看您的示例吗? –

回答

1

我终于找到了如何解决我所有的问题。我发布了所有的代码。 我希望它能帮助别人。如果你找到更好的方法来解决问题,我是开放的。

它仍然是个怪东西,但它的工作,因为我想,如果somenone作为一种思想:

  • 如果我移动代码

     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; 

    } 

} 



} 

感谢您的帮助。

-1

我不知道为什么你的代码与AbstractTableModel的作品(因为我看不到它)。但我可以帮助你让你的例子工作。

jcb.addActionListener(new java.awt.event.ActionListener() { 
     public void actionPerformed(java.awt.event.ActionEvent evt) { 
      System.out.println("test"); 
      final JComboBox j= (JComboBox)evt.getSource(); 
      SwingUtilities.invokeLater(new Runnable() { 

       @Override 
       public void run() { 
        if (j.isDisplayable()) j.setPopupVisible(true); 
       } 
      }); 

     }}); 
+0

你的样品工作!你能解释我与SwingUtilities.invokeLater的区别吗?为什么没有以后调用它不工作? – nick

+0

可能当组合框编辑器获得焦点时,弹出窗口会自动关闭。所以我们需要立即打开它。 invokeLater可以帮助你做到这一点。 但我不确定我的解释是否正确。 –

+0

-1,不要使用ActionListener来显示组合框弹出。这由编辑处理。 – camickr

0

不要在组合框上使用ActionListener。单击单元格时,编辑器将显示“弹出”。

我的第一个问题是,我不明白为什么本教程中的代码工作时,我们实现抽象表模型,而不工作DefaultTableModel。

编辑由TableModel的isCellEditable(...)方法控制。当你点击一个可编辑的单元格时,JTable将使用适当的编辑器。如果编辑器是组合框,则单击单元格时将显示弹出窗口。

只要找到问题:当注释语句jcb.setEditable(true); ,如果我单击一下comboxcell,它会打开单元格。但我不知道它为什么更好地工作

当你点击一个单元格时,我相信MouseEvent被转发到编辑器(即组合框)。由于组合框是可编辑的,所以MouseEvent转到文本字段,因此焦点仍然是文本字段,并且不显示弹出窗口。尝试使用普通的组合框,而不是在JTable中显示,以便看到相同的行为。

+0

你试图回答什么问题? DefaultTableModel总是返回true isCellEditable() –

+0

我试图告诉OP,你不需要做任何特别的事情来显示组合框下拉框。当单元格可编辑时,表格将选择适当的编辑器。已更新。 – camickr

+0

你说得对。我有一个基本的组合框相同的行为。 我已经删除了动作监听器,你有关于如何打开组合下拉列表的想法,即,我是否需要在文本框上放置一个监听器来显示组合中的弹出窗口? – nick

相关问题