001package org.jdesktop.swingx.prompt; 002 003import java.awt.Component; 004import java.awt.Insets; 005import java.util.ArrayList; 006import java.util.Collections; 007import java.util.List; 008 009import javax.swing.Box; 010import javax.swing.JComponent; 011import javax.swing.JTextField; 012import javax.swing.plaf.basic.BasicTextUI; 013 014import org.jdesktop.swingx.plaf.TextUIWrapper; 015 016public class BuddySupport { 017 public enum Position { 018 LEFT, RIGHT 019 }; 020 021 public static final String OUTER_MARGIN = "outerMargin"; 022 023 public static void addLeft(Component c, JTextField textField) { 024 add(c, Position.LEFT, textField); 025 } 026 027 public static void addRight(Component c, JTextField textField) { 028 add(c, Position.RIGHT, textField); 029 } 030 031 public static void add(Component c, Position pos, JTextField textField) { 032 TextUIWrapper.getDefaultWrapper().install(textField, true); 033 034 List<Component> leftBuddies = buddies(Position.LEFT, textField); 035 List<Component> rightBuddies = buddies(Position.RIGHT, textField); 036 037 // ensure buddies are added 038 setLeft(textField, leftBuddies); 039 setRight(textField, rightBuddies); 040 041 // check if component is already here 042 if (isBuddy(c, textField)) { 043 throw new IllegalStateException("Component already added."); 044 } 045 046 if (Position.LEFT == pos) { 047 leftBuddies.add(c); 048 } else { 049 rightBuddies.add(0, c); 050 } 051 052 addToComponentHierarchy(c, pos, textField); 053 } 054 055 public static void addGap(int width, Position pos, JTextField textField) { 056 add(createGap(width), pos, textField); 057 } 058 059 public static void setRight(JTextField textField, List<Component> rightBuddies) { 060 set(rightBuddies, Position.RIGHT, textField); 061 } 062 063 public static void setLeft(JTextField textField, List<Component> leftBuddies) { 064 set(leftBuddies, Position.LEFT, textField); 065 } 066 067 public static void set(List<Component> buddies, Position pos, JTextField textField) { 068 textField.putClientProperty(pos, buddies); 069 } 070 071 private static void addToComponentHierarchy(Component c, Position pos, JTextField textField) { 072 textField.add(c, pos.toString()); 073 } 074 075 public static List<Component> getLeft(JTextField textField) { 076 return getBuddies(Position.LEFT, textField); 077 } 078 079 public static List<Component> getRight(JTextField textField) { 080 return getBuddies(Position.RIGHT, textField); 081 } 082 083 public static List<Component> getBuddies(Position pos, JTextField textField) { 084 return Collections.unmodifiableList(buddies(pos, textField)); 085 } 086 087 @SuppressWarnings("unchecked") 088 private static List<Component> buddies(Position pos, JTextField textField) { 089 List<Component> buddies = (List<Component>) textField.getClientProperty(pos); 090 091 if (buddies != null) { 092 return buddies; 093 } 094 return new ArrayList<Component>(); 095 } 096 097 public static boolean isBuddy(Component c, JTextField textField) { 098 return buddies(Position.LEFT, textField).contains(c) || buddies(Position.RIGHT, textField).contains(c); 099 } 100 101 /** 102 * Because {@link BasicTextUI} removes all components when uninstalled and 103 * therefore all buddies are removed when the LnF changes. 104 * 105 * @param c 106 * @param textField 107 */ 108 public static void remove(JComponent c, JTextField textField) { 109 buddies(Position.LEFT, textField).remove(c); 110 buddies(Position.RIGHT, textField).remove(c); 111 112 textField.remove(c); 113 } 114 115 public static void removeAll(JTextField textField) { 116 List<Component> left = buddies(Position.LEFT, textField); 117 for (Component c : left) { 118 textField.remove(c); 119 } 120 left.clear(); 121 List<Component> right = buddies(Position.RIGHT, textField); 122 for (Component c : right) { 123 textField.remove(c); 124 } 125 right.clear(); 126 127 } 128 129 public static void setOuterMargin(JTextField buddyField, Insets margin) { 130 buddyField.putClientProperty(OUTER_MARGIN, margin); 131 } 132 133 public static Insets getOuterMargin(JTextField buddyField) { 134 return (Insets) buddyField.getClientProperty(OUTER_MARGIN); 135 } 136 137 public static void ensureBuddiesAreInComponentHierarchy(JTextField textField) { 138 for (Component c : BuddySupport.getLeft(textField)) { 139 addToComponentHierarchy(c, Position.LEFT, textField); 140 } 141 for (Component c : BuddySupport.getRight(textField)) { 142 addToComponentHierarchy(c, Position.RIGHT, textField); 143 } 144 } 145 146 /** 147 * Create a gap to insert between to buddies. 148 * 149 * @param width 150 * @return 151 */ 152 public static Component createGap(int width) { 153 return Box.createHorizontalStrut(width); 154 } 155}