Path: blob/master/src/java.desktop/macosx/classes/sun/lwawt/LWTextAreaPeer.java
41153 views
/*1* Copyright (c) 2011, 2019, 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 sun.lwawt;2627import java.awt.Component;28import java.awt.Cursor;29import java.awt.Dimension;30import java.awt.Insets;31import java.awt.Point;32import java.awt.TextArea;33import java.awt.event.TextEvent;34import java.awt.peer.TextAreaPeer;3536import javax.swing.JScrollBar;37import javax.swing.JScrollPane;38import javax.swing.JTextArea;39import javax.swing.ScrollPaneConstants;40import javax.swing.TransferHandler;41import javax.swing.text.Document;4243import sun.awt.AWTAccessor;4445/**46* Lightweight implementation of {@link TextAreaPeer}. Delegates most of the47* work to the {@link JTextArea} inside {@link JScrollPane}.48*/49final class LWTextAreaPeer50extends LWTextComponentPeer<TextArea, LWTextAreaPeer.ScrollableJTextArea>51implements TextAreaPeer {5253/**54* The default number of visible columns.55*/56private static final int DEFAULT_COLUMNS = 60;5758/**59* The default number of visible rows.60*/61private static final int DEFAULT_ROWS = 10;6263LWTextAreaPeer(final TextArea target,64final PlatformComponent platformComponent) {65super(target, platformComponent);66}6768@Override69ScrollableJTextArea createDelegate() {70return new ScrollableJTextArea();71}7273@Override74void initializeImpl() {75super.initializeImpl();76final int visibility = getTarget().getScrollbarVisibility();77synchronized (getDelegateLock()) {78getTextComponent().setWrapStyleWord(true);79setScrollBarVisibility(visibility);80}81}8283@Override84JTextArea getTextComponent() {85return getDelegate().getView();86}8788@Override89Cursor getCursor(final Point p) {90final boolean isContains;91synchronized (getDelegateLock()) {92isContains = getDelegate().getViewport().getBounds().contains(p);93}94return isContains ? super.getCursor(p) : null;95}9697@Override98Component getDelegateFocusOwner() {99return getTextComponent();100}101102@Override103public Dimension getPreferredSize() {104return getMinimumSize();105}106107@Override108public Dimension getMinimumSize() {109return getMinimumSize(DEFAULT_ROWS, DEFAULT_COLUMNS);110}111112@Override113public Dimension getPreferredSize(final int rows, final int columns) {114return getMinimumSize(rows, columns);115}116117@Override118public Dimension getMinimumSize(final int rows, final int columns) {119final Dimension size = super.getMinimumSize(rows, columns);120synchronized (getDelegateLock()) {121// JScrollPane insets122final Insets pi = getDelegate().getInsets();123size.width += pi.left + pi.right;124size.height += pi.top + pi.bottom;125// Take scrollbars into account.126final int vsbPolicy = getDelegate().getVerticalScrollBarPolicy();127if (vsbPolicy == ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS) {128final JScrollBar vbar = getDelegate().getVerticalScrollBar();129size.width += vbar != null ? vbar.getMinimumSize().width : 0;130}131final int hsbPolicy = getDelegate().getHorizontalScrollBarPolicy();132if (hsbPolicy == ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS) {133final JScrollBar hbar = getDelegate().getHorizontalScrollBar();134size.height += hbar != null ? hbar.getMinimumSize().height : 0;135}136}137return size;138}139140@Override141public void insert(final String text, final int pos) {142final ScrollableJTextArea pane = getDelegate();143synchronized (getDelegateLock()) {144final JTextArea area = pane.getView();145final boolean doScroll = pos >= area.getDocument().getLength()146&& area.getDocument().getLength() != 0;147area.insert(text, pos);148revalidate();149if (doScroll) {150final JScrollBar vbar = pane.getVerticalScrollBar();151if (vbar != null) {152vbar.setValue(vbar.getMaximum() - vbar.getVisibleAmount());153}154}155}156repaintPeer();157}158159@Override160public void replaceRange(final String text, final int start,161final int end) {162synchronized (getDelegateLock()) {163// JTextArea.replaceRange() posts two different events.164// Since we make no differences between text events,165// the document listener has to be disabled while166// JTextArea.replaceRange() is called.167final Document document = getTextComponent().getDocument();168document.removeDocumentListener(this);169getTextComponent().replaceRange(text, start, end);170revalidate();171postEvent(new TextEvent(getTarget(), TextEvent.TEXT_VALUE_CHANGED));172document.addDocumentListener(this);173}174repaintPeer();175}176177private void setScrollBarVisibility(final int visibility) {178final ScrollableJTextArea pane = getDelegate();179final JTextArea view = pane.getView();180view.setLineWrap(false);181182switch (visibility) {183case TextArea.SCROLLBARS_NONE:184pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);185pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);186view.setLineWrap(true);187break;188case TextArea.SCROLLBARS_VERTICAL_ONLY:189pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);190pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);191view.setLineWrap(true);192break;193case TextArea.SCROLLBARS_HORIZONTAL_ONLY:194pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);195pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);196break;197default:198pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);199pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);200break;201}202}203204@SuppressWarnings("serial")// Safe: outer class is non-serializable.205final class ScrollableJTextArea extends JScrollPane {206207ScrollableJTextArea() {208super();209getViewport().setView(new JTextAreaDelegate());210}211212public JTextArea getView() {213return (JTextArea) getViewport().getView();214}215216@Override217public void setEnabled(final boolean enabled) {218getViewport().getView().setEnabled(enabled);219super.setEnabled(enabled);220}221222private final class JTextAreaDelegate extends JTextArea {223224@Override225public void replaceSelection(String content) {226getDocument().removeDocumentListener(LWTextAreaPeer.this);227super.replaceSelection(content);228// post only one text event in this case229postTextEvent();230getDocument().addDocumentListener(LWTextAreaPeer.this);231}232233@Override234public boolean hasFocus() {235return getTarget().hasFocus();236}237238@Override239public Point getLocationOnScreen() {240return LWTextAreaPeer.this.getLocationOnScreen();241}242243@Override244public void setTransferHandler(final TransferHandler newHandler) {245// override the default implementation to avoid loading246// SystemFlavorMap and associated classes247Object key = AWTAccessor.getClientPropertyKeyAccessor()248.getJComponent_TRANSFER_HANDLER();249Object oldHandler = getClientProperty(key);250putClientProperty(key, newHandler);251firePropertyChange("transferHandler", oldHandler, newHandler);252}253}254}255}256257258