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