Link Here
|
43 |
|
43 |
|
44 |
import java.awt.AWTEvent; |
44 |
import java.awt.AWTEvent; |
45 |
import java.awt.event.AWTEventListener; |
45 |
import java.awt.event.AWTEventListener; |
|
|
46 |
import java.awt.event.FocusEvent; |
46 |
import java.awt.event.InputEvent; |
47 |
import java.awt.event.InputEvent; |
47 |
import java.awt.event.MouseEvent; |
48 |
import java.awt.event.MouseEvent; |
|
|
49 |
import java.lang.ref.Reference; |
50 |
import java.lang.ref.WeakReference; |
48 |
import java.lang.reflect.Field; |
51 |
import java.lang.reflect.Field; |
49 |
import java.lang.reflect.Method; |
52 |
import java.lang.reflect.Method; |
|
|
53 |
import javax.swing.text.JTextComponent; |
50 |
|
54 |
|
51 |
/** |
55 |
/** |
52 |
* hack for issue #67799, on macosx with single button mouse, |
56 |
* hack for issue #67799, on macosx with single button mouse, |
53 |
* make Ctrl-Click work as right click on multiselections |
57 |
* make Ctrl-Click work as right click on multiselections |
54 |
* @author ttran |
58 |
* |
|
|
59 |
* Also handles issue #90371 - on Macintosh, JTextComponents |
60 |
* are never sent focus lost events, resulting in multiple |
61 |
* blinking caret.s |
62 |
* |
63 |
* @author ttran, tboudreau |
55 |
*/ |
64 |
*/ |
56 |
public class CtrlClickHack implements AWTEventListener { |
65 |
public class CtrlClickHack implements AWTEventListener { |
57 |
|
66 |
private Reference<JTextComponent> lastFocusedTextComponent = null; |
58 |
/** Creates a new instance of CtrlClickHack */ |
67 |
public void eventDispatched(AWTEvent e) { |
59 |
public CtrlClickHack() { |
68 |
if (!(e instanceof MouseEvent) && !(e instanceof FocusEvent)) { |
|
|
69 |
return; |
70 |
} |
71 |
if (e instanceof MouseEvent) { |
72 |
MouseEvent evt = (MouseEvent) e; |
73 |
if (evt.getModifiers() != (InputEvent.BUTTON1_MASK | InputEvent.CTRL_MASK)) { |
74 |
return; |
75 |
} |
76 |
try { |
77 |
Field f1 = InputEvent.class.getDeclaredField("modifiers"); |
78 |
Field f2 = MouseEvent.class.getDeclaredField("button"); |
79 |
Method m = MouseEvent.class.getDeclaredMethod("setNewModifiers", new Class[] {}); |
80 |
f1.setAccessible(true); |
81 |
f1.setInt(evt, InputEvent.BUTTON3_MASK); |
82 |
f2.setAccessible(true); |
83 |
f2.setInt(evt, MouseEvent.BUTTON3); |
84 |
m.setAccessible(true); |
85 |
m.invoke(evt, new Object[] {}); |
86 |
} catch (Exception ex) { |
87 |
ex.printStackTrace(); |
88 |
} |
89 |
} else { |
90 |
System.err.println("Handling focus event"); |
91 |
FocusEvent fe = (FocusEvent) e; |
92 |
if (fe.getID() == FocusEvent.FOCUS_GAINED) { |
93 |
if (fe.getOppositeComponent() instanceof JTextComponent) { |
94 |
JTextComponent jtc = (JTextComponent) fe.getOppositeComponent(); |
95 |
jtc.getCaret().setVisible(false); |
96 |
} else { |
97 |
JTextComponent jtc = lastFocusedTextComponent == null ? null : |
98 |
lastFocusedTextComponent.get(); |
99 |
if (jtc != null) { |
100 |
jtc.getCaret().setVisible(false); |
101 |
} |
102 |
} |
103 |
if (fe.getComponent() instanceof JTextComponent) { |
104 |
JTextComponent jtc = (JTextComponent) fe.getComponent(); |
105 |
lastFocusedTextComponent = new WeakReference<JTextComponent>(jtc); |
106 |
jtc.getCaret().setVisible(true); |
107 |
} |
108 |
} |
109 |
} |
60 |
} |
110 |
} |
61 |
|
111 |
|
62 |
public void eventDispatched(AWTEvent e) { |
|
|
63 |
if (! (e instanceof MouseEvent)) { |
64 |
return; |
65 |
} |
66 |
MouseEvent evt = (MouseEvent) e; |
67 |
if (evt.getModifiers() != (InputEvent.BUTTON1_MASK | InputEvent.CTRL_MASK)) { |
68 |
return; |
69 |
} |
70 |
try { |
71 |
Field f1 = InputEvent.class.getDeclaredField("modifiers"); |
72 |
Field f2 = MouseEvent.class.getDeclaredField("button"); |
73 |
Method m = MouseEvent.class.getDeclaredMethod("setNewModifiers", new Class[] {}); |
74 |
f1.setAccessible(true); |
75 |
f1.setInt(evt, InputEvent.BUTTON3_MASK); |
76 |
f2.setAccessible(true); |
77 |
f2.setInt(evt, MouseEvent.BUTTON3); |
78 |
m.setAccessible(true); |
79 |
m.invoke(evt, new Object[] {}); |
80 |
} catch (Exception ex) { |
81 |
ex.printStackTrace(); |
82 |
} |
83 |
} |
84 |
|
85 |
} |
112 |
} |