2013-10-31 2 views
2

내 jtable에 대한 편집기 설정이 호출되지 않는 이유가 확실하지 않습니다. 다른 SO Question의 편집기 예제를 사용했습니다.JTable 셀 편집기 사용

내 jtable을 편집하면 단순히 문자열로 편집됩니다. 나는 숫자 값만 받아 들일 것으로 예상했습니다. 다른 텍스트를 입력하면 일부 예외가 될 수 있습니다 ...하지만 난 내 테이블을 편집 할 때 편집기가 여기에 호출되고 있다고 생각하지 않습니다. DocumentFilter 대신 편집자 ComponentJFormattedTextField

import javax.swing.*; 
import javax.swing.table.*; 
import javax.swing.text.NumberFormatter; 

import java.awt.*; 
import java.awt.event.*; 
import java.text.DecimalFormat; 
import java.text.NumberFormat; 
import java.text.ParseException; 
import java.text.ParsePosition; 
import java.util.Locale; 

public class Grow extends JFrame { 

private static final Object[][] rowData = {{"Hello", "World"}}; 
private static final Object[] columnNames = {"A", "B"}; 

private JTable table; 
private DefaultTableModel model; 

public Grow() { 
    Container c = getContentPane(); 
    c.setLayout(new BorderLayout()); 

    model = new DefaultTableModel(rowData, columnNames); 
    table = new JTable(); 
    table.setModel(model); 
    c.add(new JScrollPane(table), BorderLayout.CENTER); 
    JButton add = new JButton("Add"); 
    JButton delete = new JButton("Delete"); 
    c.add(add, BorderLayout.LINE_START); 
    add.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent ae) { 
      model.addRow(rowData[0]); 
     } 
    }); 

    table.setCellEditor(new NumberCellEditor()); 

    c.add(delete, BorderLayout.LINE_END); 
    delete.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent ae) { 
      if(table.getSelectedRow()>-1) 
       model.removeRow(table.getSelectedRow()); 
     } 
    }); 

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    pack(); 
} 

class NumberCellEditor extends DefaultCellEditor { 
    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 

    public NumberCellEditor(){ 
     super(new JFormattedTextField()); 
    } 

    @Override 
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 
     JFormattedTextField editor = (JFormattedTextField) super.getTableCellEditorComponent(table, value, isSelected, row, column); 

     if (value!=null){ 
      DecimalFormat numberFormat = new DecimalFormat("#,##0.00;(#,##0.00)"); 
      editor.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(numberFormat))); 
      Number num = (Number) value; 
      String text = numberFormat.format(num); 
      editor.setHorizontalAlignment(SwingConstants.RIGHT); 
      editor.setText(text); 
     } 
     System.out.println(value); 
     return editor; 
    } 

    /*@Override 
    public boolean stopCellEditing() { 
     try { 
      // try to get the value 
      //this.getCellEditorValue(); 
      return super.stopCellEditing(); 
     } catch (Exception ex) { 
      return false; 
     } 

    } 
    */ 

    @Override 
    public Object getCellEditorValue() { 
     // get content of textField 
     String str = (String) super.getCellEditorValue(); 
     if (str == null) { 
      return null; 
     } 

     if (str.length() == 0) { 
      return null; 
     } 

     // try to parse a number 
     try { 
      ParsePosition pos = new ParsePosition(0); 
      Number n = NumberFormat.getInstance().parse(str, pos); 
      if (pos.getIndex() != str.length()) { 
       throw new ParseException(
         "parsing incomplete", pos.getIndex()); 
      } 

      // return an instance of column class 
      return new Float(n.floatValue()); 

     } catch (ParseException pex) { 
      throw new RuntimeException(pex); 
     } 
    } 
    } 

public static void main(String[] args) { 
    Grow g = new Grow(); 
    g.setLocationRelativeTo(null); 
    g.setVisible(true); 
} 
} 
+2

당신의 목표는 무엇입니까? – mKorbel

+0

JTable 용 사용자 정의 렌더러와 편집기를 만드는 법을 배우고 있습니다. 필자가 사용했던 편집기가 필자의 예에 아무런 영향을 미치지 않는 이유는 모른다. 편집기가 제대로 설정되지 않았거나 무시할 항목을 놓쳤습니다 ...? –

답변

2
  • 사용 평범한 JTextField.

  • 난 당신이 필터링 숫자 만

에 대한 InternationalFormatter를 추가하기 위해 할 수있는 (중요한 세부 사항은 offical 한 오라클 튜토리얼에있는, API를 How to use FormattedTextField, NumberFormat 등) XxxFormatJFormattedTextField 위해 무언가 부착 start_point

  • 을 언급하지 못할

    예 :

    InternationalFormatter formatter = new InternationalFormatter(format); 
    formatter.setAllowsInvalid(false); 
    //formatter.setMinimum(0.0); 
    //formatter.setMaximum(1000.00); 
    

    내가 숫자 만이 가치를 수용 할 것으로 예상

    import java.awt.Component; 
    import java.awt.EventQueue; 
    import java.math.RoundingMode; 
    import java.text.DecimalFormat; 
    import java.text.NumberFormat; 
    import java.text.ParseException; 
    import javax.swing.*; 
    import javax.swing.table.TableCellEditor; 
    import javax.swing.table.TableCellRenderer; 
    import javax.swing.table.TableColumnModel; 
    
    public class EditorAsRendererTableTest { 
    
        public EditorAsRendererTableTest() { 
         JTable table = new JTable(3, 2); 
         TableColumnModel colModel = table.getColumnModel(); 
         colModel.getColumn(0).setCellEditor(new MyCellEditor()); 
         colModel.getColumn(0).setCellRenderer(new MyCellEditor()); 
         JFrame frame = new JFrame("Test"); 
         frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
         table.setPreferredScrollableViewportSize(table.getPreferredSize()); 
         frame.add(new JScrollPane(table)); 
         frame.pack(); 
         frame.setLocationRelativeTo(null); 
         frame.setVisible(true); 
        } 
    
        public static void main(String[] args) { 
         EventQueue.invokeLater(new Runnable() { 
          @Override 
          public void run() { 
           new EditorAsRendererTableTest(); 
          } 
         }); 
        } 
    
        private class MyCellEditor extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { 
    
         private static final long serialVersionUID = 1L; 
         private JFormattedTextField renderer; 
         private JFormattedTextField editor; 
         private NumberFormat format = DecimalFormat.getInstance(); 
    
         public MyCellEditor() { 
          format.setMinimumFractionDigits(2); 
          format.setMaximumFractionDigits(4); 
          format.setRoundingMode(RoundingMode.HALF_UP); 
          renderer = new JFormattedTextField(format); 
          renderer.setBorder(null); 
          editor = new JFormattedTextField(format); 
         } 
    
         @Override 
         public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
          renderer.setValue(value); 
          return renderer; 
         } 
    
         @Override 
         public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 
          editor.setValue(value); 
          return editor; 
         } 
    
         @Override 
         public boolean stopCellEditing() { 
          try { 
           editor.commitEdit(); 
          } catch (ParseException e) { 
           return false; 
          } 
          return super.stopCellEditing(); 
         } 
    
         @Override 
         public Object getCellEditorValue() { 
          return editor.getValue(); 
         } 
        } 
    } 
    
  • +0

    +1 편집기의 예입니다. – camickr

    +0

    이 예제는 정말 유용하지만 다음을 허용하도록이 편집기를 만들고 싶다면 어떻게해야합니까? 1. 셀을 선택하고 아무 것도 입력하지 않고 다른 셀을 선택하면 해당 셀을 허용하지 않습니다. 클릭하면 일부 값을 입력하게됩니다. 2. 내가 입력 한 값이 숫자로 시작하면 알파벳 숫자를 무시하고 그 숫자를 double 값으로 변환합니다. 어떻게하면 숫자 만 받아 들일 수 있을까요? –

    2

    코드에서

    enter image description here

    을 screen_shot

    일반적으로 사용자 정의 편집기를 만들 필요가 없습니다. 모델에 저장된 적절한 데이터 클래스를 반환하려면 TableModel의 getColumnClass() 메서드를 재정의하면 테이블에서 적절한 렌더러와 편집기를 사용합니다.

    그러나 편집기에서 소수 자릿수를 제한하거나 숫자에서 범위 검사를 수행하려면 사용자 지정 편집기를 사용할 수 있습니다.