From 980cbd19e805f19d5ccdad5698b580e53acbc9cf Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Fri, 8 Apr 2016 15:48:58 +0300 Subject: [PATCH] utility classes to create custom tree models --- .../util/ui/tree/TreeModelAdapter.java | 52 ++++++- .../util/ui/tree/TreeModelListenerList.java | 127 ++++++++++++++++++ 2 files changed, 173 insertions(+), 6 deletions(-) create mode 100644 platform/util/src/com/intellij/util/ui/tree/TreeModelListenerList.java diff --git a/platform/util/src/com/intellij/util/ui/tree/TreeModelAdapter.java b/platform/util/src/com/intellij/util/ui/tree/TreeModelAdapter.java index 8f343bb4d34e..3b15615f3d19 100644 --- a/platform/util/src/com/intellij/util/ui/tree/TreeModelAdapter.java +++ b/platform/util/src/com/intellij/util/ui/tree/TreeModelAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,21 +20,61 @@ import javax.swing.event.TreeModelListener; /** * @author dyoma + * @author Sergey.Malenkov */ public abstract class TreeModelAdapter implements TreeModelListener { - @Override - public void treeNodesChanged(TreeModelEvent e) { + public enum EventType {StructureChanged, NodesChanged, NodesInserted, NodesRemoved} + + /** + * Invoked after a tree has changed. + * + * @param event the event object specifying changed nodes + * @param type the event type specifying a kind of changes + */ + protected void process(TreeModelEvent event, EventType type) { } + /** + * Invoked after a tree hierarchy has changed. + * By default, it calls the {@link #process} method with the corresponding event type. + * + * @param event the event object specifying a node with changed hierarchy + */ @Override - public void treeNodesInserted(TreeModelEvent e) { + public void treeStructureChanged(TreeModelEvent event) { + if (event != null) process(event, EventType.StructureChanged); } + /** + * Invoked after some nodes have been changed. + * By default, it calls the {@link #process} method with the corresponding event type. + * + * @param event the event object specifying changed nodes + */ @Override - public void treeNodesRemoved(TreeModelEvent e) { + public void treeNodesChanged(TreeModelEvent event) { + if (event != null) process(event, EventType.NodesChanged); } + /** + * Invoked after some nodes have been inserted. + * By default, it calls the {@link #process} method with the corresponding event type. + * + * @param event the event object specifying inserted nodes + */ @Override - public void treeStructureChanged(TreeModelEvent e) { + public void treeNodesInserted(TreeModelEvent event) { + if (event != null) process(event, EventType.NodesInserted); + } + + /** + * Invoked after some nodes have been removed. + * By default, it calls the {@link #process} method with the corresponding event type. + * + * @param event the event object specifying removed nodes + */ + @Override + public void treeNodesRemoved(TreeModelEvent event) { + if (event != null) process(event, EventType.NodesRemoved); } } diff --git a/platform/util/src/com/intellij/util/ui/tree/TreeModelListenerList.java b/platform/util/src/com/intellij/util/ui/tree/TreeModelListenerList.java new file mode 100644 index 000000000000..fdbfea7a13bd --- /dev/null +++ b/platform/util/src/com/intellij/util/ui/tree/TreeModelListenerList.java @@ -0,0 +1,127 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.ui.tree; + +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import java.util.ArrayDeque; + +/** + * @author Sergey.Malenkov + */ +public final class TreeModelListenerList implements TreeModelListener { + private final ArrayDeque myDeque = new ArrayDeque(); + + /** + * Adds a listener for changes in a tree model. + * This method is safe for use by multiple concurrent threads. + * + * @param listener a listener to add + */ + public void add(TreeModelListener listener) { + if (listener != null) { + synchronized (myDeque) { + myDeque.addFirst(listener); + } + } + } + + /** + * Removes a previously added listener. + * This method is safe for use by multiple concurrent threads. + * + * @param listener a listener to remove + */ + public void remove(TreeModelListener listener) { + if (listener != null) { + synchronized (myDeque) { + myDeque.remove(listener); + } + } + } + + /** + * Returns {@code true} if no listeners have been added. + * This method is safe for use by multiple concurrent threads. + * + * @return {@code true} if no listeners have been added, or {@code false} otherwise + */ + public boolean isEmpty() { + synchronized (myDeque) { + return myDeque.isEmpty(); + } + } + + /** + * Returns all added listeners or an empty array if no listeners have been added. + * This method is safe for use by multiple concurrent threads. + * + * @return all added listeners + */ + public TreeModelListener[] get() { + synchronized (myDeque) { + return myDeque.toArray(new TreeModelListener[0]); + } + } + + /** + * Notifies all added listeners that a tree hierarchy was changed. + * + * @param event the event object specifying a node with changed hierarchy + */ + @Override + public void treeStructureChanged(TreeModelEvent event) { + for (TreeModelListener listener : get()) { + listener.treeStructureChanged(event); + } + } + + /** + * Notifies all added listeners that some nodes were changed. + * + * @param event the event object specifying changed nodes + */ + @Override + public void treeNodesChanged(TreeModelEvent event) { + for (TreeModelListener listener : get()) { + listener.treeNodesChanged(event); + } + } + + /** + * Notifies all added listeners that some nodes were inserted. + * + * @param event the event object specifying inserted nodes + */ + @Override + public void treeNodesInserted(TreeModelEvent event) { + for (TreeModelListener listener : get()) { + listener.treeNodesInserted(event); + } + } + + /** + * Notifies all added listeners that some nodes were removed. + * + * @param event the event object specifying removed nodes + */ + @Override + public void treeNodesRemoved(TreeModelEvent event) { + for (TreeModelListener listener : get()) { + listener.treeNodesRemoved(event); + } + } +}