Main Page | Packages | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

FittedComboBoxRenderer.java

Go to the documentation of this file.
00001 /*
00002  * FittedComboBoxRenderer.java
00003  *
00004  * Copyright (C) 2005 Project SQUID, http://www.cs.helsinki.fi/group/squid/
00005  *
00006  * This file is part of Ikayaki.
00007  *
00008  * Ikayaki is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * Ikayaki is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with Ikayaki; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00021  */
00022 
00023 package ikayaki.gui;
00024 
00025 import javax.swing.*;
00026 import javax.swing.plaf.basic.BasicComboBoxRenderer;
00027 import java.awt.*;
00028 
00035 class FittedComboBoxRenderer extends BasicComboBoxRenderer {
00036 
00037     private JComponent fitToComponent;
00038     private int fitLimit = -1;
00039 
00040     private String delimiter;
00041     private String delimiterRegexp;
00042 
00050     public FittedComboBoxRenderer(JComponent fitToComponent) {
00051         if (fitToComponent == null) {
00052             throw new NullPointerException();
00053         }
00054         this.fitToComponent = fitToComponent;
00055         this.delimiter = "\\";
00056         this.delimiterRegexp = "\\\\";
00057     }
00058 
00068     public FittedComboBoxRenderer(JComponent fitToComponent, String delimiter, String regexp) {
00069         if (fitToComponent == null || delimiter == null || regexp == null) {
00070             throw new NullPointerException();
00071         }
00072         this.fitToComponent = fitToComponent;
00073         this.delimiter = delimiter;
00074         this.delimiterRegexp = regexp;
00075     }
00076 
00080     public int getFitLimit() {
00081         return fitLimit;
00082     }
00083 
00089     public void setFitLimit(int fitLimit) {
00090         this.fitLimit = fitLimit;
00091     }
00092 
00093     @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
00094                                                             boolean cellHasFocus) {
00095         JLabel comp = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
00096         if (fitLimit >= 0) {
00097             fitValue(value, fitLimit);
00098         } else {
00099             fitValue(value);
00100         }
00101         return comp;
00102     }
00103 
00112     public int fitValue(Object value) {
00113         return fitValue(value, -1);
00114     }
00115 
00124     public int fitValue(Object value, int fitLimit) {
00125         int maxWidth = fitToComponent.getWidth();
00126         int fitCount = 0;
00127 
00128         // set the text and split it
00129         this.setText(value.toString());
00130         String[] text = value.toString().split(delimiterRegexp);
00131         if (text.length < 3) {
00132             return 0;               // unable to chop any smaller
00133         }
00134         if (fitLimit < 0) {
00135             // autodetecting enabled
00136             if (maxWidth > this.getPreferredSize().width) {
00137                 return 0;           // it already fits
00138             }
00139         } else if (fitLimit == 0) {
00140             return 0;               // forbidden to chop any smaller
00141         }
00142 
00143         // take out parts of the text it until it fits
00144         boolean shortenMore = true;
00145         while (shortenMore) {
00146             shortenMore = false;    // stop the loop, unless somebody tells us to continue
00147 
00148             if (fitLimit >= 0) {
00149                 // take the specified number of parts out of the text
00150                 for (int i = 1; i < text.length - 1 && fitLimit > 0; i++, fitLimit--) {
00151                     text[i] = null;
00152                     fitCount++;
00153                 }
00154             } else {
00155                 // take out one part of the text at a time
00156                 for (int i = 1; i < text.length - 1; i++) {
00157                     if (text[i] != null) {
00158                         text[i] = null;
00159                         shortenMore = true;     // try again if it doesn't fit
00160                         fitCount++;
00161                         break;
00162                     }
00163                 }
00164             }
00165 
00166             // put the text together
00167             String result = text[0] + delimiter + "...";
00168             for (int i = 1; i < text.length; i++) {
00169                 if (text[i] != null) {
00170                     result += delimiter + text[i];
00171                 }
00172             }
00173 
00174             // try if it fits
00175             this.setText(result);
00176             if (maxWidth > this.getPreferredSize().width) {
00177                 shortenMore = false;
00178             }
00179         }
00180         return fitCount;
00181     }
00182 }

Generated on Fri May 6 16:00:31 2005 for Squid by  doxygen 1.4.1