Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/classes/com/apple/laf/AquaCaret.java
38831 views
1
/*
2
* Copyright (c) 2011, 2012, 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
26
package com.apple.laf;
27
28
import java.awt.*;
29
import java.awt.event.*;
30
import java.awt.geom.Rectangle2D;
31
import java.beans.*;
32
33
import javax.swing.*;
34
import javax.swing.border.Border;
35
import javax.swing.plaf.UIResource;
36
import javax.swing.text.*;
37
38
public class AquaCaret extends DefaultCaret implements UIResource, PropertyChangeListener {
39
final boolean isMultiLineEditor;
40
final JTextComponent c;
41
42
boolean mFocused = false;
43
44
public AquaCaret(final Window inParentWindow, final JTextComponent inComponent) {
45
super();
46
c = inComponent;
47
isMultiLineEditor = (c instanceof JTextArea || c instanceof JEditorPane);
48
inComponent.addPropertyChangeListener(this);
49
}
50
51
protected Highlighter.HighlightPainter getSelectionPainter() {
52
return AquaHighlighter.getInstance();
53
}
54
55
/**
56
* Only show the flashing caret if the selection range is zero
57
*/
58
public void setVisible(boolean e) {
59
if (e) e = getDot() == getMark();
60
super.setVisible(e);
61
}
62
63
protected void fireStateChanged() {
64
// If we have focus the caret should only flash if the range length is zero
65
if (mFocused) setVisible(getComponent().isEditable());
66
67
super.fireStateChanged();
68
}
69
70
public void propertyChange(final PropertyChangeEvent evt) {
71
final String propertyName = evt.getPropertyName();
72
73
if (AquaFocusHandler.FRAME_ACTIVE_PROPERTY.equals(propertyName)) {
74
final JTextComponent comp = ((JTextComponent)evt.getSource());
75
76
if (evt.getNewValue() == Boolean.TRUE) {
77
setVisible(comp.hasFocus());
78
} else {
79
setVisible(false);
80
}
81
82
if (getDot() != getMark()) comp.getUI().damageRange(comp, getDot(), getMark());
83
}
84
}
85
86
// --- FocusListener methods --------------------------
87
88
private boolean shouldSelectAllOnFocus = true;
89
public void focusGained(final FocusEvent e) {
90
final JTextComponent component = getComponent();
91
if (!component.isEnabled() || !component.isEditable()) {
92
super.focusGained(e);
93
return;
94
}
95
96
mFocused = true;
97
if (!shouldSelectAllOnFocus) {
98
shouldSelectAllOnFocus = true;
99
super.focusGained(e);
100
return;
101
}
102
103
if (isMultiLineEditor) {
104
super.focusGained(e);
105
return;
106
}
107
108
final int end = component.getDocument().getLength();
109
final int dot = getDot();
110
final int mark = getMark();
111
if (dot == mark) {
112
if (dot == 0) {
113
component.setCaretPosition(end);
114
component.moveCaretPosition(0);
115
} else if (dot == end) {
116
component.setCaretPosition(0);
117
component.moveCaretPosition(end);
118
}
119
}
120
121
super.focusGained(e);
122
}
123
124
public void focusLost(final FocusEvent e) {
125
mFocused = false;
126
shouldSelectAllOnFocus = true;
127
if (isMultiLineEditor) {
128
setVisible(false);
129
c.repaint();
130
} else {
131
super.focusLost(e);
132
}
133
}
134
135
// This fixes the problem where when on the mac you have to ctrl left click to
136
// get popup triggers the caret has code that only looks at button number.
137
// see radar # 3125390
138
public void mousePressed(final MouseEvent e) {
139
if (!e.isPopupTrigger()) {
140
super.mousePressed(e);
141
shouldSelectAllOnFocus = false;
142
}
143
}
144
145
/**
146
* Damages the area surrounding the caret to cause
147
* it to be repainted in a new location. If paint()
148
* is reimplemented, this method should also be
149
* reimplemented. This method should update the
150
* caret bounds (x, y, width, and height).
151
*
152
* @param r the current location of the caret
153
* @see #paint
154
*/
155
protected synchronized void damage(final Rectangle r) {
156
if (r == null || fPainting) return;
157
158
x = r.x - 4;
159
y = r.y;
160
width = 10;
161
height = r.height;
162
163
// Don't damage the border area. We can't paint a partial border, so get the
164
// intersection of the caret rectangle and the component less the border, if any.
165
final Rectangle caretRect = new Rectangle(x, y, width, height);
166
final Border border = getComponent().getBorder();
167
if (border != null) {
168
final Rectangle alloc = getComponent().getBounds();
169
alloc.x = alloc.y = 0;
170
final Insets borderInsets = border.getBorderInsets(getComponent());
171
alloc.x += borderInsets.left;
172
alloc.y += borderInsets.top;
173
alloc.width -= borderInsets.left + borderInsets.right;
174
alloc.height -= borderInsets.top + borderInsets.bottom;
175
Rectangle2D.intersect(caretRect, alloc, caretRect);
176
}
177
x = caretRect.x;
178
y = caretRect.y;
179
width = Math.max(caretRect.width, 1);
180
height = Math.max(caretRect.height, 1);
181
repaint();
182
}
183
184
boolean fPainting = false;
185
186
// See <rdar://problem/3833837> 1.4.2_05-141.3: JTextField performance with Aqua L&F
187
// We are getting into a circular condition with the BasicCaret paint code since it doesn't know about the fact that our
188
// damage routine above elminates the border. Sadly we can't easily change either one, so we will
189
// add a painting flag and not damage during a repaint.
190
public void paint(final Graphics g) {
191
if (isVisible()) {
192
fPainting = true;
193
super.paint(g);
194
fPainting = false;
195
}
196
}
197
}
198
199