Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/classes/com/apple/laf/AquaCaret.java
38831 views
/*1* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.apple.laf;2627import java.awt.*;28import java.awt.event.*;29import java.awt.geom.Rectangle2D;30import java.beans.*;3132import javax.swing.*;33import javax.swing.border.Border;34import javax.swing.plaf.UIResource;35import javax.swing.text.*;3637public class AquaCaret extends DefaultCaret implements UIResource, PropertyChangeListener {38final boolean isMultiLineEditor;39final JTextComponent c;4041boolean mFocused = false;4243public AquaCaret(final Window inParentWindow, final JTextComponent inComponent) {44super();45c = inComponent;46isMultiLineEditor = (c instanceof JTextArea || c instanceof JEditorPane);47inComponent.addPropertyChangeListener(this);48}4950protected Highlighter.HighlightPainter getSelectionPainter() {51return AquaHighlighter.getInstance();52}5354/**55* Only show the flashing caret if the selection range is zero56*/57public void setVisible(boolean e) {58if (e) e = getDot() == getMark();59super.setVisible(e);60}6162protected void fireStateChanged() {63// If we have focus the caret should only flash if the range length is zero64if (mFocused) setVisible(getComponent().isEditable());6566super.fireStateChanged();67}6869public void propertyChange(final PropertyChangeEvent evt) {70final String propertyName = evt.getPropertyName();7172if (AquaFocusHandler.FRAME_ACTIVE_PROPERTY.equals(propertyName)) {73final JTextComponent comp = ((JTextComponent)evt.getSource());7475if (evt.getNewValue() == Boolean.TRUE) {76setVisible(comp.hasFocus());77} else {78setVisible(false);79}8081if (getDot() != getMark()) comp.getUI().damageRange(comp, getDot(), getMark());82}83}8485// --- FocusListener methods --------------------------8687private boolean shouldSelectAllOnFocus = true;88public void focusGained(final FocusEvent e) {89final JTextComponent component = getComponent();90if (!component.isEnabled() || !component.isEditable()) {91super.focusGained(e);92return;93}9495mFocused = true;96if (!shouldSelectAllOnFocus) {97shouldSelectAllOnFocus = true;98super.focusGained(e);99return;100}101102if (isMultiLineEditor) {103super.focusGained(e);104return;105}106107final int end = component.getDocument().getLength();108final int dot = getDot();109final int mark = getMark();110if (dot == mark) {111if (dot == 0) {112component.setCaretPosition(end);113component.moveCaretPosition(0);114} else if (dot == end) {115component.setCaretPosition(0);116component.moveCaretPosition(end);117}118}119120super.focusGained(e);121}122123public void focusLost(final FocusEvent e) {124mFocused = false;125shouldSelectAllOnFocus = true;126if (isMultiLineEditor) {127setVisible(false);128c.repaint();129} else {130super.focusLost(e);131}132}133134// This fixes the problem where when on the mac you have to ctrl left click to135// get popup triggers the caret has code that only looks at button number.136// see radar # 3125390137public void mousePressed(final MouseEvent e) {138if (!e.isPopupTrigger()) {139super.mousePressed(e);140shouldSelectAllOnFocus = false;141}142}143144/**145* Damages the area surrounding the caret to cause146* it to be repainted in a new location. If paint()147* is reimplemented, this method should also be148* reimplemented. This method should update the149* caret bounds (x, y, width, and height).150*151* @param r the current location of the caret152* @see #paint153*/154protected synchronized void damage(final Rectangle r) {155if (r == null || fPainting) return;156157x = r.x - 4;158y = r.y;159width = 10;160height = r.height;161162// Don't damage the border area. We can't paint a partial border, so get the163// intersection of the caret rectangle and the component less the border, if any.164final Rectangle caretRect = new Rectangle(x, y, width, height);165final Border border = getComponent().getBorder();166if (border != null) {167final Rectangle alloc = getComponent().getBounds();168alloc.x = alloc.y = 0;169final Insets borderInsets = border.getBorderInsets(getComponent());170alloc.x += borderInsets.left;171alloc.y += borderInsets.top;172alloc.width -= borderInsets.left + borderInsets.right;173alloc.height -= borderInsets.top + borderInsets.bottom;174Rectangle2D.intersect(caretRect, alloc, caretRect);175}176x = caretRect.x;177y = caretRect.y;178width = Math.max(caretRect.width, 1);179height = Math.max(caretRect.height, 1);180repaint();181}182183boolean fPainting = false;184185// See <rdar://problem/3833837> 1.4.2_05-141.3: JTextField performance with Aqua L&F186// We are getting into a circular condition with the BasicCaret paint code since it doesn't know about the fact that our187// damage routine above elminates the border. Sadly we can't easily change either one, so we will188// add a painting flag and not damage during a repaint.189public void paint(final Graphics g) {190if (isVisible()) {191fPainting = true;192super.paint(g);193fPainting = false;194}195}196}197198199