2012-03-06 20 views
5

मैं एक JToggleButton (कि कस्टम पृष्ठभूमि है) की आवश्यकता है कि के भीतर ही कई JLabels के साथ एक JPanel हो उसमें भीतर JPanel साथ JToggleButton लगाकर। वह हिस्सा काम करता है।एक JTable सेल

यह बटन एक JTable सेल में बाद में रख दिया गया है और उपयोगकर्ताओं द्वारा दबाया जा करने के लिए है। समस्या यह है कि मैं केवल दूसरे क्लिक पर बटन दबा सकता हूं। पहली बार पर क्लिक करें फोकस पहले जेएलएबल्स के साथ पैनल में कूदता है और केवल बाद में वास्तविक बटन पर जाता है।

मैंने इस मुद्दे को हल करने के लिए कई चीजों की कोशिश की, लेकिन एक ही मुद्दा बनी हुई है। ए) जेपीनल को लेबल्स के साथ सीधे JToggleButton # add() पर रखकर। बी) JLayeredPane अलग परतों पर बटन और JPanel जगह का उपयोग कर जहां JToggleButton लेता बाधा पूर्णांक (-) ताकि JLabels साथ JPanel शीर्ष

आप कोई सुझाव है पर दिखाई रहता है? धन्यवाद

नीचे एक नमूना कोड है जो समस्या को दर्शाता है। बटन पर क्लिक करना केवल दूसरी बार काम करता है।

public class ClickableCustomButtonInTable extends JToggleButton { 

public ClickableCustomButtonInTable() { 
    Dimension d = new Dimension(100, 100); 
    JLabel lFirst = new JLabel("1st label"); 
    lFirst.setPreferredSize(d); 

    JLabel lSecond = new JLabel("2nd label"); 
    lSecond.setPreferredSize(d); 

    JPanel panel = new JPanel(); 
    panel.setOpaque(true); 

    panel.setLayout(new BorderLayout()); 
    panel.add(lFirst, BorderLayout.NORTH); 
    panel.add(lSecond, BorderLayout.SOUTH); 
    add(panel); 
    addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("Button clicked"); 
     } 
    }); 
} 

private static class CustomButtonRenderer implements TableCellRenderer { 

    private final ClickableCustomButtonInTable button = new ClickableCustomButtonInTable(); 

    @Override 
    public Component getTableCellRendererComponent(JTable table, 
      Object value, boolean isSelected, boolean hasFocus, int row, 
      int column) { 
     return button; 
    } 
} 

private static class CustomButtonEditor extends AbstractCellEditor 
     implements TableCellEditor { 

    private final ClickableCustomButtonInTable button = new ClickableCustomButtonInTable(); 

    @Override 
    public Object getCellEditorValue() { 
     return button.getText(); 
    } 

    @Override 
    public Component getTableCellEditorComponent(JTable table, 
      Object value, boolean isSelected, int row, int column) { 
     return button; 
    } 

} 

public static void main(String[] args) { 
    JFrame frame = new JFrame(); 
    frame.setSize(new Dimension(200, 200)); 
    Container content = frame.getContentPane(); 
    TableModel model = new AbstractTableModel() { 

     @Override 
     public Object getValueAt(int rowIndex, int columnIndex) { 
      return null; 
     } 

     @Override 
     public int getRowCount() { 
      return 1; 
     } 

     @Override 
     public int getColumnCount() { 
      return 1; 
     } 

     @Override 
     public boolean isCellEditable(int rowIndex, int columnIndex) { 
      return true; 
     } 

     @Override 
     public Class<?> getColumnClass(int columnIndex) { 
      return ClickableCustomButtonInTable.class; 
     } 
    }; 

    JTable table = new JTable(model); 
    // table.setBounds(new Rectangle(0, 0, content.getWidth(), content 
    // .getHeight())); 
    table.setRowHeight(frame.getHeight()); 
    table.setDefaultRenderer(ClickableCustomButtonInTable.class, 
      new CustomButtonRenderer()); 
    table.setDefaultEditor(ClickableCustomButtonInTable.class, 
      new CustomButtonEditor()); 

    content.add(table); 
    content.setVisible(true); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setVisible(true); 
} 
} 
+1

सीधे आपकी समस्या से संबंधित नहीं: संपादक कार्यान्वयन _invalid_ है: यह _must_ अपने श्रोताओं में सूचित करते हैं संपादन आंतरिक कारणों से समाप्त कर दिया जाता। आपकी समस्या के अनुसार: मूल रूप से आपको एक करना होगा) सुनिश्चित करें कि पहले क्लिक पर संपादन शुरू हो गया है b) उस क्लिक को पकड़ें, घटक समन्वय संपादन में अपनी स्थिति की गणना करें और संपादन पर "असली" लक्ष्य घटक (fi बटन) पर प्रेषित करें पैनल – kleopatra

+2

बीटीडब्ल्यू: आप _never-ever_ अपनी तालिका में घटक रखो मॉडल ... क्योंकि आपकी टेबल मॉडल कार्यान्वयन भी खराब है (यह संपादन योग्य होने की घोषणा करता है लेकिन सेल मानों को बदलने के लिए कोई एपीआई गायब है), शायद आपको कुछ पढ़ना चाहिए और समझना चाहिए टेबल की मूल बातें न तो छोटी-छोटी चीजों के बीच में कूदने से पहले :-) – kleopatra

+0

@ क्लेओपेट्रा, आपकी युक्तियों के लिए धन्यवाद। क्या आप शायद लिंक/दिखा सकते हैं कि कैसे करें) सुनिश्चित करें कि पहले क्लिक पर संपादन शुरू हो गया है b) उस क्लिक को पकड़ें, घटक समन्वय संपादन में अपनी स्थिति की गणना करें और संपादन पैनल पर "वास्तविक" लक्ष्य घटक को प्रेषित करें मैं नहीं हूं सुनिश्चित करें कि वास्तविक लक्ष्य में ईवेंट प्रेषित करके आपका क्या मतलब है, क्या यह है कि क्लिक करें() कॉल करें जिसका मतलब है।यदि हां, तो मुझे डर है कि मैं उस क्लिक एनीमेशन को खो दूंगा जो jToggleButton प्रदान करता है। – d56

उत्तर

0
+1

जो शायद आपके करियर को नहीं बचाएगा ;-) बेहतर सीखें कि _correctly_ टेबल/रेंडरर्स/संपादकों का उपयोग कैसे करें ... – kleopatra

+0

उस समाधान के साथ क्या गलत है? – d56

+0

सब कुछ गलत है, अपने प्रश्न ... – kleopatra

8

तालिका एक सेल यह है कि घटक माउस घटनाओं संभाल कर सकते हैं चाहे गहरी घटक के लिए पर माउस घटना गुजरता चयन करने के लिए एक माउस घटना कब्जा है। आपके उदाहरण में पहला क्लिक में से एक पर समाप्त होता है, JToggleButton को पूरी तरह से छोड़कर। एक बार JToggleButton सक्रिय सेल संपादक बन गया है, माउस क्लिक सामान्य रूप से उस पर काम करते हैं। यदि यह फोकस खोना था, तो इसे फिर से सक्रिय करने के लिए दो-क्लिक की आवश्यकता होगी।

इस करता है, तो आप आप बटन सीमा पर क्लिक करें, निहित पैनल पर नहीं अपने प्रदर्शन में देखते हैं, बटन काम करता है के रूप में वांछित देख सकते हैं। इससे बचने के लिए

एक तरीका यह सुनिश्चित करना है कि किसी भी माउस घटना है कि JToggleButton के भीतर किसी भी घटक पर लक्षित है। अपने निर्माता आह्वान के अंत में

static void addEventBubble(final Container target, Container container) { 
    for(Component comp:container.getComponents()) { 
     if (comp instanceof Container) { 
      addEventBubble(target, (Container) comp); 
     } 
     comp.addMouseListener(new MouseAdapter() { 
      private MouseEvent retarget(MouseEvent e) { 
       return new MouseEvent(target, e.getID(), e.getWhen(), 
         e.getModifiers(), e.getX(), e.getY(), 
         e.getClickCount(), e.isPopupTrigger(), 
         e.getButton()); 
      } 


      public void mousePressed(MouseEvent e) { 
       MouseEvent r = retarget(e); 
       for(MouseListener listen:target.getMouseListeners()) { 
        listen.mousePressed(r); 
       } 
      } 


      public void mouseReleased(MouseEvent e) { 
       MouseEvent r = retarget(e); 
       for(MouseListener listen:target.getMouseListeners()) { 
        listen.mouseReleased(r); 
       } 
      } 


      public void mouseClicked(MouseEvent e) { 
       MouseEvent r = retarget(e); 
       for(MouseListener listen:target.getMouseListeners()) { 
        listen.mouseClicked(r); 
       } 
      } 
     }); 
    } 
} 

और उसके बाद:: आप इस का उपयोग करते हुए इस स्थैतिक विधि कर सकते हैं

addEventBubble(this,this); 

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

+0

मुझे http://www.coderanch.com/t/570021/GUI/java पर एक और समाधान दिया गया था/क्लिक-इवेंट-कस्टम-जेटीओगलगटन-जेटटेबल यह "भंगुर" लेकिन कम कोड है। मुझे लगता है कि मैं इसके साथ रहूँगा। स्पष्टीकरण और समाधान के लिए धन्यवाद, मुझे बहुत कुछ चाहिए। – d56

+0

देखा, "भंगुर" वास्तव में इसके लिए शब्द है :) साझा करने के लिए धन्यवाद। –