0N/A/*
3909N/A * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.awt.X11;
0N/A
0N/Aimport java.awt.*;
0N/Aimport java.awt.peer.ComponentPeer;
0N/Aimport java.awt.peer.TextAreaPeer;
0N/Aimport java.awt.event.*;
0N/Aimport javax.swing.event.DocumentListener;
0N/Aimport javax.swing.event.DocumentEvent;
0N/Aimport javax.swing.JTextArea;
0N/Aimport javax.swing.JComponent;
0N/Aimport javax.swing.JScrollPane;
0N/Aimport javax.swing.JScrollBar;
0N/Aimport javax.swing.plaf.ComponentUI;
0N/Aimport com.sun.java.swing.plaf.motif.MotifTextAreaUI;
0N/Aimport javax.swing.plaf.UIResource;
0N/Aimport javax.swing.UIDefaults;
0N/Aimport javax.swing.border.Border;
0N/Aimport javax.swing.border.EmptyBorder;
0N/Aimport javax.swing.border.CompoundBorder;
0N/Aimport javax.swing.border.AbstractBorder;
0N/Aimport javax.swing.JButton;
0N/Aimport javax.swing.JViewport;
0N/Aimport javax.swing.InputMap;
0N/Aimport javax.swing.SwingUtilities;
0N/Aimport javax.swing.TransferHandler;
0N/Aimport javax.swing.plaf.basic.BasicArrowButton;
0N/Aimport javax.swing.plaf.basic.BasicScrollBarUI;
0N/Aimport javax.swing.plaf.basic.BasicScrollPaneUI;
0N/Aimport java.beans.PropertyChangeEvent;
0N/Aimport java.beans.PropertyChangeListener;
0N/Aimport javax.swing.text.Caret;
0N/Aimport javax.swing.text.DefaultCaret;
0N/Aimport javax.swing.text.JTextComponent;
0N/A
0N/Aimport javax.swing.plaf.BorderUIResource;
0N/Aimport java.awt.im.InputMethodRequests;
0N/Aimport sun.awt.CausedFocusEvent;
1976N/Aimport sun.awt.AWTAccessor;
2860N/Aimport sun.awt.SunToolkit;
0N/A
0N/A
0N/Aclass XTextAreaPeer extends XComponentPeer implements TextAreaPeer {
0N/A boolean editable;
0N/A
0N/A AWTTextPane textPane;
0N/A AWTTextArea jtext;
0N/A
0N/A boolean firstChangeSkipped;
0N/A
0N/A private final JavaMouseEventHandler javaMouseEventHandler
0N/A = new JavaMouseEventHandler( this );
0N/A
0N/A /* FIXME */
0N/A
0N/A public long filterEvents(long mask) {
0N/A Thread.dumpStack();
0N/A return 0;
0N/A }
0N/A
0N/A /* FIXME */
0N/A public Rectangle getCharacterBounds(int i) {
0N/A Thread.dumpStack();
0N/A return null;
0N/A }
0N/A
0N/A public int getIndexAtPoint(int x, int y) {
0N/A Thread.dumpStack();
0N/A return 0;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Create a Text area.
0N/A */
0N/A XTextAreaPeer(TextArea target) {
0N/A super( target );
0N/A
0N/A // some initializations require that target be set even
0N/A // though init(target) has not been called
0N/A this.target = target;
0N/A
0N/A //ComponentAccessor.enableEvents(target,AWTEvent.MOUSE_WHEEL_EVENT_MASK);
0N/A
0N/A firstChangeSkipped = false;
0N/A String text = ((TextArea)target).getText();
0N/A jtext = new AWTTextArea(text, this);
0N/A jtext.setWrapStyleWord(true);
0N/A jtext.getDocument().addDocumentListener(jtext);
0N/A XToolkit.specialPeerMap.put(jtext,this);
0N/A textPane = new AWTTextPane(jtext,this, target.getParent());
0N/A
0N/A setBounds(x, y, width, height, SET_BOUNDS);
0N/A textPane.setVisible(true);
0N/A textPane.validate();
0N/A
1976N/A AWTAccessor.ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor();
1976N/A foreground = compAccessor.getForeground(target);
0N/A if (foreground == null) {
0N/A foreground = SystemColor.textText;
0N/A }
0N/A setForeground(foreground);
0N/A
1976N/A background = compAccessor.getBackground(target);
0N/A if (background == null) {
0N/A if (target.isEditable()) background = SystemColor.text;
0N/A else background = SystemColor.control;
0N/A }
0N/A setBackground(background);
0N/A
0N/A if (!target.isBackgroundSet()) {
0N/A // This is a way to set the background color of the TextArea
1976N/A // without calling setBackground - go through accessor
1976N/A compAccessor.setBackground(target, background);
0N/A }
0N/A if (!target.isForegroundSet()) {
0N/A target.setForeground(SystemColor.textText);
0N/A }
0N/A
0N/A setFont(font);
0N/A
0N/A int start = target.getSelectionStart();
0N/A int end = target.getSelectionEnd();
0N/A
0N/A if (end > start) {
0N/A select(start, end);
0N/A }
0N/A // Fix for 5100200
0N/A // Restoring Motif behaviour
0N/A // Since the end position of the selected text can be greater then the length of the text,
0N/A // so we should set caret to max position of the text
0N/A int caretPosition = Math.min(end, text.length());
0N/A setCaretPosition(caretPosition);
0N/A
0N/A setEditable(target.isEditable());
0N/A
0N/A setScrollBarVisibility();
0N/A // set the text of this object to the text of its target
0N/A setTextImpl(target.getText()); //?? should this be setText
0N/A
0N/A // After this line we should not change the component's text
0N/A firstChangeSkipped = true;
0N/A }
0N/A
0N/A public void dispose() {
0N/A XToolkit.specialPeerMap.remove(jtext);
5346N/A // visible caret has a timer thread which must be stopped
5346N/A jtext.getCaret().setVisible(false);
0N/A jtext.removeNotify();
0N/A textPane.removeNotify();
0N/A super.dispose();
0N/A }
0N/A
3446N/A
3446N/A /*
3446N/A * The method overrides one from XComponentPeer
3446N/A * If ignoreSubComponents=={@code true} it calls super.
3446N/A * If ignoreSubComponents=={@code false} it uses the XTextArea machinery
3446N/A * to change cursor appropriately. In particular it changes the cursor to
3446N/A * default if over scrollbars.
3446N/A */
3446N/A @Override
3446N/A public void pSetCursor(Cursor cursor, boolean ignoreSubComponents) {
3446N/A Point onScreen = getLocationOnScreen();
3446N/A if (ignoreSubComponents ||
3446N/A javaMouseEventHandler == null ||
3446N/A onScreen == null)
3446N/A {
3446N/A super.pSetCursor(cursor, true);
3446N/A return;
3446N/A }
3446N/A
3446N/A Point cursorPos = new Point();
3446N/A ((XGlobalCursorManager)XGlobalCursorManager.getCursorManager()).getCursorPos(cursorPos);
3446N/A
3446N/A Point localPoint = new Point(cursorPos.x - onScreen.x, cursorPos.y - onScreen.y );
3446N/A
3446N/A javaMouseEventHandler.setPointerToUnderPoint(localPoint);
3446N/A javaMouseEventHandler.setCursor();
3446N/A }
3446N/A
0N/A void setScrollBarVisibility() {
0N/A int visibility = ((TextArea)target).getScrollbarVisibility();
0N/A jtext.setLineWrap(false);
0N/A
0N/A if (visibility == TextArea.SCROLLBARS_NONE) {
0N/A textPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
0N/A textPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
0N/A jtext.setLineWrap(true);
0N/A }
0N/A else if (visibility == TextArea.SCROLLBARS_BOTH) {
0N/A
0N/A textPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
0N/A textPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
0N/A }
0N/A else if (visibility == TextArea.SCROLLBARS_VERTICAL_ONLY) {
0N/A textPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
0N/A textPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
0N/A jtext.setLineWrap(true);
0N/A }
0N/A else if (visibility == TextArea.SCROLLBARS_HORIZONTAL_ONLY) {
0N/A textPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
0N/A textPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Compute minimum size.
0N/A */
0N/A public Dimension getMinimumSize() {
0N/A return getMinimumSize(10, 60);
0N/A }
0N/A
0N/A public Dimension getPreferredSize(int rows, int cols) {
0N/A return getMinimumSize(rows, cols);
0N/A }
0N/A
0N/A /**
0N/A * @see java.awt.peer.TextAreaPeer
0N/A */
0N/A
0N/A public Dimension getMinimumSize(int rows, int cols) {
0N/A /* Dimension d = null;
0N/A if (jtext != null) {
0N/A d = jtext.getMinimumSize(rows,cols);
0N/A }
0N/A return d;
0N/A */
0N/A
0N/A int vsbwidth=0;
0N/A int hsbheight=0;
0N/A
0N/A JScrollBar vsb = textPane.getVerticalScrollBar();
0N/A if (vsb != null) {
0N/A vsbwidth = vsb.getMinimumSize().width;
0N/A }
0N/A
0N/A JScrollBar hsb = textPane.getHorizontalScrollBar();
0N/A if (hsb != null) {
0N/A hsbheight = hsb.getMinimumSize().height;
0N/A }
0N/A
0N/A Font f = jtext.getFont();
0N/A FontMetrics fm = jtext.getFontMetrics(f);
0N/A
0N/A return new Dimension(fm.charWidth('0') * cols + /*2*XMARGIN +*/ vsbwidth,
0N/A fm.getHeight() * rows + /*2*YMARGIN +*/ hsbheight);
0N/A }
0N/A
0N/A public boolean isFocusable() {
0N/A return true;
0N/A }
0N/A
0N/A public void setVisible(boolean b) {
0N/A super.setVisible(b);
0N/A if (textPane != null)
0N/A textPane.setVisible(b);
0N/A }
0N/A
0N/A void repaintText() {
0N/A jtext.repaintNow();
0N/A }
0N/A
0N/A public void focusGained(FocusEvent e) {
0N/A super.focusGained(e);
0N/A jtext.forwardFocusGained(e);
0N/A }
0N/A
0N/A public void focusLost(FocusEvent e) {
0N/A super.focusLost(e);
0N/A jtext.forwardFocusLost(e);
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Paint the component
0N/A * this method is called when the repaint instruction has been used
0N/A */
0N/A
0N/A public void repaint() {
0N/A if (textPane != null) {
0N/A //textPane.validate();
0N/A textPane.repaint();
0N/A }
0N/A }
0N/A
0N/A public void paint(Graphics g) {
0N/A if (textPane != null) {
0N/A textPane.paint(g);
0N/A }
0N/A }
0N/A
0N/A public void setBounds(int x, int y, int width, int height, int op) {
0N/A super.setBounds(x, y, width, height, op);
0N/A if (textPane != null) {
0N/A /*
0N/A * Fixed 6277332, 6198290:
0N/A * the coordinates is coming (to peer): relatively to closest HW parent
0N/A * the coordinates is setting (to textPane): relatively to closest ANY parent
0N/A * the parent of peer is target.getParent()
0N/A * the parent of textPane is the same
0N/A * see 6277332, 6198290 for more information
0N/A */
0N/A int childX = x;
0N/A int childY = y;
0N/A Component parent = target.getParent();
0N/A // we up to heavyweight parent in order to be sure
0N/A // that the coordinates of the text pane is relatively to closest parent
0N/A while (parent.isLightweight()){
0N/A childX -= parent.getX();
0N/A childY -= parent.getY();
0N/A parent = parent.getParent();
0N/A }
0N/A textPane.setBounds(childX,childY,width,height);
0N/A textPane.validate();
0N/A }
0N/A }
0N/A
0N/A void handleJavaKeyEvent(KeyEvent e) {
1976N/A AWTAccessor.getComponentAccessor().processEvent(jtext,e);
0N/A }
0N/A
0N/A public boolean handlesWheelScrolling() { return true; }
0N/A
0N/A void handleJavaMouseWheelEvent(MouseWheelEvent e) {
1976N/A AWTAccessor.getComponentAccessor().processEvent(textPane,e);
0N/A }
0N/A
0N/A public void handleJavaMouseEvent( MouseEvent e ) {
0N/A super.handleJavaMouseEvent( e );
0N/A javaMouseEventHandler.handle( e );
0N/A }
0N/A
0N/A void handleJavaInputMethodEvent(InputMethodEvent e) {
0N/A if (jtext != null)
0N/A jtext.processInputMethodEventPublic((InputMethodEvent)e);
0N/A }
0N/A
0N/A /**
0N/A * @see java.awt.peer.TextComponentPeer
0N/A */
0N/A public void select(int s, int e) {
0N/A jtext.select(s,e);
0N/A // Fixed 5100806
0N/A // We must take care that Swing components repainted correctly
0N/A jtext.repaint();
0N/A }
0N/A
0N/A public void setBackground(Color c) {
0N/A super.setBackground(c);
0N/A// synchronized (getStateLock()) {
0N/A// background = c;
0N/A// }
0N/A if (jtext != null) {
0N/A jtext.setBackground(c);
0N/A jtext.setSelectedTextColor(c);
0N/A }
0N/A// repaintText();
0N/A }
0N/A
0N/A public void setForeground(Color c) {
0N/A super.setForeground(c);
0N/A// synchronized (getStateLock()) {
0N/A// foreground = c;
0N/A// }
0N/A if (jtext != null) {
0N/A jtext.setForeground(foreground);
0N/A jtext.setSelectionColor(foreground);
0N/A jtext.setCaretColor(foreground);
0N/A }
0N/A// repaintText();
0N/A }
0N/A
0N/A public void setFont(Font f) {
0N/A super.setFont(f);
0N/A// synchronized (getStateLock()) {
0N/A// font = f;
0N/A// }
0N/A if (jtext != null) {
0N/A jtext.setFont(font);
0N/A }
0N/A textPane.validate();
0N/A }
0N/A
0N/A
0N/A /**
0N/A * @see java.awt.peer.TextComponentPeer
0N/A */
0N/A public void setEditable(boolean editable) {
0N/A this.editable = editable;
0N/A if (jtext != null) jtext.setEditable(editable);
0N/A repaintText();
0N/A }
0N/A
0N/A /**
0N/A * @see java.awt.peer.ComponentPeer
0N/A */
0N/A public void setEnabled(boolean enabled) {
0N/A super.setEnabled(enabled);
0N/A if (jtext != null) {
0N/A jtext.setEnabled(enabled);
0N/A jtext.repaint();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * @see java.awt.peer.TextComponentPeer
0N/A */
0N/A public InputMethodRequests getInputMethodRequests() {
0N/A if (jtext != null) return jtext.getInputMethodRequests();
0N/A else return null;
0N/A }
0N/A
0N/A /**
0N/A * @see java.awt.peer.TextComponentPeer
0N/A */
0N/A public int getSelectionStart() {
0N/A return jtext.getSelectionStart();
0N/A }
0N/A
0N/A /**
0N/A * @see java.awt.peer.TextComponentPeer
0N/A */
0N/A public int getSelectionEnd() {
0N/A return jtext.getSelectionEnd();
0N/A }
0N/A
0N/A /**
0N/A * @see java.awt.peer.TextComponentPeer
0N/A */
0N/A public String getText() {
0N/A return jtext.getText();
0N/A }
0N/A
0N/A /**
0N/A * @see java.awt.peer.TextComponentPeer
0N/A */
0N/A public void setText(String txt) {
0N/A setTextImpl(txt);
0N/A repaintText();
0N/A }
0N/A
0N/A protected boolean setTextImpl(String txt) {
0N/A if (jtext != null) {
0N/A // JTextArea.setText() posts two different events (remove & insert).
0N/A // Since we make no differences between text events,
0N/A // the document listener has to be disabled while
0N/A // JTextArea.setText() is called.
0N/A jtext.getDocument().removeDocumentListener(jtext);
0N/A jtext.setText(txt);
0N/A if (firstChangeSkipped) {
0N/A postEvent(new TextEvent(target, TextEvent.TEXT_VALUE_CHANGED));
0N/A }
0N/A jtext.getDocument().addDocumentListener(jtext);
0N/A }
0N/A return true;
0N/A }
0N/A
0N/A /**
0N/A * insert the text "txt on position "pos" in the array lines
0N/A * @see java.awt.peer.TextAreaPeer
0N/A */
0N/A public void insert(String txt, int p) {
0N/A if (jtext != null) {
0N/A boolean doScroll = (p >= jtext.getDocument().getLength() && jtext.getDocument().getLength() != 0);
0N/A jtext.insert(txt,p);
0N/A textPane.validate();
0N/A if (doScroll) {
0N/A JScrollBar bar = textPane.getVerticalScrollBar();
0N/A if (bar != null) {
0N/A bar.setValue(bar.getMaximum()-bar.getVisibleAmount());
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * replace the text between the position "s" and "e" with "txt"
0N/A * @see java.awt.peer.TextAreaPeer
0N/A */
0N/A public void replaceRange(String txt, int s, int e) {
0N/A if (jtext != null) {
0N/A // JTextArea.replaceRange() posts two different events.
0N/A // Since we make no differences between text events,
0N/A // the document listener has to be disabled while
0N/A // JTextArea.replaceRange() is called.
0N/A jtext.getDocument().removeDocumentListener(jtext);
0N/A jtext.replaceRange(txt, s, e);
0N/A postEvent(new TextEvent(target, TextEvent.TEXT_VALUE_CHANGED));
0N/A jtext.getDocument().addDocumentListener(jtext);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * to be implemented.
0N/A * @see java.awt.peer.TextComponentPeer
0N/A */
0N/A public void setCaretPosition(int position) {
0N/A jtext.setCaretPosition(position);
0N/A }
0N/A
0N/A /**
0N/A * to be implemented.
0N/A * @see java.awt.peer.TextComponentPeer
0N/A */
0N/A public int getCaretPosition() {
0N/A return jtext.getCaretPosition();
0N/A }
0N/A
0N/A /**
0N/A * DEPRECATED
0N/A * @see java.awt.peer.TextAreaPeer
0N/A */
0N/A public void insertText(String txt, int pos) {
0N/A insert(txt, pos);
0N/A }
0N/A
0N/A /**
0N/A * DEPRECATED
0N/A * @see java.awt.peer.TextAreaPeer
0N/A */
0N/A public void replaceText(String txt, int start, int end) {
0N/A replaceRange(txt, start, end);
0N/A }
0N/A
0N/A /**
0N/A * DEPRECATED
0N/A * @see java.awt.peer.TextAreaPeer
0N/A */
0N/A public Dimension minimumSize(int rows, int cols) {
0N/A return getMinimumSize(rows, cols);
0N/A }
0N/A
0N/A /**
0N/A * DEPRECATED
0N/A * @see java.awt.peer.TextAreaPeer
0N/A */
0N/A public Dimension preferredSize(int rows, int cols) {
0N/A return getPreferredSize(rows, cols);
0N/A }
0N/A
0N/A
0N/A class AWTTextAreaUI extends MotifTextAreaUI {
0N/A /**
0N/A * Creates a UI for a JTextArea.
0N/A *
0N/A * @param c the text field
0N/A * @return the UI
0N/A */
0N/A JTextArea jta;
0N/A
0N/A protected String getPropertyPrefix() { return "TextArea"; }
0N/A
0N/A public void installUI(JComponent c) {
0N/A super.installUI(c);
0N/A
0N/A jta = (JTextArea) c;
0N/A
0N/A JTextArea editor = jta;
0N/A
0N/A UIDefaults uidefaults = XToolkit.getUIDefaults();
0N/A
0N/A String prefix = getPropertyPrefix();
0N/A Font f = editor.getFont();
0N/A if ((f == null) || (f instanceof UIResource)) {
0N/A editor.setFont(uidefaults.getFont(prefix + ".font"));
0N/A }
0N/A
0N/A Color bg = editor.getBackground();
0N/A if ((bg == null) || (bg instanceof UIResource)) {
0N/A editor.setBackground(uidefaults.getColor(prefix + ".background"));
0N/A }
0N/A
0N/A Color fg = editor.getForeground();
0N/A if ((fg == null) || (fg instanceof UIResource)) {
0N/A editor.setForeground(uidefaults.getColor(prefix + ".foreground"));
0N/A }
0N/A
0N/A Color color = editor.getCaretColor();
0N/A if ((color == null) || (color instanceof UIResource)) {
0N/A editor.setCaretColor(uidefaults.getColor(prefix + ".caretForeground"));
0N/A }
0N/A
0N/A Color s = editor.getSelectionColor();
0N/A if ((s == null) || (s instanceof UIResource)) {
0N/A editor.setSelectionColor(uidefaults.getColor(prefix + ".selectionBackground"));
0N/A }
0N/A
0N/A Color sfg = editor.getSelectedTextColor();
0N/A if ((sfg == null) || (sfg instanceof UIResource)) {
0N/A editor.setSelectedTextColor(uidefaults.getColor(prefix + ".selectionForeground"));
0N/A }
0N/A
0N/A Color dfg = editor.getDisabledTextColor();
0N/A if ((dfg == null) || (dfg instanceof UIResource)) {
0N/A editor.setDisabledTextColor(uidefaults.getColor(prefix + ".inactiveForeground"));
0N/A }
0N/A
0N/A Border b = new BevelBorder(false,SystemColor.controlDkShadow,SystemColor.controlLtHighlight);
0N/A editor.setBorder(new BorderUIResource.CompoundBorderUIResource(
0N/A b,new EmptyBorder(2, 2, 2, 2)));
0N/A
0N/A Insets margin = editor.getMargin();
0N/A if (margin == null || margin instanceof UIResource) {
0N/A editor.setMargin(uidefaults.getInsets(prefix + ".margin"));
0N/A }
0N/A }
0N/A
0N/A protected void installKeyboardActions() {
0N/A super.installKeyboardActions();
0N/A
0N/A JTextComponent comp = getComponent();
0N/A
0N/A UIDefaults uidefaults = XToolkit.getUIDefaults();
0N/A
0N/A String prefix = getPropertyPrefix();
0N/A
0N/A InputMap map = (InputMap)uidefaults.get(prefix + ".focusInputMap");
0N/A
0N/A if (map != null) {
0N/A SwingUtilities.replaceUIInputMap(comp, JComponent.WHEN_FOCUSED,
0N/A map);
0N/A }
0N/A }
0N/A
0N/A protected Caret createCaret() {
0N/A return new XAWTCaret();
0N/A }
0N/A }
0N/A
0N/A
5348N/A static class XAWTCaret extends DefaultCaret {
0N/A public void focusGained(FocusEvent e) {
0N/A super.focusGained(e);
5348N/A if (getComponent().isEnabled()){
5348N/A // Make sure the cursor is visible in case of non-editable TextArea
5348N/A super.setVisible(true);
5348N/A }
0N/A getComponent().repaint();
0N/A }
0N/A
0N/A public void focusLost(FocusEvent e) {
0N/A super.focusLost(e);
0N/A getComponent().repaint();
0N/A }
0N/A
0N/A // Fix for 5100950: textarea.getSelectedText() returns the de-selected text, on XToolkit
0N/A // Restoring Motif behaviour
0N/A // If the text is unhighlighted then we should sets the selection range to zero
0N/A public void setSelectionVisible(boolean vis) {
0N/A if (vis){
0N/A super.setSelectionVisible(vis);
0N/A }else{
0N/A // In order to de-select the selection
0N/A setDot(getDot());
0N/A }
0N/A }
0N/A }
0N/A
0N/A
0N/A class XAWTScrollBarButton extends BasicArrowButton
0N/A {
0N/A UIDefaults uidefaults = XToolkit.getUIDefaults();
0N/A private Color darkShadow = SystemColor.controlShadow;
0N/A private Color lightShadow = SystemColor.controlLtHighlight;
0N/A private Color buttonBack = uidefaults.getColor("ScrollBar.track");
0N/A
0N/A public XAWTScrollBarButton(int direction)
0N/A {
0N/A super(direction);
0N/A
0N/A switch (direction) {
0N/A case NORTH:
0N/A case SOUTH:
0N/A case EAST:
0N/A case WEST:
0N/A this.direction = direction;
0N/A break;
0N/A default:
0N/A throw new IllegalArgumentException("invalid direction");
0N/A }
0N/A
0N/A setRequestFocusEnabled(false);
0N/A setOpaque(true);
0N/A setBackground(uidefaults.getColor("ScrollBar.thumb"));
0N/A setForeground(uidefaults.getColor("ScrollBar.foreground"));
0N/A }
0N/A
0N/A public Dimension getPreferredSize() {
0N/A switch (direction) {
0N/A case NORTH:
0N/A case SOUTH:
0N/A return new Dimension(11, 12);
0N/A case EAST:
0N/A case WEST:
0N/A default:
0N/A return new Dimension(12, 11);
0N/A }
0N/A }
0N/A
0N/A public Dimension getMinimumSize() {
0N/A return getPreferredSize();
0N/A }
0N/A
0N/A public Dimension getMaximumSize() {
0N/A return getPreferredSize();
0N/A }
0N/A
0N/A public boolean isFocusTraversable() {
0N/A return false;
0N/A }
0N/A
0N/A public void paint(Graphics g)
0N/A {
0N/A int w = getWidth();
0N/A int h = getHeight();
0N/A
0N/A if (isOpaque()) {
0N/A g.setColor(buttonBack);
0N/A g.fillRect(0, 0, w, h);
0N/A }
0N/A
0N/A boolean isPressed = getModel().isPressed();
0N/A Color lead = (isPressed) ? darkShadow : lightShadow;
0N/A Color trail = (isPressed) ? lightShadow : darkShadow;
0N/A Color fill = getBackground();
0N/A
0N/A int cx = w / 2;
0N/A int cy = h / 2;
0N/A int s = Math.min(w, h);
0N/A
0N/A switch (direction) {
0N/A case NORTH:
0N/A g.setColor(lead);
0N/A g.drawLine(cx, 0, cx, 0);
0N/A for (int x = cx - 1, y = 1, dx = 1; y <= s - 2; y += 2) {
0N/A g.setColor(lead);
0N/A g.drawLine(x, y, x, y);
0N/A if (y >= (s - 2)) {
0N/A g.drawLine(x, y + 1, x, y + 1);
0N/A }
0N/A g.setColor(fill);
0N/A g.drawLine(x + 1, y, x + dx, y);
0N/A if (y < (s - 2)) {
0N/A g.drawLine(x, y + 1, x + dx + 1, y + 1);
0N/A }
0N/A g.setColor(trail);
0N/A g.drawLine(x + dx + 1, y, x + dx + 1, y);
0N/A if (y >= (s - 2)) {
0N/A g.drawLine(x + 1, y + 1, x + dx + 1, y + 1);
0N/A }
0N/A dx += 2;
0N/A x -= 1;
0N/A }
0N/A break;
0N/A
0N/A case SOUTH:
0N/A g.setColor(trail);
0N/A g.drawLine(cx, s, cx, s);
0N/A for (int x = cx - 1, y = s - 1, dx = 1; y >= 1; y -= 2) {
0N/A g.setColor(lead);
0N/A g.drawLine(x, y, x, y);
0N/A if (y <= 2) {
0N/A g.drawLine(x, y - 1, x + dx + 1, y - 1);
0N/A }
0N/A g.setColor(fill);
0N/A g.drawLine(x + 1, y, x + dx, y);
0N/A if (y > 2) {
0N/A g.drawLine(x, y - 1, x + dx + 1, y - 1);
0N/A }
0N/A g.setColor(trail);
0N/A g.drawLine(x + dx + 1, y, x + dx + 1, y);
0N/A
0N/A dx += 2;
0N/A x -= 1;
0N/A }
0N/A break;
0N/A
0N/A case EAST:
0N/A g.setColor(lead);
0N/A g.drawLine(s, cy, s, cy);
0N/A for (int y = cy - 1, x = s - 1, dy = 1; x >= 1; x -= 2) {
0N/A g.setColor(lead);
0N/A g.drawLine(x, y, x, y);
0N/A if (x <= 2) {
0N/A g.drawLine(x - 1, y, x - 1, y + dy + 1);
0N/A }
0N/A g.setColor(fill);
0N/A g.drawLine(x, y + 1, x, y + dy);
0N/A if (x > 2) {
0N/A g.drawLine(x - 1, y, x - 1, y + dy + 1);
0N/A }
0N/A g.setColor(trail);
0N/A g.drawLine(x, y + dy + 1, x, y + dy + 1);
0N/A
0N/A dy += 2;
0N/A y -= 1;
0N/A }
0N/A break;
0N/A
0N/A case WEST:
0N/A g.setColor(trail);
0N/A g.drawLine(0, cy, 0, cy);
0N/A for (int y = cy - 1, x = 1, dy = 1; x <= s - 2; x += 2) {
0N/A g.setColor(lead);
0N/A g.drawLine(x, y, x, y);
0N/A if (x >= (s - 2)) {
0N/A g.drawLine(x + 1, y, x + 1, y);
0N/A }
0N/A g.setColor(fill);
0N/A g.drawLine(x, y + 1, x, y + dy);
0N/A if (x < (s - 2)) {
0N/A g.drawLine(x + 1, y, x + 1, y + dy + 1);
0N/A }
0N/A g.setColor(trail);
0N/A g.drawLine(x, y + dy + 1, x, y + dy + 1);
0N/A if (x >= (s - 2)) {
0N/A g.drawLine(x + 1, y + 1, x + 1, y + dy + 1);
0N/A }
0N/A dy += 2;
0N/A y -= 1;
0N/A }
0N/A break;
0N/A }
0N/A }
0N/A }
0N/A
0N/A
0N/A class XAWTScrollBarUI extends BasicScrollBarUI
0N/A {
0N/A public XAWTScrollBarUI() {
0N/A super();
0N/A }
0N/A
0N/A protected void installDefaults()
0N/A {
0N/A super.installDefaults();
0N/A scrollbar.setBorder(new BevelBorder(false,SystemColor.controlDkShadow,SystemColor.controlLtHighlight) );
0N/A }
0N/A
0N/A protected void configureScrollBarColors() {
0N/A UIDefaults uidefaults = XToolkit.getUIDefaults();
0N/A Color bg = scrollbar.getBackground();
0N/A if (bg == null || bg instanceof UIResource) {
0N/A scrollbar.setBackground(uidefaults.getColor("ScrollBar.background"));
0N/A }
0N/A
0N/A Color fg = scrollbar.getForeground();
0N/A if (fg == null || fg instanceof UIResource) {
0N/A scrollbar.setForeground(uidefaults.getColor("ScrollBar.foreground"));
0N/A }
0N/A
0N/A thumbHighlightColor = uidefaults.getColor("ScrollBar.thumbHighlight");
0N/A thumbLightShadowColor = uidefaults.getColor("ScrollBar.thumbShadow");
0N/A thumbDarkShadowColor = uidefaults.getColor("ScrollBar.thumbDarkShadow");
0N/A thumbColor = uidefaults.getColor("ScrollBar.thumb");
0N/A trackColor = uidefaults.getColor("ScrollBar.track");
0N/A
0N/A trackHighlightColor = uidefaults.getColor("ScrollBar.trackHighlight");
0N/A
0N/A }
0N/A
0N/A protected JButton createDecreaseButton(int orientation) {
0N/A JButton b = new XAWTScrollBarButton(orientation);
0N/A return b;
0N/A
0N/A }
0N/A
0N/A protected JButton createIncreaseButton(int orientation) {
0N/A JButton b = new XAWTScrollBarButton(orientation);
0N/A return b;
0N/A }
0N/A
0N/A public JButton getDecreaseButton(){
0N/A return decrButton;
0N/A }
0N/A
0N/A public JButton getIncreaseButton(){
0N/A return incrButton;
0N/A }
0N/A
0N/A public void paint(Graphics g, JComponent c) {
0N/A paintTrack(g, c, getTrackBounds());
0N/A Rectangle thumbBounds = getThumbBounds();
0N/A paintThumb(g, c, thumbBounds);
0N/A }
0N/A
0N/A public void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds)
0N/A {
0N/A if(!scrollbar.isEnabled()) {
0N/A return;
0N/A }
0N/A
0N/A if (thumbBounds.isEmpty())
0N/A thumbBounds = getTrackBounds();
0N/A
0N/A int w = thumbBounds.width;
0N/A int h = thumbBounds.height;
0N/A
0N/A g.translate(thumbBounds.x, thumbBounds.y);
0N/A g.setColor(thumbColor);
0N/A g.fillRect(0, 0, w-1, h-1);
0N/A
0N/A g.setColor(thumbHighlightColor);
0N/A g.drawLine(0, 0, 0, h-1);
0N/A g.drawLine(1, 0, w-1, 0);
0N/A
0N/A g.setColor(thumbLightShadowColor);
0N/A g.drawLine(1, h-1, w-1, h-1);
0N/A g.drawLine(w-1, 1, w-1, h-2);
0N/A
0N/A g.translate(-thumbBounds.x, -thumbBounds.y);
0N/A }
0N/A }
0N/A
0N/A
0N/A class AWTTextArea extends JTextArea implements DocumentListener {
0N/A boolean isFocused = false;
0N/A XTextAreaPeer peer;
0N/A
0N/A public AWTTextArea(String text, XTextAreaPeer peer) {
0N/A super(text);
0N/A setFocusable(false);
0N/A this.peer = peer;
0N/A }
0N/A
0N/A public void insertUpdate(DocumentEvent e) {
0N/A if (peer != null) {
0N/A peer.postEvent(new TextEvent(peer.target,
0N/A TextEvent.TEXT_VALUE_CHANGED));
0N/A }
0N/A }
0N/A
0N/A public void removeUpdate(DocumentEvent e) {
0N/A if (peer != null) {
0N/A peer.postEvent(new TextEvent(peer.target,
0N/A TextEvent.TEXT_VALUE_CHANGED));
0N/A }
0N/A }
0N/A
0N/A public void changedUpdate(DocumentEvent e) {
0N/A if (peer != null) {
0N/A peer.postEvent(new TextEvent(peer.target,
0N/A TextEvent.TEXT_VALUE_CHANGED));
0N/A }
0N/A }
0N/A
0N/A void forwardFocusGained( FocusEvent e) {
0N/A isFocused = true;
0N/A FocusEvent fe = CausedFocusEvent.retarget(e, this);
0N/A super.processFocusEvent(fe);
0N/A }
0N/A
0N/A
0N/A void forwardFocusLost( FocusEvent e) {
0N/A isFocused = false;
0N/A FocusEvent fe = CausedFocusEvent.retarget(e, this);
0N/A super.processFocusEvent(fe);
0N/A }
0N/A
0N/A public boolean hasFocus() {
0N/A return isFocused;
0N/A }
0N/A
0N/A public void repaintNow() {
0N/A paintImmediately(getBounds());
0N/A }
0N/A
0N/A public void processMouseEventPublic(MouseEvent e) {
0N/A processMouseEvent(e);
0N/A }
0N/A
0N/A public void processMouseMotionEventPublic(MouseEvent e) {
0N/A processMouseMotionEvent(e);
0N/A }
0N/A
0N/A public void processInputMethodEventPublic(InputMethodEvent e) {
0N/A processInputMethodEvent(e);
0N/A }
0N/A
0N/A public void updateUI() {
0N/A ComponentUI ui = new AWTTextAreaUI();
0N/A setUI(ui);
0N/A }
0N/A
0N/A // Fix for 4915454 - override the default implementation to avoid
0N/A // loading SystemFlavorMap and associated classes.
0N/A public void setTransferHandler(TransferHandler newHandler) {
0N/A TransferHandler oldHandler = (TransferHandler)
5255N/A getClientProperty(AWTAccessor.getClientPropertyKeyAccessor()
5255N/A .getJComponent_TRANSFER_HANDLER());
5255N/A putClientProperty(AWTAccessor.getClientPropertyKeyAccessor()
5255N/A .getJComponent_TRANSFER_HANDLER(),
0N/A newHandler);
0N/A
0N/A firePropertyChange("transferHandler", oldHandler, newHandler);
0N/A }
0N/A }
0N/A
0N/A
0N/A class XAWTScrollPaneUI extends BasicScrollPaneUI
0N/A {
0N/A private final Border vsbMarginBorderR = new EmptyBorder(0, 2, 0, 0);
0N/A private final Border vsbMarginBorderL = new EmptyBorder(0, 0, 0, 2);
0N/A private final Border hsbMarginBorder = new EmptyBorder(2, 0, 0, 0);
0N/A
0N/A private Border vsbBorder;
0N/A private Border hsbBorder;
0N/A
0N/A private PropertyChangeListener propertyChangeHandler;
0N/A
0N/A protected void installListeners(JScrollPane scrollPane) {
0N/A super.installListeners(scrollPane);
0N/A propertyChangeHandler = createPropertyChangeHandler();
0N/A scrollPane.addPropertyChangeListener(propertyChangeHandler);
0N/A }
0N/A
0N/A public void paint(Graphics g, JComponent c) {
0N/A Border vpBorder = scrollpane.getViewportBorder();
0N/A if (vpBorder != null) {
0N/A Rectangle r = scrollpane.getViewportBorderBounds();
0N/A vpBorder.paintBorder(scrollpane, g, r.x, r.y, r.width, r.height);
0N/A }
0N/A }
0N/A
0N/A protected void uninstallListeners(JScrollPane scrollPane) {
0N/A super.uninstallListeners(scrollPane);
0N/A scrollPane.removePropertyChangeListener(propertyChangeHandler);
0N/A }
0N/A
0N/A private PropertyChangeListener createPropertyChangeHandler() {
0N/A return new PropertyChangeListener() {
0N/A public void propertyChange(PropertyChangeEvent e) {
0N/A String propertyName = e.getPropertyName();
0N/A
0N/A if (propertyName.equals("componentOrientation")) {
0N/A JScrollPane pane = (JScrollPane)e.getSource();
0N/A JScrollBar vsb = pane.getVerticalScrollBar();
0N/A if (vsb != null) {
0N/A if (isLeftToRight(pane)) {
0N/A vsbBorder = new CompoundBorder(new EmptyBorder(0, 4, 0, -4),
0N/A vsb.getBorder());
0N/A } else {
0N/A vsbBorder = new CompoundBorder(new EmptyBorder(0, -4, 0, 4),
0N/A vsb.getBorder());
0N/A }
0N/A vsb.setBorder(vsbBorder);
0N/A }
0N/A }
0N/A }};
0N/A }
0N/A
0N/A boolean isLeftToRight( Component c ) {
0N/A return c.getComponentOrientation().isLeftToRight();
0N/A }
0N/A
0N/A
0N/A protected void installDefaults(JScrollPane scrollpane) {
0N/A Border b = scrollpane.getBorder();
0N/A UIDefaults uidefaults = XToolkit.getUIDefaults();
0N/A scrollpane.setBorder(uidefaults.getBorder("ScrollPane.border"));
0N/A scrollpane.setBackground(uidefaults.getColor("ScrollPane.background"));
0N/A scrollpane.setViewportBorder(uidefaults.getBorder("TextField.border"));
0N/A JScrollBar vsb = scrollpane.getVerticalScrollBar();
0N/A if (vsb != null) {
0N/A if (isLeftToRight(scrollpane)) {
0N/A vsbBorder = new CompoundBorder(vsbMarginBorderR,
0N/A vsb.getBorder());
0N/A }
0N/A else {
0N/A vsbBorder = new CompoundBorder(vsbMarginBorderL,
0N/A vsb.getBorder());
0N/A }
0N/A vsb.setBorder(vsbBorder);
0N/A }
0N/A
0N/A JScrollBar hsb = scrollpane.getHorizontalScrollBar();
0N/A if (hsb != null) {
0N/A hsbBorder = new CompoundBorder(hsbMarginBorder, hsb.getBorder());
0N/A hsb.setBorder(hsbBorder);
0N/A }
0N/A }
0N/A
0N/A protected void uninstallDefaults(JScrollPane c) {
0N/A super.uninstallDefaults(c);
0N/A
0N/A JScrollBar vsb = scrollpane.getVerticalScrollBar();
0N/A if (vsb != null) {
0N/A if (vsb.getBorder() == vsbBorder) {
0N/A vsb.setBorder(null);
0N/A }
0N/A vsbBorder = null;
0N/A }
0N/A
0N/A JScrollBar hsb = scrollpane.getHorizontalScrollBar();
0N/A if (hsb != null) {
0N/A if (hsb.getBorder() == hsbBorder) {
0N/A hsb.setBorder(null);
0N/A }
0N/A hsbBorder = null;
0N/A }
0N/A }
0N/A }
0N/A
0N/A
0N/A private class AWTTextPane extends JScrollPane implements FocusListener {
0N/A JTextArea jtext;
0N/A XWindow xwin;
0N/A
0N/A Color control = SystemColor.control;
0N/A Color focus = SystemColor.activeCaptionBorder;
0N/A
0N/A public AWTTextPane(JTextArea jt, XWindow xwin, Container parent) {
0N/A super(jt);
0N/A this.xwin = xwin;
0N/A setDoubleBuffered(true);
0N/A jt.addFocusListener(this);
1976N/A AWTAccessor.getComponentAccessor().setParent(this,parent);
0N/A setViewportBorder(new BevelBorder(false,SystemColor.controlDkShadow,SystemColor.controlLtHighlight) );
0N/A this.jtext = jt;
0N/A setFocusable(false);
0N/A addNotify();
0N/A }
0N/A
0N/A public void focusGained(FocusEvent e) {
0N/A Graphics g = getGraphics();
0N/A Rectangle r = getViewportBorderBounds();
0N/A g.setColor(focus);
0N/A g.drawRect(r.x,r.y,r.width,r.height);
0N/A g.dispose();
0N/A }
0N/A
0N/A public void focusLost(FocusEvent e) {
0N/A Graphics g = getGraphics();
0N/A Rectangle r = getViewportBorderBounds();
0N/A g.setColor(control);
0N/A g.drawRect(r.x,r.y,r.width,r.height);
0N/A g.dispose();
0N/A }
0N/A
0N/A public Window getRealParent() {
0N/A return (Window) xwin.target;
0N/A }
0N/A
0N/A public ComponentPeer getPeer() {
0N/A return (ComponentPeer) (xwin);
0N/A }
0N/A
0N/A public void updateUI() {
0N/A ComponentUI ui = new XAWTScrollPaneUI();
0N/A setUI(ui);
0N/A }
0N/A
0N/A public JScrollBar createVerticalScrollBar() {
0N/A return new XAWTScrollBar(JScrollBar.VERTICAL);
0N/A }
0N/A
0N/A public JScrollBar createHorizontalScrollBar() {
0N/A return new XAWTScrollBar(JScrollBar.HORIZONTAL);
0N/A }
0N/A
0N/A public JTextArea getTextArea () {
0N/A return this.jtext;
0N/A }
0N/A
0N/A public Graphics getGraphics() {
0N/A return xwin.getGraphics();
0N/A }
0N/A
0N/A
0N/A class XAWTScrollBar extends ScrollBar {
0N/A
0N/A public XAWTScrollBar(int i) {
0N/A super(i);
0N/A setFocusable(false);
0N/A }
0N/A
0N/A public void updateUI() {
0N/A ComponentUI ui = new XAWTScrollBarUI();
0N/A setUI(ui);
0N/A }
0N/A }
0N/A }
0N/A
0N/A static class BevelBorder extends AbstractBorder implements UIResource {
0N/A private Color darkShadow = SystemColor.controlDkShadow;
0N/A private Color lightShadow = SystemColor.controlLtHighlight;
0N/A private Color control = SystemColor.controlShadow;
0N/A private boolean isRaised;
0N/A
0N/A public BevelBorder(boolean isRaised, Color darkShadow, Color lightShadow) {
0N/A this.isRaised = isRaised;
0N/A this.darkShadow = darkShadow;
0N/A this.lightShadow = lightShadow;
0N/A }
0N/A
0N/A public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
0N/A g.setColor((isRaised) ? lightShadow : darkShadow);
0N/A g.drawLine(x, y, x+w-1, y); // top
0N/A g.drawLine(x, y+h-1, x, y+1); // left
0N/A
0N/A g.setColor(control);
0N/A g.drawLine(x+1, y+1, x+w-2, y+1); // top
0N/A g.drawLine(x+1, y+h-1, x+1, y+1); // left
0N/A
0N/A g.setColor((isRaised) ? darkShadow : lightShadow);
0N/A g.drawLine(x+1, y+h-1, x+w-1, y+h-1); // bottom
0N/A g.drawLine(x+w-1, y+h-1, x+w-1, y+1); // right
0N/A
0N/A g.setColor(control);
0N/A g.drawLine(x+1, y+h-2, x+w-2, y+h-2); // bottom
0N/A g.drawLine(x+w-2, y+h-2, x+w-2, y+1); // right
0N/A }
0N/A
0N/A public Insets getBorderInsets(Component c) {
0N/A return getBorderInsets(c, new Insets(0,0,0,0));
0N/A }
0N/A
0N/A public Insets getBorderInsets(Component c, Insets insets) {
0N/A insets.top = insets.left = insets.bottom = insets.right = 2;
0N/A return insets;
0N/A }
0N/A
0N/A public boolean isOpaque(Component c) {
0N/A return true;
0N/A }
0N/A }
0N/A
0N/A
0N/A // This class dispatches 'MouseEvent's to 'XTextAreaPeer''s (hidden)
0N/A // subcomponents, and overrides mouse cursor, e.g. for scrollbars.
0N/A //
0N/A // However, current dispatching is a kind of fake, and is tuned to do only
0N/A // what is necessary/possible. E.g. no additional mouse-exited/entered
0N/A // events are generated, when mouse exits scrollbar and enters viewport
0N/A // with JTextArea inside. Actually, no events are ever generated here (for
0N/A // now). They are only dispatched as correctly as possible/neccessary.
0N/A //
0N/A // In future, it would be better to replace fake-emulation of grab-detection
0N/A // and event-dispatching here, by reusing some common implementation of this
0N/A // functionality. Mouse-cursor setting should also be freed of hacked
0N/A // overloading here.
0N/A
0N/A private static final class JavaMouseEventHandler {
0N/A private final XTextAreaPeer outer;
0N/A private final Pointer current = new Pointer();
0N/A private boolean grabbed = false;
0N/A
0N/A JavaMouseEventHandler( XTextAreaPeer outer ) {
0N/A this.outer = outer;
0N/A }
0N/A
0N/A
0N/A // 1. We can make grab-tracking emulation here more robust to variations in
0N/A // in mouse-events order and consistence. E.g. by using such code:
0N/A // if( grabbed && event.getID()==MouseEvent.MOUSE_MOVED ) grabbed = false;
0N/A // Or we can also use 'assert'ions.
0N/A // 2. WARNING: Currently, while grab-detection mechanism _here_ says, that
0N/A // grab is in progress, we do not update 'current'. In case 'current'
0N/A // is set to a scrollbar or to a scroll-button, then references to their
0N/A // 'Component'-instances are "remembered". And events are dispatched to
0N/A // these remembered components, without checking, if XTextAreaPeer has
0N/A // replaced these instances with another ones. This also aplies to
0N/A // mouse-drags-from-outside (see comment in 'grabbed_update' method).
0N/A
0N/A void handle( MouseEvent event ) {
0N/A if ( ! grabbed ) {
0N/A // dispatch() needs up-to-date pointer in ungrabbed case.
3446N/A setPointerToUnderPoint( event.getPoint() );
0N/A }
0N/A dispatch( event );
0N/A boolean wasGrabbed = grabbed;
0N/A grabbed_update( event );
0N/A if ( wasGrabbed && ! grabbed ) {
3446N/A setPointerToUnderPoint( event.getPoint() );
0N/A }
0N/A setCursor();
0N/A }
0N/A
0N/A // Following is internally private:
0N/A
0N/A // Here dispatching is performed, of 'MouseEvent's to (some)
0N/A // 'XTextAreaPeer''s (hidden) subcomponents.
0N/A private void dispatch( MouseEvent event ) {
0N/A switch( current.getType() )
0N/A {
0N/A case TEXT:
0N/A Point point = toViewportChildLocalSpace(
0N/A outer.textPane.getViewport(), event.getPoint() );
0N/A XTextAreaPeer.AWTTextArea jtext = outer.jtext;
0N/A MouseEvent newEvent = newMouseEvent( jtext, point, event );
0N/A int id = newEvent.getID();
0N/A if ( id==MouseEvent.MOUSE_MOVED || id==MouseEvent.MOUSE_DRAGGED ) {
0N/A jtext.processMouseMotionEventPublic( newEvent );
0N/A } else {
0N/A jtext.processMouseEventPublic( newEvent );
0N/A }
0N/A break;
0N/A
0N/A // We perform (additional) dispatching of events to buttons of
0N/A // scrollbar, instead of leaving it to JScrollbar. This is
0N/A // required, because of different listeners in Swing and AWT,
0N/A // which trigger scrolling (ArrowButtonListener vs. TrackListener,
0N/A // accordingly). So we dispatch events to scroll-buttons, to
0N/A // invoke a correct Swing button listener.
0N/A // See CR 6175401 for more information.
0N/A case BAR:
0N/A case BUTTON:
0N/A Component c = current.getBar();
0N/A Point p = toLocalSpace( c, event.getPoint() );
0N/A if ( current.getType()==Pointer.Type.BUTTON ) {
0N/A c = current.getButton();
0N/A p = toLocalSpace( c, p );
0N/A }
1976N/A AWTAccessor.getComponentAccessor().processEvent( c, newMouseEvent( c, p, event ) );
0N/A break;
0N/A }
0N/A }
0N/A
0N/A private static MouseEvent newMouseEvent(
0N/A Component source, Point point, MouseEvent template )
0N/A {
0N/A MouseEvent e = template;
2860N/A MouseEvent nme = new MouseEvent(
0N/A source,
0N/A e.getID(), e.getWhen(),
0N/A e.getModifiersEx() | e.getModifiers(),
0N/A point.x, point.y,
0N/A e.getXOnScreen(), e.getYOnScreen(),
0N/A e.getClickCount(), e.isPopupTrigger(), e.getButton() );
2860N/A // Because these MouseEvents are dispatched directly to
2860N/A // their target, we need to mark them as being
2860N/A // system-generated here
2860N/A SunToolkit.setSystemGenerated(nme);
2860N/A return nme;
0N/A }
0N/A
0N/A private void setCursor() {
0N/A if ( current.getType()==Pointer.Type.TEXT ) {
0N/A // 'target.getCursor()' is also applied from elsewhere
0N/A // (at least now), but only when mouse "entered", and
0N/A // before 'XTextAreaPeer.handleJavaMouseEvent' is invoked.
3446N/A outer.pSetCursor( outer.target.getCursor(), true );
0N/A }
0N/A else {
0N/A // We can write here a more intelligent cursor selection
0N/A // mechanism, like getting cursor from 'current' component.
0N/A // However, I see no point in doing so now. But if you feel
0N/A // like implementing it, you'll probably need to introduce
0N/A // 'Pointer.Type.PANEL'.
3446N/A outer.pSetCursor( outer.textPane.getCursor(), true );
0N/A }
0N/A }
0N/A
0N/A
0N/A // Current way of grab-detection causes interesting (but harmless)
0N/A // side-effect. If mouse is draged from outside to inside of TextArea,
0N/A // we will then (in some cases) be asked to dispatch mouse-entered/exited
0N/A // events. But, as at least one mouse-button is down, we will detect
0N/A // grab-mode is on (though the grab isn't ours).
0N/A //
0N/A // Thus, we will not update 'current' (see 'handle' method), and will
0N/A // dispatch events to the last subcomponent, the 'current' was set to.
0N/A // As always, we set cursor in this case also. But, all this seems
0N/A // harmless, because mouse entered/exited events seem to have no effect
0N/A // here, and cursor setting is ignored in case of drags from outside.
0N/A //
0N/A // Grab-detection can be further improved, e.g. by taking into account
0N/A // current event-ID, but I see not point in doing it now.
0N/A
0N/A private void grabbed_update( MouseEvent event ) {
0N/A final int allButtonsMask
0N/A = MouseEvent.BUTTON1_DOWN_MASK
0N/A | MouseEvent.BUTTON2_DOWN_MASK
0N/A | MouseEvent.BUTTON3_DOWN_MASK;
0N/A grabbed = ( (event.getModifiersEx() & allButtonsMask) != 0 );
0N/A }
0N/A
0N/A // 'toLocalSpace' and 'toViewportChildLocalSpace' can be "optimized" to
0N/A // 'return' 'void' and use 'Point' input-argument also as output.
0N/A private static Point toLocalSpace( Component local, Point inParentSpace )
0N/A {
0N/A Point p = inParentSpace;
0N/A Point l = local.getLocation();
0N/A return new Point( p.x - l.x, p.y - l.y );
0N/A }
0N/A private static Point toViewportChildLocalSpace( JViewport v, Point inViewportParentSpace )
0N/A {
0N/A Point l = toLocalSpace(v, inViewportParentSpace);
0N/A Point p = v.getViewPosition();
0N/A l.x += p.x;
0N/A l.y += p.y;
0N/A return l;
0N/A }
0N/A
3446N/A private void setPointerToUnderPoint( Point point ) {
0N/A if ( outer.textPane.getViewport().getBounds().contains( point ) ) {
0N/A current.setText();
0N/A }
0N/A else if ( ! setPointerIfPointOverScrollbar(
0N/A outer.textPane.getVerticalScrollBar(), point ) )
0N/A {
0N/A if ( ! setPointerIfPointOverScrollbar(
0N/A outer.textPane.getHorizontalScrollBar(), point ) )
0N/A {
0N/A current.setNone();
0N/A }
0N/A }
0N/A }
0N/A
0N/A private boolean setPointerIfPointOverScrollbar( JScrollBar bar, Point point ) {
0N/A if ( ! bar.getBounds().contains( point ) ) {
0N/A return false;
0N/A }
0N/A current.setBar( bar );
0N/A Point local = toLocalSpace( bar, point );
0N/A
0N/A XTextAreaPeer.XAWTScrollBarUI ui =
0N/A (XTextAreaPeer.XAWTScrollBarUI) bar.getUI();
0N/A
0N/A if ( ! setPointerIfPointOverButton( ui.getIncreaseButton(), local ) ) {
0N/A setPointerIfPointOverButton( ui.getDecreaseButton(), local );
0N/A }
0N/A
0N/A return true;
0N/A }
0N/A
0N/A private boolean setPointerIfPointOverButton( JButton button, Point point ) {
0N/A if ( ! button.getBounds().contains( point ) ) {
0N/A return false;
0N/A }
0N/A current.setButton( button );
0N/A return true;
0N/A }
0N/A
0N/A private static final class Pointer {
0N/A static enum Type {
0N/A NONE, TEXT, BAR, BUTTON // , PANEL
0N/A }
0N/A Type getType() {
0N/A return type;
0N/A }
0N/A boolean isNone() {
0N/A return type==Type.NONE;
0N/A }
0N/A JScrollBar getBar() {
0N/A boolean ok = type==Type.BAR || type==Type.BUTTON;
0N/A assert ok;
0N/A return ok ? bar : null;
0N/A }
0N/A JButton getButton() {
0N/A boolean ok = type==Type.BUTTON;
0N/A assert ok;
0N/A return ok ? button : null;
0N/A }
0N/A void setNone() {
0N/A type = Type.NONE;
0N/A }
0N/A void setText() {
0N/A type = Type.TEXT;
0N/A }
0N/A void setBar( JScrollBar bar ) {
0N/A this.bar=bar;
0N/A type=Type.BAR;
0N/A }
0N/A void setButton( JButton button ) {
0N/A this.button=button;
0N/A type=Type.BUTTON;
0N/A }
0N/A
0N/A private Type type;
0N/A private JScrollBar bar;
0N/A private JButton button;
0N/A }
0N/A }
0N/A}