2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as published
4 * by the Free Software Foundation, either version 3 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU Lesser General Public License for more details.
12 * You should have received a copy of the GNU Lesser General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 // Can be found at: https://code.google.com/archive/p/aephyr/source/default/source
16 // package aephyr.swing;
17 package be
.nikiroo
.utils
.ui
;
20 import java
.awt
.event
.*;
23 import javax
.swing
.tree
.*;
27 public class TreeCellSpanner
extends Container
implements TreeCellRenderer
, ComponentListener
{
29 public TreeCellSpanner(JTree tree
, TreeCellRenderer renderer
) {
30 if (tree
== null || renderer
== null)
31 throw new NullPointerException();
33 this.renderer
= renderer
;
34 treeParent
= tree
.getParent();
35 if (treeParent
!= null && treeParent
instanceof JViewport
) {
36 treeParent
.addComponentListener(this);
39 tree
.addComponentListener(this);
43 protected final JTree tree
;
45 private TreeCellRenderer renderer
;
47 private Component rendererComponent
;
49 private Container treeParent
;
51 private Map
<TreePath
,Integer
> offsets
= new HashMap
<TreePath
,Integer
>();
53 private TreePath path
;
55 public TreeCellRenderer
getRenderer() {
60 public Component
getTreeCellRendererComponent(JTree tree
, Object value
,
61 boolean selected
, boolean expanded
, boolean leaf
, int row
,
63 path
= tree
.getPathForRow(row
);
64 if (path
!= null && path
.getLastPathComponent() != value
)
66 rendererComponent
= renderer
.getTreeCellRendererComponent(
67 tree
, value
, selected
, expanded
, leaf
, row
, hasFocus
);
68 if (getComponentCount() < 1 || getComponent(0) != rendererComponent
) {
70 add(rendererComponent
);
76 public void doLayout() {
81 Integer offset
= offsets
.get(path
);
82 if (offset
== null || offset
.intValue() != x
) {
84 fireTreePathChanged(path
);
87 rendererComponent
.setBounds(getX(), getY(), getWidth(), getHeight());
91 public void paint(Graphics g
) {
92 if (rendererComponent
!= null)
93 rendererComponent
.paint(g
);
97 public Dimension
getPreferredSize() {
98 Dimension s
= rendererComponent
.getPreferredSize();
99 // check if path count is greater than 1 to exclude the root
100 if (path
!= null && path
.getPathCount() > 1) {
101 Integer offset
= offsets
.get(path
);
102 if (offset
!= null) {
104 if (tree
.getParent() == treeParent
) {
105 width
= treeParent
.getWidth();
107 if (treeParent
!= null) {
108 treeParent
.removeComponentListener(this);
109 tree
.addComponentListener(this);
112 if (tree
.getParent() instanceof JViewport
) {
113 treeParent
= tree
.getParent();
114 tree
.removeComponentListener(this);
115 treeParent
.addComponentListener(this);
116 width
= treeParent
.getWidth();
118 width
= tree
.getWidth();
121 s
.width
= width
- offset
;
128 protected void fireTreePathChanged(TreePath path
) {
129 if (path
.getPathCount() > 1) {
130 // this cannot be used for the root node or else
131 // the entire tree will keep being revalidated ad infinitum
132 TreeModel model
= tree
.getModel();
133 Object node
= path
.getLastPathComponent();
134 if (node
instanceof TreeNode
&& (model
instanceof DefaultTreeModel
135 || (model
instanceof TreeModelTransformer
<?
> &&
136 (model
=((TreeModelTransformer
<?
>)model
).getModel()) instanceof DefaultTreeModel
))) {
137 ((DefaultTreeModel
)model
).nodeChanged((TreeNode
)node
);
139 model
.valueForPathChanged(path
, node
.toString());
148 private int lastWidth
;
151 public void componentHidden(ComponentEvent e
) {}
154 public void componentMoved(ComponentEvent e
) {}
157 public void componentResized(ComponentEvent e
) {
158 if (e
.getComponent().getWidth() != lastWidth
) {
159 lastWidth
= e
.getComponent().getWidth();
160 for (int row
=tree
.getRowCount(); --row
>=0;) {
161 fireTreePathChanged(tree
.getPathForRow(row
));
167 public void componentShown(ComponentEvent e
) {}