001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.widgets; 003 004import java.awt.KeyboardFocusManager; 005import java.awt.event.FocusEvent; 006import java.awt.event.FocusListener; 007 008import javax.swing.JTextArea; 009import javax.swing.text.Document; 010 011import org.openstreetmap.josm.Main; 012 013/** 014 * Subclass of {@link JTextArea} that adds a "native" context menu (cut/copy/paste/select all). 015 * @since 5886 016 */ 017public class JosmTextArea extends JTextArea implements FocusListener { 018 019 /** 020 * Constructs a new {@code JosmTextArea}. A default model is set, the initial string 021 * is null, and rows/columns are set to 0. 022 */ 023 public JosmTextArea() { 024 this(null, null, 0, 0); 025 } 026 027 /** 028 * Constructs a new {@code JosmTextArea} with the specified text displayed. 029 * A default model is created and rows/columns are set to 0. 030 * 031 * @param text the text to be displayed, or null 032 */ 033 public JosmTextArea(String text) { 034 this(null, text, 0, 0); 035 } 036 037 /** 038 * Constructs a new {@code JosmTextArea} with the given document model, and defaults 039 * for all of the other arguments (null, 0, 0). 040 * 041 * @param doc the model to use 042 */ 043 public JosmTextArea(Document doc) { 044 this(doc, null, 0, 0); 045 } 046 047 /** 048 * Constructs a new empty {@code JosmTextArea} with the specified number of 049 * rows and columns. A default model is created, and the initial 050 * string is null. 051 * 052 * @param rows the number of rows >= 0 053 * @param columns the number of columns >= 0 054 * @throws IllegalArgumentException if the rows or columns 055 * arguments are negative. 056 */ 057 public JosmTextArea(int rows, int columns) { 058 this(null, null, rows, columns); 059 } 060 061 /** 062 * Constructs a new {@code JosmTextArea} with the specified text and number 063 * of rows and columns. A default model is created. 064 * 065 * @param text the text to be displayed, or null 066 * @param rows the number of rows >= 0 067 * @param columns the number of columns >= 0 068 * @throws IllegalArgumentException if the rows or columns 069 * arguments are negative. 070 */ 071 public JosmTextArea(String text, int rows, int columns) { 072 this(null, text, rows, columns); 073 } 074 075 /** 076 * Constructs a new {@code JosmTextArea} with the specified number of rows 077 * and columns, and the given model. All of the constructors 078 * feed through this constructor. 079 * 080 * @param doc the model to use, or create a default one if null 081 * @param text the text to be displayed, null if none 082 * @param rows the number of rows >= 0 083 * @param columns the number of columns >= 0 084 * @throws IllegalArgumentException if the rows or columns 085 * arguments are negative. 086 */ 087 public JosmTextArea(Document doc, String text, int rows, int columns) { 088 super(doc, text, rows, columns); 089 TextContextualPopupMenu.enableMenuFor(this, true); 090 addFocusListener(this); 091 } 092 093 /** 094 * Restore default behaviour of focus transfer with TAB, overriden by {@link JTextArea}. 095 * @return {@code this} 096 * @since 11308 097 */ 098 public JosmTextArea transferFocusOnTab() { 099 // http://stackoverflow.com/a/525867/2257172 100 setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null); 101 setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null); 102 return this; 103 } 104 105 @Override 106 public void focusGained(FocusEvent e) { 107 if (Main.map != null) { 108 Main.map.keyDetector.setEnabled(false); 109 } 110 } 111 112 @Override 113 public void focusLost(FocusEvent e) { 114 if (Main.map != null) { 115 Main.map.keyDetector.setEnabled(true); 116 } 117 } 118}