001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2009 Sun Microsystems, Inc. 025 * Portions Copyright 2015 ForgeRock AS. 026 */ 027package org.opends.guitools.controlpanel.ui.components; 028 029import javax.swing.text.AttributeSet; 030import javax.swing.text.BadLocationException; 031import javax.swing.text.DocumentFilter; 032import javax.swing.text.JTextComponent; 033 034/** 035 * Document filter used to update properly a text component displaying a 036 * time. 037 */ 038public class TimeDocumentFilter extends DocumentFilter 039{ 040 private JTextComponent tf; 041 042 /** 043 * Constructor. 044 * @param tf the text component associated with the document. 045 */ 046 public TimeDocumentFilter(JTextComponent tf) 047 { 048 this.tf = tf; 049 } 050 051 /** {@inheritDoc} */ 052 public void insertString(DocumentFilter.FilterBypass fb, int offset, 053 String text, AttributeSet attr) 054 throws BadLocationException 055 { 056 int previousLength = fb.getDocument().getLength(); 057 fb.insertString(offset, text.replaceAll("[^0-9]", ""), attr); 058 trimPosition(fb, text, offset, previousLength); 059 } 060 061 /** {@inheritDoc} */ 062 public void remove(DocumentFilter.FilterBypass fb, int offset, 063 int length) 064 throws BadLocationException 065 { 066 String text = fb.getDocument().getText(offset, length); 067 int index = text.indexOf(":"); 068 if (index == -1) 069 { 070 fb.remove(offset, length); 071 } 072 else 073 { 074 // index value is relative to offset 075 if (index > 0) 076 { 077 fb.remove(offset, index); 078 } 079 if (index < length - 1) 080 { 081 fb.remove(offset + index + 1, length - index -1); 082 } 083 } 084 updateCaretPosition(fb); 085 } 086 087 /** {@inheritDoc} */ 088 public void replace(DocumentFilter.FilterBypass fb, int offset, 089 int length, String text, AttributeSet attr) 090 throws BadLocationException 091 { 092 int previousLength = fb.getDocument().getLength(); 093 094 String t = fb.getDocument().getText(offset, length); 095 int index = t.indexOf(":"); 096 fb.replace(offset, length, text.replaceAll("[^0-9]", ""), attr); 097 if (index != -1) 098 { 099 if (fb.getDocument().getLength() >= 2) 100 { 101 fb.insertString(2, ":", attr); 102 } 103 else 104 { 105 fb.insertString(fb.getDocument().getLength(), ":", attr); 106 } 107 } 108 109 trimPosition(fb, text, offset, previousLength); 110 } 111 112 private void trimPosition(DocumentFilter.FilterBypass fb, String newText, 113 int offset, int previousLength) 114 throws BadLocationException 115 { 116 String allText = 117 fb.getDocument().getText(0, fb.getDocument().getLength()); 118 int index = allText.indexOf(':'); 119 if (index != -1 && newText.length() == 1) 120 { 121 int minuteLength = allText.length() - index - 1; 122 int hourLength = index; 123 124 if (minuteLength > 2 || hourLength > 2) 125 { 126 if (offset < previousLength) 127 { 128 fb.remove(offset + 1, 1); 129 } 130 else 131 { 132 fb.remove(previousLength, 1); 133 } 134 } 135 } 136 updateCaretPosition(fb); 137 } 138 139 private void updateCaretPosition(DocumentFilter.FilterBypass fb) 140 throws BadLocationException 141 { 142 String allText = 143 fb.getDocument().getText(0, fb.getDocument().getLength()); 144 int index = allText.indexOf(':'); 145 if (index != -1) 146 { 147 int minuteLength = allText.length() - index - 1; 148 int hourLength = index; 149 int caretPosition = tf.getCaretPosition(); 150 151 if (minuteLength >= 2 && 152 caretPosition == allText.length()) 153 { 154 tf.setCaretPosition(0); 155 } 156 else if (hourLength == caretPosition) 157 { 158 if (hourLength >= 2) 159 { 160 tf.setCaretPosition(3); 161 } 162 else if (hourLength == 1) 163 { 164 char c = allText.charAt(0); 165 if (c != '0' && c != '1' && c != '2') 166 { 167 tf.setCaretPosition(2); 168 } 169 } 170 } 171 else if (hourLength + 1 == caretPosition) 172 { 173 if (hourLength == 1) 174 { 175 char c = allText.charAt(0); 176 if (c == '0' || c == '1' || c == '2') 177 { 178 tf.setCaretPosition(caretPosition - 1); 179 } 180 } 181 else if (hourLength == 0) 182 { 183 tf.setCaretPosition(caretPosition - 1); 184 } 185 } 186 } 187 if (allText.length() == 1) 188 { 189 tf.setCaretPosition(0); 190 } 191 } 192}