JTree चयन को रोकने से रोकने का सबसे अच्छा तरीका क्या हो रहा है?

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

मैंने JTree पर एक मूल्यChangeListener के साथ ऐसा करने का प्रयास किया, लेकिन वर्तमान में उसके पास मूल्य है, अगर कोई त्रुटि हो तो पुराने चयन में "setSelectionRow" कॉल करें। इसलिए मुझे स्टैक ओवरफ्लो नहीं मिलता है, मैंने ऐसा करने से पहले एक बुलियन "isError" सत्य करने के लिए सेट किया है ताकि मैं नए मान को बदलकर ईवेंट को अनदेखा कर सकूं। किसी भी तरह मुझे आंत महसूस होता है कि यह सबसे अच्छा समाधान नहीं है। ;-)

इसके बजाय मैं इसके बारे में कैसे जाऊं? क्या इस तरह की स्थितियों के लिए एक अच्छा डिजाइन पैटर्न है?

0

6 उत्तर

एक TreeSelectionModel सेट करें जो उचित अर्थशास्त्र लागू करता है।

0
जोड़ा

सुनिश्चित नहीं है कि यह सबसे अच्छा अभ्यास है, लेकिन हो सकता है कि आप उस फोकस लिस्टर को उस घटक (ओं) पर मान्य कर सकें जिसे आप सत्यापित करना चाहते हैं ... ईवेंट को कॉल करते समय अपना सत्यापन कॉल करें और फिर यदि आप फोकस को स्थानांतरित नहीं करना चाहते हैं तो तब ईवेंट का उपभोग करें क्योंकि सत्यापन विफल रहता है?

बाद में संपादित करें:

कम से कम जावा 8 के साथ (मैंने पिछले संस्करणों की जांच नहीं की थी) यह समाधान काम नहीं करेगा, क्योंकि फोकसइवेंट निम्न स्तर की घटना नहीं है। इसलिए इसे खपत नहीं किया जा सकता है। विधि AWTEvent.consume देखें ()

0
जोड़ा
यह आदर्श दृष्टिकोण है, आईएमओ
जोड़ा लेखक Steve McLeod, स्रोत

यहां एक TreeSelectionModel को लागू करने का एक उदाहरण दिया गया है जो एक और TreeSelectionModel को लपेटता है लेकिन चयन को वीटो करने की अनुमति देता है:

public class VetoableTreeSelectionModel implements TreeSelectionModel
{
   private final ListenerList m_vetoableTreeSelectionListeners = new ListenerList();

   private final DefaultTreeSelectionModel m_treeSelectionModel = new DefaultTreeSelectionModel();

   /**
    * {@inheritDoc}
    */
   public void addTreeSelectionListener(final TreeSelectionListener listener)
   {
      m_treeSelectionModel.addTreeSelectionListener(listener);
   }

   /**
    * {@inheritDoc}
    */
   public void removeTreeSelectionListener(final TreeSelectionListener listener)
   {
      m_treeSelectionModel.removeTreeSelectionListener(listener);
   }

   /**
    * Add a vetoable tree selection listener
    *
    * @param listener the listener
    */
   public void addVetoableTreeSelectionListener(final VetoableTreeSelectionListener listener)
   {
      m_vetoableTreeSelectionListeners.addListener(listener);
   }

   /**
    * Remove a vetoable tree selection listener
    *
    * @param listener the listener
    */
   public void removeVetoableTreeSelectionListener(final VetoableTreeSelectionListener listener)
   {
      m_vetoableTreeSelectionListeners.removeListener(listener);
   }

   /**
    * {@inheritDoc}
    */
   public void addPropertyChangeListener(final PropertyChangeListener listener)
   {
      m_treeSelectionModel.addPropertyChangeListener(listener);
   }

   /**
    * {@inheritDoc}
    */
   public void removePropertyChangeListener(final PropertyChangeListener listener)
   {
      m_treeSelectionModel.removePropertyChangeListener(listener);
   }

   /**
    * {@inheritDoc}
    */
   public void addSelectionPath(final TreePath path)
   {
      try
      {
         m_vetoableTreeSelectionListeners.fireVetoableEvent(new VetoableAction() {
            public void fireEvent(final VetoableTreeSelectionListener listener) throws EventVetoedException
            {
               listener.aboutToAddSelectionPath(path);
            }});

         m_treeSelectionModel.addSelectionPath(path);
      }
      catch (final EventVetoedException e)
      {
         return;
      }
   }

   /**
    * {@inheritDoc}
    */
   public void addSelectionPaths(final TreePath[] paths)
   {
      try
      {
         m_vetoableTreeSelectionListeners.fireVetoableEvent(new VetoableAction() {
            public void fireEvent(final VetoableTreeSelectionListener listener) throws EventVetoedException
            {
               listener.aboutToAddSelectionPaths(paths);
            }});

         m_treeSelectionModel.addSelectionPaths(paths);
      }
      catch (final EventVetoedException e)
      {
         return;
      }
   }

   /**
    * {@inheritDoc}
    */
   public void clearSelection()
   {
      try
      {
         m_vetoableTreeSelectionListeners.fireVetoableEvent(new VetoableAction() {
            public void fireEvent(final VetoableTreeSelectionListener listener) throws EventVetoedException
            {
               listener.aboutToClearSelection();
            }});

         m_treeSelectionModel.clearSelection();
      }
      catch (final EventVetoedException e)
      {
         return;
      }
   }

   /**
    * {@inheritDoc}
    */
   public TreePath getLeadSelectionPath()
   {
      return m_treeSelectionModel.getLeadSelectionPath();
   }

   /**
    * {@inheritDoc}
    */
   public int getLeadSelectionRow()
   {
      return m_treeSelectionModel.getLeadSelectionRow();
   }

   /**
    * {@inheritDoc}
    */
   public int getMaxSelectionRow()
   {
      return m_treeSelectionModel.getMaxSelectionRow();
   }

   /**
    * {@inheritDoc}
    */
   public int getMinSelectionRow()
   {
      return m_treeSelectionModel.getMinSelectionRow();
   }

   /**
    * {@inheritDoc}
    */
   public RowMapper getRowMapper()
   {
      return m_treeSelectionModel.getRowMapper();
   }

   /**
    * {@inheritDoc}
    */
   public int getSelectionCount()
   {
      return m_treeSelectionModel.getSelectionCount();
   }

   public int getSelectionMode()
   {
      return m_treeSelectionModel.getSelectionMode();
   }

   /**
    * {@inheritDoc}
    */
   public TreePath getSelectionPath()
   {
      return m_treeSelectionModel.getSelectionPath();
   }

   /**
    * {@inheritDoc}
    */
   public TreePath[] getSelectionPaths()
   {
      return m_treeSelectionModel.getSelectionPaths();
   }

   /**
    * {@inheritDoc}
    */
   public int[] getSelectionRows()
   {
      return m_treeSelectionModel.getSelectionRows();
   }

   /**
    * {@inheritDoc}
    */
   public boolean isPathSelected(final TreePath path)
   {
      return m_treeSelectionModel.isPathSelected(path);
   }

   /**
    * {@inheritDoc}
    */
   public boolean isRowSelected(final int row)
   {
      return m_treeSelectionModel.isRowSelected(row);
   }

   /**
    * {@inheritDoc}
    */
   public boolean isSelectionEmpty()
   {
      return m_treeSelectionModel.isSelectionEmpty();
   }

   /**
    * {@inheritDoc}
    */
   public void removeSelectionPath(final TreePath path)
   {
      try
      {
         m_vetoableTreeSelectionListeners.fireVetoableEvent(new VetoableAction() {
            public void fireEvent(final VetoableTreeSelectionListener listener) throws EventVetoedException
            {
               listener.aboutRemoveSelectionPath(path);
            }});

         m_treeSelectionModel.removeSelectionPath(path);
      }
      catch (final EventVetoedException e)
      {
         return;
      }
   }

   /**
    * {@inheritDoc}
    */
   public void removeSelectionPaths(final TreePath[] paths)
   {
      try
      {
         m_vetoableTreeSelectionListeners.fireVetoableEvent(new VetoableAction() {
            public void fireEvent(final VetoableTreeSelectionListener listener) throws EventVetoedException
            {
               listener.aboutRemoveSelectionPaths(paths);
            }});

         m_treeSelectionModel.removeSelectionPaths(paths);
      }
      catch (final EventVetoedException e)
      {
         return;
      }
   }

   /**
    * {@inheritDoc}
    */
   public void resetRowSelection()
   {
      try
      {
         m_vetoableTreeSelectionListeners.fireVetoableEvent(new VetoableAction() {
            public void fireEvent(final VetoableTreeSelectionListener listener) throws EventVetoedException
            {
               listener.aboutToResetRowSelection();
            }});

         m_treeSelectionModel.resetRowSelection();
      }
      catch (final EventVetoedException e)
      {
         return;
      }
   }

   /**
    * {@inheritDoc}
    */
   public void setRowMapper(final RowMapper newMapper)
   {
      m_treeSelectionModel.setRowMapper(newMapper);
   }

   /**
    * {@inheritDoc}
    */
   public void setSelectionMode(final int mode)
   {
      try
      {
         m_vetoableTreeSelectionListeners.fireVetoableEvent(new VetoableAction() {
            public void fireEvent(final VetoableTreeSelectionListener listener) throws EventVetoedException
            {
               listener.aboutToSetSelectionMode(mode);
            }});

         m_treeSelectionModel.setSelectionMode(mode);
      }
      catch (final EventVetoedException e)
      {
         return;
      }
   }

   /**
    * {@inheritDoc}
    */
   public void setSelectionPath(final TreePath path)
   {
      try
      {
         m_vetoableTreeSelectionListeners.fireVetoableEvent(new VetoableAction() {
            public void fireEvent(final VetoableTreeSelectionListener listener) throws EventVetoedException
            {
               listener.aboutToSetSelectionPath(path);
            }});

         m_treeSelectionModel.setSelectionPath(path);
      }
      catch (final EventVetoedException e)
      {
         return;
      }
   }

   /**
    * {@inheritDoc}
    */
   public void setSelectionPaths(final TreePath[] paths)
   {
      try
      {
         m_vetoableTreeSelectionListeners.fireVetoableEvent(new VetoableAction() {
            public void fireEvent(final VetoableTreeSelectionListener listener) throws EventVetoedException
            {
               listener.aboutToSetSelectionPaths(paths);
            }});

         m_treeSelectionModel.setSelectionPaths(paths);
      }
      catch (final EventVetoedException e)
      {
         return;
      }
   }

   /**
    * {@inheritDoc}
    */
   @Override
   public String toString()
   {
      return m_treeSelectionModel.toString();
   }

}

और श्रोता यहां जाने के लिए है:

public interface VetoableTreeSelectionListener
{
   /**
    * About to add a path to the selection
    *
    * @param path the path to add
    *
    * @throws EventVetoedException
    */
   void aboutToAddSelectionPath(TreePath path) throws EventVetoedException;

   /**
    * About to add paths to the selection
    *
    * @param paths the paths to add
    *
    * @throws EventVetoedException
    */
   void aboutToAddSelectionPaths(TreePath[] paths) throws EventVetoedException;

   /**
    * About to clear selection
    *
    * @throws EventVetoedException
    */
   void aboutToClearSelection() throws EventVetoedException;

   /**
    * About to remove a selection path
    *
    * @param path the path
    *
    * @throws EventVetoedException
    */
   void aboutRemoveSelectionPath(TreePath path) throws EventVetoedException;

   /**
    * About to remove multiple selection paths
    *
    * @param paths the paths
    *
    * @throws EventVetoedException
    */
   void aboutRemoveSelectionPaths(TreePath[] paths) throws EventVetoedException;

   /**
    * About to reset the row selection
    *
    * @throws EventVetoedException
    */
   void aboutToResetRowSelection() throws EventVetoedException;

   /**
    * About to set the selection mode
    *
    * @param mode the selection mode
    *
    * @throws EventVetoedException
    */
   void aboutToSetSelectionMode(int mode) throws EventVetoedException;

   /**
    * About to set the selection path
    *
    * @param path the path
    *
    * @throws EventVetoedException
    */
   void aboutToSetSelectionPath(TreePath path) throws EventVetoedException;

   /**
    * About to set the selection paths
    *
    * @param paths the paths
    *
    * @throws EventVetoedException
    */
   void aboutToSetSelectionPaths(TreePath[] paths) throws EventVetoedException;
}

आप श्रोता सूची के अपने कार्यान्वयन का उपयोग कर सकते हैं, लेकिन आपको विचार मिलता है ...

0
जोड़ा

मेरा समाधान यहाँ है।

एक जेटीरी सबक्लास में:

protected void processMouseEvent(MouseEvent e) {
        TreePath selPath = getPathForLocation(e.getX(), e.getY());
        try {
            fireVetoableChange(LEAD_SELECTION_PATH_PROPERTY, getLeadSelectionPath(), selPath);
        }
        catch (PropertyVetoException ex) {
           //OK, we do not want change to happen
            return;
        }

        super.processMouseEvent(e);
}

फिर कक्षा का उपयोग कर पेड़ में:

VetoableChangeListener vcl = new VetoableChangeListener() {

        public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException {
            if ( evt.getPropertyName().equals(JTree.LEAD_SELECTION_PATH_PROPERTY) ) {
                try {
                    
                } catch (InvalidInputException e) {
                    throw new PropertyVetoException("", evt);
                }

            }
        }
    };
    tree.addVetoableChangeListener(vcl);

तंत्र जल्द से जल्द संभव स्थान पर शुरू होता है। माउस एक्शन को अवरुद्ध किया गया, चुना जाने वाला मार्ग VetoableChangeListeners को विज्ञापित किया जाता है। कंक्रीट वीसीएल में बदलती संपत्ति की जांच की जाती है और यदि यह मुख्य चयन है, तो वीटो तर्क की जांच की जाती है। यदि वीटोइंग की आवश्यकता है, तो वीसीएल PropertyVetoException फेंकता है, अन्यथा माउस इवेंट हैंडलिंग सामान्य के रूप में चला जाता है और चयन होता है। संक्षेप में, यह लीड चयन संपत्ति को बाधित संपत्ति बन जाती है।

0
जोड़ा
इसके लिए धन्यवाद!
जोड़ा लेखक The111, स्रोत

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

तो अब वास्तविक समाधान के लिए!
स्टैक डंप प्राप्त करने के लिए कुछ Thread.dumpStack() कॉल का उपयोग करने के बाद, मुझे वह तरीका मिला जो मैं ओवरराइड करना चाहता था। मैंने बेसिकट्रीयूआई को बढ़ाया और "संरक्षित शून्य चयनपैथफोर्ड (ट्रीपाथ पथ, माउसइवेंट इवेंट)" को ओवरराइड किया।

इससे आपको माउस ईवेंट तक पहुंच मिल जाएगी जिससे चयन से पहले चयन होता है। फिर आप event.consume() पर जो भी तर्क चाहते हैं उसका उपयोग कर सकते हैं और अगर आप चयन को रोकना चाहते हैं, तो जो भी चयन आप चाहते हैं उसे करें या सुपर.सेक्स्टपाथफोरवेन्ट (पथ, घटना) को कॉल करके डिफ़ॉल्ट प्रोसेसिंग के लिए इसे पास करें;

बस जेटी में बनाए गए यूआई को सेट करना याद रखें। उस गलती ने मेरे जीवन के कुछ मिनटों को बर्बाद कर दिया ;-)

0
जोड़ा

चयन को रोकने के लिए मैंने बस डिफॉल्ट ट्रीसेलेक्शन मॉडल को उप-वर्गीकृत किया और उन ऑब्जेक्ट्स को जांचने के लिए सभी विधियों को ओवरराइड किया जिन्हें मैं नहीं चुनना चाहता था (नीचे दिए गए मेरे उदाहरण में "DisplayRepoOwner" के उदाहरण)। अगर ऑब्जेक्ट का चयन करना ठीक था, तो मैंने सुपर विधि को बुलाया; अन्यथा मैंने नहीं किया। मैंने अपने जेटीआर के चयन मॉडल को उस सबक्लास के उदाहरण में सेट किया।

public class MainTreeSelectionModel extends DefaultTreeSelectionModel {
public void addSelectionPath(TreePath path) {
    if (path.getLastPathComponent() instanceof DisplayRepoOwner) {
        return;
    }
    super.addSelectionPath(path);
}
public void addSelectionPaths(TreePath[] paths) {
    for (TreePath tp : paths) {
        if (tp.getLastPathComponent() instanceof DisplayRepoOwner) {
            return;
        }
    }
    super.addSelectionPaths(paths);
}
public void setSelectionPath(TreePath path) {
    if (path.getLastPathComponent() instanceof DisplayRepoOwner) {
        return;
    }
    super.setSelectionPath(path);
}
public void setSelectionPaths(TreePath[] paths) {
    for (TreePath tp : paths) {
        if (tp.getLastPathComponent() instanceof DisplayRepoOwner) {
            return;
        }
    }
    super.setSelectionPaths(paths);
}

}

0
जोड़ा