2015-01-30 10 views
8

जब मैं अपने डेटा को प्रस्तुत और संपादित करने के लिए एक JXTable का उपयोग कर रहा हूं, तो सेलइडिटर में कुछ इनपुट खो जाता है। यदि मैं JXTable-ColumnHeader के Resizing-Divider पर क्लिक करता हूं या JFrame की चौड़ाई बदलता हूं, तो सेल एडिटर मूल्य को कम किए बिना समाप्त हो जाता है। यदि मैं जेटीबल का उपयोग करता हूं तो मान सहेजे जाते हैं।JXTable इनपुट खोने क्यों है जहां JTable नहीं है?

मैं अपनी अन्य सुविधाओं के कारण JXTable का उपयोग करना चाहता हूं, तो क्या JXTable को ठीक करने का कोई तरीका है?

Screenrecording

उदाहरण:

package table.columnresize; 

import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.table.DefaultTableModel; 

import org.jdesktop.swingx.JXTable; 

/** 
* Demo of differing behaviour of JXTable and JTable. JXTable loses input in a TableCell where JTable persists 
* it. 
* <p> 
* <table border=1> 
* <tr> 
* <th></th> 
* <th>JXTable</th> 
* <th>JTable</th> 
* </tr> 
* <tr> 
* <td>Click on TableColumnHeader</td> 
* <td>saved</td> 
* <td>saved</td> 
* </tr> 
* <tr> 
* <td>Resizing with Divider of TableColumnHeader</td> 
* <td>lost</td> 
* <td>saved</td> 
* </tr> 
* <tr> 
* <td>Changing the width of JFrame</td> 
* <td>lost</td> 
* <td>saved</td> 
* </tr> 
* 
* </table> 
* </p> 
* 
* @author bobndrew 2015-01-29 
*/ 
public class JXTableAndJTableEditLossDemo 
{ 
    private static class DataModel extends DefaultTableModel 
    { 
    public DataModel(Object[][] data, Object[] columnNames) 
    { 
     super(data, columnNames); 
    } 
    } 

    private static void createAndShowUI() 
    { 
    Object[][] DATA = { { "One", 1 }, { "Two", 2 }, { "Three", 3 }, { "Four", 4 }, { "Five", 5 } }; 
    String[] COLUMNS = { "A", "B" }; 
    DataModel dataModel = new DataModel(DATA, COLUMNS); 

    JFrame frame1 = new JFrame("JXTable"); 
    JXTable jXTable = new JXTable(dataModel); 
    //does not change anything: jXTable.setTerminateEditOnFocusLost(true); 
    System.out.println(jXTable.isTerminateEditOnFocusLost()); 
    frame1.add(new JScrollPane(jXTable)); 
    frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame1.pack(); 
    frame1.setVisible(true); 

    JFrame frame2 = new JFrame("JTable"); 
    JTable jTable = new JTable(dataModel); 
    //does not change anything: jTable.putClientProperty("terminateEditOnFocusLost", Boolean.FALSE); 
    System.out.println(jTable.getClientProperty("terminateEditOnFocusLost")); 
    frame2.add(new JScrollPane(jTable)); 
    frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame2.pack(); 
    frame2.setLocation((int) frame1.getLocation().getX() + frame1.getWidth() + 100, (int) frame1 
     .getLocation().getY()); 
    frame2.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
    java.awt.EventQueue.invokeLater(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
     createAndShowUI(); 
     } 
    }); 
    } 

} 
+0

क्या आपने JXTable पर एक कस्टम फोकस श्रोता जोड़ने की कोशिश की है? इस पोस्ट पर दूसरा और तीसरा जवाब देखें। http://stackoverflow.com/questions/1652942/can-a-jtable-save-data-whenever-a-cell-loses-focus –

+0

अच्छा विचार है, लेकिन एक फोकस लिस्टर विभिन्न ऑपरेटिंग सिस्टम के तहत बहुत अविश्वसनीय है। – bobndrew

उत्तर

3

JXTable और JTable डीबग करते समय मुझे सेलएडिट्स के नुकसान का कारण मिला।

if (isEditing()) { 
    removeEditor(); 
} 

JTable:

JXTable: अंतर विधि columnMarginChanged() में है मैंने सोचा था कि removeEditor() विधि JTable का बढ़ा हुआ है पहले तो

if (isEditing() && !getCellEditor().stopCellEditing()) { 
    getCellEditor().cancelCellEditing(); 
} 

... लेकिन तब मैं यह OpenJDK changeset from September 2010 पाया गया जो बग "4330 9 50: कॉलम चौड़ाई का आकार बदलते समय सेल में नए दर्ज डेटा खो गया"। ऐसा लगता है कि जेडीके से परिवर्तन स्विंगएक्स स्रोत कोड पर लागू नहीं किए गए थे।

मैं अपना उत्तर स्वीकार करूंगा क्योंकि अलग-अलग व्यवहार का कारण अब स्पष्ट है। मेरे और अन्य स्विंगएक्स उपयोगकर्ताओं के लिए इसे ठीक करने के लिए मैं स्विंगएक्स मेलिंग सूची और बग ट्रैकर पर जाउंगा।

1

जब आप JTable की विधि frameInit() पर एक नज़र डालें, तो आप देख सकते हैं कि यह सब AWTEvent.WINDOW * घटनाओं को बांधता है। JXTable में initActionsAndBindings() विधि विशिष्ट क्रियाओं (जैसे मान परिवर्तित), और केवल तालिका के लिए बाध्य होती है।

आप अपनी खुद की श्रोता

jXTable.getColumnModel().addColumnModelListener(new TableColumnModelListener() { 
     @Override 
     public void columnMarginChanged(ChangeEvent e) { 

     } 
    }); 

जोड़ने और फिर करने की आवश्यकता होगी तालिका की कुछ कार्यक्षमता को बेनकाब करने के घटना तालिका को अद्यतन करने को ट्रिगर करने के लिए होगा। या शायद आप वहां से TableModelEvent ट्रिगर कर सकते हैं।

+0

'frameInit()' 'JFrame.java' में एक विधि है और 'JTable.java' नहीं है। लेकिन 'TableColumnModelListener' और 'columnMarginChanged()' के साथ आपका विचार मेरे निष्कर्षों के समान है; मेरा जवाब देखें – bobndrew

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