2009-10-31 15 views
22

उच्च स्तर: मेरे पास एक जेटीबल है जिसे उपयोगकर्ता डेटा संपादित करने के लिए उपयोग कर सकता है।जब कोई सेल फ़ोकस खो देता है तो कोई Jtable डेटा सहेज सकता है?

जब भी उपयोगकर्ता प्रेस दर्ज करें या टैब संपादन समाप्त करने के लिए, डेटा सहेजा जाता

तो उपयोगकर्ता पत्ते (मैं asusming रहा है कि "बचाया" वास्तव में "TableModel के setValueAt() विधि कहा जाता है"। इसका मतलब है) एक संपादन करने के बाद किसी अन्य तरीके से सेल, नया डेटा सहेजा नहीं जाता है और मान जिस तरह से रहता है। इसलिए, उदाहरण के लिए, यदि उपयोगकर्ता कोई मान बदलता है और फिर स्क्रीन पर किसी अन्य विजेट पर क्लिक करता है, तो परिवर्तन "छड़ी" नहीं होता है।

मेरा मानना ​​है कि स्ट्रिंग्स से भरा एक जेटीबल के लिए यह डिफ़ॉल्ट व्यवहार है, हां?

कई कारणों से, जब भी उपयोगकर्ता सेल छोड़ देता है तो वांछित व्यवहार किसी भी और सभी संपादन को सहेजने के लिए होता है। ऐसा करने के लिए स्विंग प्राप्त करने का सबसे अच्छा/सही तरीका क्या है?

उत्तर

5

आपको focus listener जोड़ने की आवश्यकता है। यह देखते हुए कि जेटीबल मूल रूप से अपने सेल घटकों का एक कंटेनर है, आप वास्तव में अपनी तालिका में प्रत्येक सेल के लिए फोकस श्रोता चाहते हैं जिसे आपके द्वारा संकेतित तरीके से व्यवहार करने की आवश्यकता है।

ऐसा करने के लिए, आपको कस्टम सेल संपादक बनाना होगा, जो एक पंजीकृत फोकस श्रोता के सेल घटक को लपेटता है। और जब आपको फोकस ईवेंट के नुकसान के लिए कॉलबैक मिलता है, तो आप डेटा की बचत करते हैं, जैसा कि आपको चाहिए।

This pretty much details most of what you need to do। फोकस श्रोता को लागू करने का विवरण वहां नहीं है, लेकिन यह काफी सरल है।

आइए कहें कि आप अपने सेल घटक के रूप में JTextComponent का उपयोग करते हैं। फिर:

public void focusLost(FocusEvent e) { 
    JTextComponent cell = (JTextComponent) e.getSource(); 
    String data = cell.getText(); 

    // TODO: save the data for this cell 
} 

[पी। संपादित करें]:

थ्रेड जो आपको इस घटना के साथ बुला रहा है वह प्रेषण धागा है। उच्च विलंबता वाले कार्यों के लिए इसका उपयोग न करें। लेकिन अगर आप ढेर में सिर्फ बिट्स फिसल रहे हैं, तो यह ठीक होना चाहिए।

+0

दूसरा लिंक काम नहीं कर रहा है। :( – Niroshan

+0

तात्कालिक मीडिया पर संग्रहीत सामूहिक ज्ञान के संदर्भ में मानवता के लिए सीखने के लिए एक सबक। – alphazero

+0

द वेबैक मशीन में यह था - मैंने तदनुसार लिंक बदल दिया। –

24

Table Stop Editing बताता है कि क्या हो रहा है और कुछ सरल समाधान देता है।

14

सरल समाधान में से एक प्रस्तावित

table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); 

केवल स्ट्रिंग स्तंभों के लिए अच्छा है। समस्या यह है कि, उदाहरण के लिए, कॉलम के फ़्लोट प्रकार को संपादित किया जा रहा है, संबंधित सेल में एक खाली स्ट्रिंग दर्ज करें और फिर विंडो के किसी भी अन्य नियंत्रण पर क्लिक करें - CellEditorRemover.propertyChange()JTable.java की विधि NullPointerException पर फेंकता है। यह संपादन को रोकने या रद्द करने के लिए getCellEditor() कॉल का उपयोग करता है लेकिन यह इस मामले में null देता है। यदि दर्ज किया गया मान खाली नहीं है या यदि मैं terminateEditOnFocusLost ध्वज हटाता हूं तो सबकुछ ठीक है। शायद, वर्णित स्थिति एक बग है।

मुझे आशा है कि मैं पिछले पोस्टों में से एक के आधार पर समाधान प्रदान कर सकता हूं। यह इतना छोटा नहीं है जैसा कि मैंने पहले माना था लेकिन मुझे लगता है कि यह काम करता है। मुझे डिफ़ॉल्ट सेल संपादक और JTextField से अपने स्वयं के टेक्स्ट फ़ील्ड से अपना स्वयं का सेल संपादक प्राप्त करना था जिसमें FocusListener है। जब संपादन कक्ष फोकस खो देता है, और खिड़की के दूसरे नियंत्रण से प्राप्त फोकस खो देता है तो यह फोकस श्रोता ठीक काम करता है। लेकिन सेल चयन के मामले में फोकस श्रोता "बहरा" बदलता है। यही कारण है कि अगर प्रवेश मूल्य अमान्य हो जाएगा तो इसे पुनर्स्थापित करने के लिए संपादन को संपादित करने से पहले मुझे पहले वैध मान भी याद रखना होगा।

नीचे दिए गए कोड को देखें। Double, Float और Integer के साथ परीक्षण किया गया, लेकिन मुझे उम्मीद है कि यह Byte और String के साथ भी काम करेगा। फोकस श्रोता साथ

पाठ क्षेत्र:

public class TextFieldCell extends JTextField { 
    public TextFieldCell(JTable cellTable) { 
     super();       // calling parent constructor 
     final JTable table = cellTable;  // this one is required to get cell editor and stop editing 

     this.addFocusListener(new FocusListener() { 
      public void focusGained(FocusEvent e) { 
      } 

      // this function successfully provides cell editing stop 
      // on cell losts focus (but another cell doesn't gain focus) 
      public void focusLost(FocusEvent e) { 
       CellEditor cellEditor = table.getCellEditor(); 
       if (cellEditor != null) 
        if (cellEditor.getCellEditorValue() != null) 
         cellEditor.stopCellEditing(); 
        else 
         cellEditor.cancelCellEditing(); 
      } 
     }); 
    } 
} 

डिफ़ॉल्ट सेल संपादक वर्ग:

myTable.setDefaultEditor(Float.class, new TextFieldCellEditor(new TextFieldCell(myTable), Float.class)); 
myTable.setDefaultEditor(Double.class, new TextFieldCellEditor(new TextFieldCell(myTable), Double.class)); 
myTable.setDefaultEditor(Integer.class, new TextFieldCellEditor(new TextFieldCell(myTable), Integer.class)); 

आशा:

class TextFieldCellEditor extends DefaultCellEditor { 
TextFieldCell textField; // an instance of edit field 
Class<?> columnClass;  // specifies cell type class 
Object valueObject;   // for storing correct value before editing 
public TextFieldCellEditor(TextFieldCell tf, Class<?> cc) { 
    super(tf); 
    textField = tf; 
    columnClass = cc; 
    valueObject = null; 
} 

@Override 
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 
    TextFieldCell tf = (TextFieldCell)super.getTableCellEditorComponent(table, value, isSelected, row, column); 
    if (value != null) { 
     tf.setText(value.toString()); 
    } 
    // we have to save current value to restore it on another cell selection 
    // if edited value couldn't be parsed to this cell's type 
    valueObject = value; 
    return tf; 
} 

@Override 
public Object getCellEditorValue() { 
    try { 
     // converting edited value to specified cell's type 
     if (columnClass.equals(Double.class)) 
      return Double.parseDouble(textField.getText()); 
     else if (columnClass.equals(Float.class)) 
      return Float.parseFloat(textField.getText()); 
     else if (columnClass.equals(Integer.class)) 
      return Integer.parseInt(textField.getText()); 
     else if (columnClass.equals(Byte.class)) 
      return Byte.parseByte(textField.getText()); 
     else if (columnClass.equals(String.class)) 
      return textField.getText(); 
    } 
    catch (NumberFormatException ex) { 

    } 

    // this handles restoring cell's value on jumping to another cell 
    if (valueObject != null) { 
     if (valueObject instanceof Double) 
      return ((Double)valueObject).doubleValue(); 
     else if (valueObject instanceof Float) 
      return ((Float)valueObject).floatValue(); 
     else if (valueObject instanceof Integer) 
      return ((Integer)valueObject).intValue(); 
     else if (valueObject instanceof Byte) 
      return ((Byte)valueObject).byteValue(); 
     else if (valueObject instanceof String) 
      return (String)valueObject; 
    } 

    return null; 
} 

यह आप तालिका प्रारंभ की कोड निम्नलिखित जोड़ने के लिए , यह किसी ऐसे व्यक्ति की मदद करेगा जिसकी एक ही समस्या है।

संबंधित मुद्दे