org.nuiton.jaxx.runtime.swing.nav.treetable.NavTreeTableBridge Maven / Gradle / Ivy
The newest version!
/*
* #%L
* JAXX :: Runtime
* %%
* Copyright (C) 2008 - 2024 Code Lutin, Ultreia.io
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
package org.nuiton.jaxx.runtime.swing.nav.treetable;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.jdesktop.swingx.treetable.TreeTableNode;
import org.nuiton.jaxx.runtime.swing.nav.NavBridge;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.List;
/**
* Delegate model used to switch between tree model and tree table model api
*
* @author Sylvain Lletellier
* @since 2.1
*/
public class NavTreeTableBridge> implements NavBridge {
/** Logger */
static private final Logger log = LogManager.getLogger(NavTreeTableBridge.class);
/** bridge model */
protected NavTreeTableModel model;
/** bridge ui */
// protected JXTreeTable ui;
// public NavTreeTableBridge() {
// if (log.isDebugEnabled()) {
// log.debug("New " + this);
// }
// }
//--------------------------------------------------------------------------
//-- Model Queries
//--------------------------------------------------------------------------
@Override
public NavTreeTableModel getModel() {
return model;
}
@Override
@SuppressWarnings({"unchecked"})
public N getRoot() {
return (N) model.getRoot();
}
@Override
public boolean isLeaf(Object node) {
return model.isLeaf(node);
}
@Override
public int getChildCount(Object parent) {
return model.getChildCount(parent);
}
@Override
@SuppressWarnings({"unchecked"})
public N getChild(Object parent, int index) {
return (N) model.getChild(parent, index);
}
@Override
public int getIndexOfChild(Object parent, Object child) {
return model.getIndexOfChild(parent, child);
}
@Override
public TreeNode[] getPathToRoot(TreeNode aNode) {
return model.getPathToRoot((TreeTableNode) aNode);
}
//--------------------------------------------------------------------------
//-- Model modification
//--------------------------------------------------------------------------
@Override
public void setModel(NavTreeTableModel model) {
this.model = model;
}
@Override
public void setRoot(N node) {
model.setRoot(node);
}
@Override
public void insertNodeInto(N newChild, N parent, int index) {
parent.insert(newChild, index);
model.getModelSupport().fireChildAdded(getTreePath(parent), index, newChild);
}
@Override
public void removeNodeFromParent(N node) {
N parent = node.getParent();
int index = parent.getIndex(node);
if (index == -1) {
throw new IllegalArgumentException("Node " + node + " is not in tree");
}
parent.remove(node);
// It's not enougth to fire model support...
// model.getModelSupport().fireChildRemoved(path, index, node);
model.getModelSupport().fireTreeStructureChanged(getTreePath(parent));
}
@Override
public void reload(N node) {
model.getModelSupport().fireTreeStructureChanged(getTreePath(node));
}
@Override
public boolean canLoadChild(N node) {
return true;
}
//--------------------------------------------------------------------------
//-- Listeners notifications
//--------------------------------------------------------------------------
@Override
public void valueForPathChanged(TreePath path, Object newValue) {
model.valueForPathChanged(path, newValue);
}
@Override
public void nodeStructureChanged(TreeNode node) {
model.nodeStructureChanged((NavTreeTableNode>) node);
}
@Override
public void nodeChanged(TreeNode node) {
model.nodeChanged((NavTreeTableNode>) node);
}
@Override
public void nodesChanged(TreeNode node, int[] childIndices) {
// changé par le node en lui meme
NavTreeTableNode> tableNode = (NavTreeTableNode>) node;
// Extract children
Object[] children = getChildren(tableNode, childIndices);
model.getModelSupport().fireChildrenChanged(getTreePath(tableNode), childIndices, children);
}
@Override
public void nodesWereInserted(N parent, int[] indices) {
// Extract children
Object[] children = getChildren(parent, indices);
model.getModelSupport().fireChildrenAdded(getTreePath(parent), indices, children);
}
@Override
public void nodeWereInserted(N parentNode, int index, N node) {
model.getModelSupport().fireChildAdded(getTreePath(parentNode), index, node);
}
@Override
public void nodesWereRemoved(TreeNode node, int[] childIndices,
Object[] removedChildren) {
model.getModelSupport().fireChildrenRemoved(getTreePath(node),
childIndices,
removedChildren);
}
@Override
@SuppressWarnings({"unchecked"})
public void notifyChildNodesInserted(N node) {
int count = node.getChildCount();
if (count < 1) {
if (log.isDebugEnabled()) {
log.debug("Skip for leaf node : " + node);
}
return;
}
if (log.isDebugEnabled()) {
log.debug("Notify for node : " + node + ", " + count + " child(s) inserted.");
}
int[] indices = new int[count];
for (int i = 0; i < count; i++) {
indices[i] = i;
}
nodesWereInserted(node, indices);
// recurse notify on childs
for (Enumeration extends NavTreeTableNode>> childs = node.children();
childs.hasMoreElements(); ) {
N child = (N) childs.nextElement();
notifyChildNodesInserted(child);
}
}
@Override
public void notifyNodeInserted(N node) {
N parent = node.getParent();
if (parent != null) {
int index = parent.getIndex(node);
if (index == -1) {
throw new IllegalArgumentException("Node " + node + " is not in tree");
}
if (log.isDebugEnabled()) {
log.debug("Notify for node : " + node + ", for parent [" + parent + "] child " + index + " inserted.");
}
nodesWereInserted(parent, new int[]{index});
notifyChildNodesInserted(node);
}
}
//--------------------------------------------------------------------------
//-- TreeModelListener provider
//--------------------------------------------------------------------------
@Override
public void addTreeModelListener(TreeModelListener l) {
model.addTreeModelListener(l);
}
@Override
public void removeTreeModelListener(TreeModelListener l) {
model.removeTreeModelListener(l);
}
@Override
public TreeModelListener[] getTreeModelListeners() {
return model.getModelSupport().getTreeModelListeners();
}
@Override
@SuppressWarnings({"unchecked"})
public T[] getListeners(Class listenerType) {
TreeModelListener[] treeModelListeners = getTreeModelListeners();
List result = new ArrayList<>();
for (TreeModelListener listener : treeModelListeners) {
if (listener.getClass().isAssignableFrom(listenerType)) {
result.add(listener);
}
}
return (T[]) result.toArray();
}
// Extract children
protected Object[] getChildren(NavTreeTableNode> tableNode, int[] childIndices) {
int size = childIndices.length;
Object[] children = new Object[size];
for (int i = 0; i < size; i++) {
int index = childIndices[i];
NavTreeTableNode> child = tableNode.getChildAt(index);
children[i] = child;
}
return children;
}
// Create tree path for node in param
protected TreePath getTreePath(TreeNode node) {
return new TreePath(getPathToRoot(node));
}
}