2014-05-23 165 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

相關問題