Skip to content

Commit a7e77b5

Browse files
committed
preliminary -- not implemented -- JSTreeUI
1 parent 4f633c2 commit a7e77b5

File tree

2 files changed

+258
-54
lines changed

2 files changed

+258
-54
lines changed
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/*
2+
* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package javax.swing.plaf.basic;
26+
27+
import java.awt.dnd.DragSource;
28+
import java.awt.event.MouseEvent;
29+
30+
import javax.swing.JComponent;
31+
import javax.swing.SwingUtilities;
32+
import javax.swing.TransferHandler;
33+
34+
import sun.awt.AppContext;
35+
import sun.awt.dnd.SunDragSourceContextPeer;
36+
37+
/**
38+
* Drag gesture recognition support for classes that have a
39+
* <code>TransferHandler</code>. The gesture for a drag in this class is a mouse
40+
* press followed by movement by <code>DragSource.getDragThreshold()</code>
41+
* pixels. An instance of this class is maintained per AppContext, and the
42+
* public static methods call into the appropriate instance.
43+
*
44+
* @author Shannon Hickey
45+
*/
46+
class DragRecognitionSupport {
47+
private int motionThreshold;
48+
private MouseEvent dndArmedEvent;
49+
private JComponent component;
50+
51+
/**
52+
* This interface allows us to pass in a handler to mouseDragged,
53+
* so that we can be notified immediately before a drag begins.
54+
*/
55+
public static interface BeforeDrag {
56+
public void dragStarting(MouseEvent me);
57+
}
58+
59+
/**
60+
* Returns the DragRecognitionSupport for the caller's AppContext.
61+
*/
62+
private static DragRecognitionSupport getDragRecognitionSupport() {
63+
DragRecognitionSupport support =
64+
(DragRecognitionSupport)AppContext.getAppContext().
65+
get(DragRecognitionSupport.class);
66+
67+
if (support == null) {
68+
support = new DragRecognitionSupport();
69+
AppContext.getAppContext().put(DragRecognitionSupport.class, support);
70+
}
71+
72+
return support;
73+
}
74+
75+
/**
76+
* Returns whether or not the event is potentially part of a drag sequence.
77+
*/
78+
public static boolean mousePressed(MouseEvent me) {
79+
return getDragRecognitionSupport().mousePressedImpl(me);
80+
}
81+
82+
/**
83+
* If a dnd recognition has been going on, return the MouseEvent
84+
* that started the recognition. Otherwise, return null.
85+
*/
86+
public static MouseEvent mouseReleased(MouseEvent me) {
87+
return getDragRecognitionSupport().mouseReleasedImpl(me);
88+
}
89+
90+
/**
91+
* Returns whether or not a drag gesture recognition is ongoing.
92+
*/
93+
public static boolean mouseDragged(MouseEvent me, BeforeDrag bd) {
94+
return getDragRecognitionSupport().mouseDraggedImpl(me, bd);
95+
}
96+
97+
private void clearState() {
98+
dndArmedEvent = null;
99+
component = null;
100+
}
101+
102+
private int mapDragOperationFromModifiers(MouseEvent me,
103+
TransferHandler th) {
104+
105+
if (th == null || !SwingUtilities.isLeftMouseButton(me)) {
106+
return TransferHandler.NONE;
107+
}
108+
109+
return SunDragSourceContextPeer.
110+
convertModifiersToDropAction(me.getModifiersEx(),
111+
th.getSourceActions(component));
112+
}
113+
114+
/**
115+
* Returns whether or not the event is potentially part of a drag sequence.
116+
*/
117+
private boolean mousePressedImpl(MouseEvent me) {
118+
component = (JComponent)me.getSource();
119+
120+
if (mapDragOperationFromModifiers(me, component.getTransferHandler())
121+
!= TransferHandler.NONE) {
122+
123+
motionThreshold = DragSource.getDragThreshold();
124+
dndArmedEvent = me;
125+
return true;
126+
}
127+
128+
clearState();
129+
return false;
130+
}
131+
132+
/**
133+
* If a dnd recognition has been going on, return the MouseEvent
134+
* that started the recognition. Otherwise, return null.
135+
*/
136+
private MouseEvent mouseReleasedImpl(MouseEvent me) {
137+
/* no recognition has been going on */
138+
if (dndArmedEvent == null) {
139+
return null;
140+
}
141+
142+
MouseEvent retEvent = null;
143+
144+
if (me.getSource() == component) {
145+
retEvent = dndArmedEvent;
146+
} // else component has changed unexpectedly, so return null
147+
148+
clearState();
149+
return retEvent;
150+
}
151+
152+
/**
153+
* Returns whether or not a drag gesture recognition is ongoing.
154+
*/
155+
private boolean mouseDraggedImpl(MouseEvent me, BeforeDrag bd) {
156+
/* no recognition is in progress */
157+
if (dndArmedEvent == null) {
158+
return false;
159+
}
160+
161+
/* component has changed unexpectedly, so bail */
162+
if (me.getSource() != component) {
163+
clearState();
164+
return false;
165+
}
166+
167+
int dx = Math.abs(me.getX() - dndArmedEvent.getX());
168+
int dy = Math.abs(me.getY() - dndArmedEvent.getY());
169+
if ((dx > motionThreshold) || (dy > motionThreshold)) {
170+
TransferHandler th = component.getTransferHandler();
171+
int action = mapDragOperationFromModifiers(me, th);
172+
if (action != TransferHandler.NONE) {
173+
/* notify the BeforeDrag instance */
174+
if (bd != null) {
175+
bd.dragStarting(dndArmedEvent);
176+
}
177+
th.exportAsDrag(component, dndArmedEvent, action);
178+
clearState();
179+
}
180+
}
181+
182+
return true;
183+
}
184+
}

sources/net.sf.j2s.java.core/src/sun/swing/SwingUtilities2.java

Lines changed: 74 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
import static java.awt.RenderingHints.KEY_TEXT_ANTIALIASING;
3232
import java.awt.Color;
3333
import java.awt.Component;
34+
import java.awt.Container;
3435
import java.awt.Dimension;
36+
import java.awt.FocusTraversalPolicy;
3537
import java.awt.Font;
3638
import java.awt.FontMetrics;
3739
import java.awt.Graphics;
@@ -62,7 +64,9 @@
6264
import javax.swing.ListSelectionModel;
6365
import javax.swing.SwingUtilities;
6466
import javax.swing.UIManager;
67+
import javax.swing.event.TreeModelEvent;
6568
import javax.swing.table.TableCellRenderer;
69+
import javax.swing.text.DefaultCaret;
6670
import javax.swing.text.DefaultHighlighter;
6771
import javax.swing.text.Highlighter;
6872
import javax.swing.text.JTextComponent;
@@ -83,6 +87,8 @@
8387
//import java.awt.event.KeyEvent;
8488
//import javax.swing.UIDefaults;
8589
//import javax.swing.text.DefaultCaret;
90+
import javax.swing.tree.TreeModel;
91+
import javax.swing.tree.TreePath;
8692

8793
/**
8894
* A collection of utility methods for Swing.
@@ -122,11 +128,11 @@ public class SwingUtilities2 {
122128
*/
123129
public static final Object AA_TEXT_PROPERTY_KEY = new Object(); // AATextInfoPropertyKey
124130

125-
// /**
126-
// * Used to tell a text component, being used as an editor for table
127-
// * or tree, how many clicks it took to start editing.
128-
// */
129-
// private static final Object SKIP_CLICK_COUNT = new Object(); // skipClickCount
131+
/**
132+
* Used to tell a text component, being used as an editor for table
133+
* or tree, how many clicks it took to start editing.
134+
*/
135+
private static final Object SKIP_CLICK_COUNT = new Object(); // skipClickCount
130136

131137
/* Presently this class assumes default fractional metrics.
132138
* This may need to change to emulate future platform L&Fs.
@@ -1611,37 +1617,37 @@ public static int getUIDefaultsInt(Object key, Locale l, int defaultValue) {
16111617
}
16121618

16131619
// SwingJS X: Key Focus
1614-
// // At this point we need this method here. But we assume that there
1615-
// // will be a common method for this purpose in the future releases.
1616-
// public static Component compositeRequestFocus(Component component) {
1617-
// if (component instanceof Container) {
1618-
// Container container = (Container)component;
1619-
// if (container.isFocusCycleRoot()) {
1620-
// FocusTraversalPolicy policy = container.getFocusTraversalPolicy();
1621-
// Component comp = policy.getDefaultComponent(container);
1622-
// if (comp!=null) {
1623-
// comp.requestFocus();
1624-
// return comp;
1625-
// }
1626-
// }
1627-
// Container rootAncestor = container.getFocusCycleRootAncestor();
1628-
// if (rootAncestor!=null) {
1629-
// FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy();
1630-
// Component comp = policy.getComponentAfter(rootAncestor, container);
1631-
//
1632-
// if (comp!=null && SwingUtilities.isDescendingFrom(comp, container)) {
1633-
// comp.requestFocus();
1634-
// return comp;
1635-
// }
1636-
// }
1637-
// }
1638-
// if (component.isFocusable()) {
1639-
// component.requestFocus();
1640-
// return component;
1641-
// }
1642-
// return null;
1643-
// }
1644-
//
1620+
// At this point we need this method here. But we assume that there
1621+
// will be a common method for this purpose in the future releases.
1622+
public static Component compositeRequestFocus(Component component) {
1623+
if (component instanceof Container) {
1624+
Container container = (Container)component;
1625+
if (container.isFocusCycleRoot()) {
1626+
FocusTraversalPolicy policy = container.getFocusTraversalPolicy();
1627+
Component comp = policy.getDefaultComponent(container);
1628+
if (comp!=null) {
1629+
comp.requestFocus();
1630+
return comp;
1631+
}
1632+
}
1633+
Container rootAncestor = container.getFocusCycleRootAncestor();
1634+
if (rootAncestor!=null) {
1635+
FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy();
1636+
Component comp = policy.getComponentAfter(rootAncestor, container);
1637+
1638+
if (comp!=null && SwingUtilities.isDescendingFrom(comp, container)) {
1639+
comp.requestFocus();
1640+
return comp;
1641+
}
1642+
}
1643+
}
1644+
if (component.isFocusable()) {
1645+
component.requestFocus();
1646+
return component;
1647+
}
1648+
return null;
1649+
}
1650+
16451651
/**
16461652
* Change focus to the visible component in {@code JTabbedPane}.
16471653
* This is not a general-purpose method and is here only to permit
@@ -1705,20 +1711,20 @@ public static boolean tabbedPaneChangeFocusTo(Component comp) {
17051711
// private static void execute(Runnable command) {
17061712
// SwingUtilities.invokeLater(command);
17071713
// }
1708-
// /**
1709-
// * Sets the {@code SKIP_CLICK_COUNT} client property on the component
1710-
// * if it is an instance of {@code JTextComponent} with a
1711-
// * {@code DefaultCaret}. This property, used for text components acting
1712-
// * as editors in a table or tree, tells {@code DefaultCaret} how many
1713-
// * clicks to skip before starting selection.
1714-
// */
1715-
// public static void setSkipClickCount(Component comp, int count) {
1716-
// if (comp instanceof JTextComponent
1717-
// && ((JTextComponent) comp).getCaret() instanceof DefaultCaret) {
1718-
//
1719-
// ((JTextComponent) comp).putClientProperty(SKIP_CLICK_COUNT, count);
1720-
// }
1721-
// }
1714+
/**
1715+
* Sets the {@code SKIP_CLICK_COUNT} client property on the component
1716+
* if it is an instance of {@code JTextComponent} with a
1717+
* {@code DefaultCaret}. This property, used for text components acting
1718+
* as editors in a table or tree, tells {@code DefaultCaret} how many
1719+
* clicks to skip before starting selection.
1720+
*/
1721+
public static void setSkipClickCount(Component comp, int count) {
1722+
if (comp instanceof JTextComponent
1723+
&& ((JTextComponent) comp).getCaret() instanceof DefaultCaret) {
1724+
1725+
((JTextComponent) comp).putClientProperty(SKIP_CLICK_COUNT, count);
1726+
}
1727+
}
17221728

17231729
// /**
17241730
// * Return the MouseEvent's click count, possibly reduced by the value of
@@ -1896,8 +1902,22 @@ public static Section liesInVertical(Rectangle rect, Point p,
18961902
return liesIn(rect, p, false, false, three);
18971903
}
18981904

1899-
public static void compositeRequestFocus(Component editorComponent) {
1900-
// TODO Auto-generated method stub
1901-
1902-
}
1905+
/**
1906+
* Returns the {@link TreePath} that identifies the changed nodes.
1907+
*
1908+
* @param event changes in a tree model
1909+
* @param model corresponing tree model
1910+
* @return the path to the changed nodes
1911+
*/
1912+
public static TreePath getTreePath(TreeModelEvent event, TreeModel model) {
1913+
TreePath path = event.getTreePath();
1914+
if ((path == null) && (model != null)) {
1915+
Object root = model.getRoot();
1916+
if (root != null) {
1917+
path = new TreePath(root);
1918+
}
1919+
}
1920+
return path;
1921+
}
1922+
19031923
}

0 commit comments

Comments
 (0)