2009-02-19 20 views
8

के साथ जेटीबल मेरे पास जेटीबल के लिए कई कस्टम संपादक हैं और यह कहना कमजोर है कि उपयोगिता, विशेष रूप से कीबोर्ड के साथ संपादन के संबंध में, कमी है।एक जटिल संपादक

इसका मुख्य कारण है कि मेरे संपादकों हमेशा इस लिए एक समान (हमेशा और अधिक जटिल) की स्थिति के साथ बनाई गई हैं:

@Override 
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 
    JPanel container = new JPanel(); 
    container.setLayout(new BorderLayout()); 
    container.add(field, BorderLayout.CENTER); 
    field.setText((String) value); 
    container.add(new JButton("..."), BorderLayout.EAST); 
    return container; 
} 

यानी एक से अधिक घटक के अंदर के साथ एक पैनल। वास्तविक पाठ संपादक संपादक के रूप में वापस आने वाले घटक का वंशज है। तो, जो कुछ मैं बता सकता हूं, उससे अलग मुद्दों को प्रस्तुत करना, जेटीबल getTableCellEditorComponent विधि द्वारा वापस लौटाए गए घटक पर ध्यान केंद्रित कर रहा है, इसलिए जब आप एक सेल के साथ एक कुंजी दबाते हैं तो यह फोकस और पैनल पर कुंजी दबाता है, यह सोचकर कि संपादक।
क्या वैसे भी मैं जेटीबल को सूचित कर सकता हूं कि "असली" संपादक जेटीक्स्टफील्ड है? सही घटक पर एक हैकी requestFocusInWindow जोड़ना अपर्याप्त है क्योंकि कुंजी प्रेस पारित नहीं होगी।

उत्तर

4

कुछ संबंधित लेख here और here देखें।

सामान्य रूप से जेटीबल संपादन के बारे में एक और good article

+0

हां धन्यवाद। मुझे बस सूर्य मंच पर कुछ समान सलाह मिली है। http://forums.sun.com/thread.jspa?threadID=5368525 –

2

यदि मैं आपका प्रश्न सही ढंग से पढ़ता हूं, तो आप चाहते हैं कि उपयोगकर्ता सेल सेल एडिटर को सक्रिय किए बिना तुरंत सेल में टाइप करने में सक्षम हो, यानी, आप चाहते हैं कि जो भी कीस्ट्रोक सेल को टेक्स्ट में दर्ज किया गया पहला अक्षर बन जाए खेत।

मेरा पहला प्रयास एक संपत्ति जोड़ने के लिए था, कीबोर्ड फोकसमेनर की फोकसऑनर संपत्ति पर ध्यान दें, केवल ध्यान दें कि फोकस कभी भी जेटटेबल को नहीं छोड़ता है। आप शायद उसमें भी भाग गए। योजना बी के लिए समय बी

मुझे उस तालिका में एक KeyListener जोड़कर काम करने के लिए "पहली कीप्रेस" चीज मिल गई है जो एक उदाहरण फ़ील्ड में keyPressed() विधि के लिए अंतिम keyEvent रिकॉर्ड करता है। GetTableCellEditorComponent() विधि वहां से चरित्र को पढ़ती है। मुझे उस हैकी अनुरोध की आवश्यकता है फोकसइनविंडो() कॉल का उल्लेख है यदि उपयोगकर्ता पहले के बाद किसी भी अक्षर टाइप करना है।

मेरे नमूना ऐप के लिए, मैंने जेटीबल का एक उप-वर्ग बनाया जो कि एक कुंजीलिस्टर को स्वयं जोड़ता है। अपने सेल एडिटर इंस्टेंस को KeyListener को लागू करने और इसके बजाय नियमित जेटीबल में जोड़ने के लिए यह एक बेहतर विचार है, लेकिन मैं इसे आपके पास छोड़ दूंगा।

अपने कोड स्निपेट के रूप में मैं इसे संशोधित:

@Override 
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 
    JPanel container = new JPanel(); 
    container.setLayout(new BorderLayout()); 
    container.add(field, BorderLayout.CENTER); 

    // Will want to add an instanceof check as well as a check on Character.isLetterOrDigit(char). 
    char keypressed = ((StickyKeypressTable)table).getLastKeyPressed(); 
    field.setText(String.valueOf(keypressed)); 

    container.add(new JButton("..."), BorderLayout.EAST); 

    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      // This needs to be in an invokeLater() to work properly 
      field.requestFocusInWindow(); 
     } 
    }); 
    return container; 
} 

जहां तक ​​गंदगी चला जाता है के रूप में इस कहीं वहाँ Vogon काव्य के साथ बैठता है, लेकिन यह अपने तत्काल समस्या का समाधान करना चाहिए।

public boolean editCellAt(int row, int column, EventObject e) 
{ 
    if (cellEditor != null && !cellEditor.stopCellEditing()) 
    { 
    return false; 
    } 

    if (row < 0 || row >= getRowCount() || 
     column < 0 || column >= getColumnCount()) 
    { 
    return false; 
    } 

    if (!isCellEditable(row, column)) 
    return false; 

    TableCellEditor editor=getCellEditor(row, column); 
    if (editor != null && editor.isCellEditable(e)) 
    { 
    editorComp=prepareEditor(editor, row, column); 
    if (editorComp == null) 
     { 
     removeEditor(); 
     return false; 
     } 
    //aangepast 
    Rectangle rect=getCellRect(row, column, false); 
    if (datamodel_.useAdaptedEditorRect()) 
     rect=datamodel_.changeRectangle(rect, editorComp); 
    editorComp.setBounds(rect); 
    add(editorComp); 
    editorComp.validate(); 

    setCellEditor(editor); 
    setEditingRow(row); 
    setEditingColumn(column); 
    editor.addCellEditorListener(this); 
    //NEXT LINE ADDED 
    editorComp.requestFocus(); 
    return true; 
    } 
    return false; 
} 

फिर अपने JPanel से requestFocus ओवरलोड और सुनिश्चित करें कि आपके लेख फ़ील्ड है:

+0

उत्तर के लिए धन्यवाद। हम कुछ समय के लिए प्रभावी ढंग से यह कर रहे हैं (अलग-अलग संपादकों के लिए अलग-अलग तरीकों से) और यह हमें सभी तरह की परेशानी में डाल देता है (उदाहरण के लिए संपादक माउस द्वारा सक्रिय किया जाता है और तालिका कुंजी श्रोता अभी भी एक आखिरी कुंजी दबाया जाता है)। एक अच्छे समाधान की तलाश में। –

+0

मैं इसे थोड़ा और आगे देख रहा हूं, और अंततः आंतरिक कक्षा BasicTableUI में समाप्त हो गया। हालांकि अभी तक कोई कोड नमूने नहीं है। – Barend

0

मैं 2 चरणों

सबसे पहले अपने JTable से editCellAt ओवरराइड और संपादक की तैयारी के बाद requestFocus फोन में कुछ इसी तरह तय editorComponent के रूप में डाल दिया:

public class EditorPanel extends JPanel { 
    JComponent editorComponent; 

    public boolean isRequestFocusEnabled() 
    { 
    return true; 
    } 

    public void requestFocus() 
    { 
    editorComponent.requestFocus(); 
    } 
} 

तुम हमेशा keyEvent हड़पने और यह अपने आप सेट कर सकते हैं:

AWTEvent event = EventQueue.getCurrentEvent(); 
if (event instanceof KeyEvent) 
    { 
    char newSelection = ((KeyEvent) event).getKeyChar(); 
    int keyCode = ((KeyEvent) event).getKeyCode(); 
    editorComponent.requestFocus(); 
    if (editorComponent instanceof JTextField) 
    { 
    if ((newSelection >= (char) FIRST_ALLOWED_CHAR) && (newSelection != (char) LAST_ALLOWED_CHAR)) //comes from DefaultKeyTypedAction 
     ((JTextField) editorComponent).setText(Character.toString(newSelection)); 
    if (keyCode == KeyEvent.VK_BACK_SPACE || keyCode == KeyEvent.VK_DELETE) 
     ((JTextField) editorComponent).setText("");   
    } 
    } 
else 
    editorComponent.requestFocus(); 
+0

हाँ मैंने पहले इस दृष्टिकोण की कोशिश की है। मैंने इसे अपने कोड पर आज़माया और जैसा कि मैंने उम्मीद की थी, संपादक को सक्रिय करने वाली पहली कुंजी प्रेस पास नहीं हो रही है (जैसा कि जब आप एक साधारण संपादन क्षेत्र का उपयोग कर रहे होते हैं) यानी यदि आप सेल पर टैब करते हैं और "123" घटक में केवल "23" दिखाई देता है। –

0

मुझे लगता है कि मैंने इसे हल किया है।
आप सच बताने के लिए, मैं क्या समस्या हल पता नहीं है, के बाद से मैं एक कस्टम संपादक, एक कस्टम रेंडरर और सामान ...

उपयोग कर रहा हूँ जब एक सेल हाइलाइट किया गया है और मैं "abc" प्रेस , 3 अक्षर स्क्रीन पर जाते हैं (सेल, इस मामले में)।

grid.addKeyListener(new KeyAdapter() { 
    public void keyTyped(KeyEvent ke) { 
     int l = grid.getSelectedRow(); 
     int c = grid.getSelectedColumn(); 
     grid.editCellAt(l, c); 
    } 
}); 

खैर ... मैंने कोशिश की ... =)
(मैं अगर यह एक ही है, क्योंकि मेरी JTable संपादक के रूप में JTextField और JComboBox का उपयोग करता है पता नहीं है)।

0

मुझे बहुत ही समस्या थी। मेरे मामले में मेरे पास जटिल TableCellEditor था जिसमें जेएसपीनर और कुछ अन्य घटक शामिल थे। समस्या यह थी कि जब सेल संपादक शुरू हुआ तो मैं अपने आंतरिक घटक पर ध्यान केंद्रित करना चाहता था। मैंने panel.transferFocusDownCycle() पर कॉल करके इसे ठीक किया लेकिन बदले में कुंजीपटल घटनाओं ने काम करना बंद कर दिया - जब मेरा आंतरिक घटक फोकस करता था और मैंने कुंजी दबाया, तो मुझे उम्मीद थी कि घटक इस घटना को रोक देगा और इसका मूल्य बदल देगा। इसके बजाय तालिका ने पंक्ति फोकस को ऊपर एक में बदल दिया ... मैंने इसे KeyListener जोड़कर और सभी महत्वपूर्ण घटनाओं को सीधे आंतरिक घटक में प्रेषित करके तय किया।

यह JPanel पर आधारित रैपर वर्ग है, मैंने अपना जीवन आसान बनाने के लिए लिखा है।

public class ContainerPanel extends JPanel implements KeyListener, FocusListener { 

    private JComponent component = null; 

    public ContainerPanel(JComponent component) { 
     this.component = component; 
     addKeyListener(this); 
     addFocusListener(this); 
     setFocusCycleRoot(true); 
     setFocusTraversalPolicy(new ContainerOrderFocusTraversalPolicy()); 
     add(component); 
    } 

    @Override 
    public void keyTyped(KeyEvent e) { 
     component.dispatchEvent(e); 
    } 

    @Override 
    public void keyPressed(KeyEvent e) { 
     component.dispatchEvent(e); 
    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
     component.dispatchEvent(e); 
    } 

    @Override 
    public void focusGained(FocusEvent e) { 
     component.transferFocusDownCycle(); 
    } 

    @Override 
    public void focusLost(FocusEvent e) { 
    } 
} 
संबंधित मुद्दे