001: /*
002: * Created on 20/03/2004
003: *
004: * Swing Components - visit http://sf.net/projects/gfd
005: *
006: * Copyright (C) 2004 Igor Regis da Silva Simões
007: *
008: * This program is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public License
010: * as published by the Free Software Foundation; either version 2
011: * of the License, or (at your option) any later version.
012: *
013: * This program is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public License
019: * along with this program; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
021: *
022: */
023: package br.com.gfpshare.plaf.util;
024:
025: import java.awt.Component;
026: import java.io.File;
027: import java.io.FileInputStream;
028: import java.io.FileOutputStream;
029: import java.io.IOException;
030: import java.net.MalformedURLException;
031: import java.net.URL;
032: import java.util.ArrayList;
033: import java.util.Enumeration;
034: import java.util.Properties;
035:
036: import javax.swing.LookAndFeel;
037: import javax.swing.SwingUtilities;
038: import javax.swing.UIManager;
039: import javax.swing.UnsupportedLookAndFeelException;
040: import javax.swing.UIManager.LookAndFeelInfo;
041: import javax.swing.plaf.metal.MetalLookAndFeel;
042: import javax.swing.plaf.metal.MetalTheme;
043:
044: import br.com.gfpshare.plugin.core.DynamicClassLoader;
045: import br.com.gfpshare.util.FileManager;
046: import br.com.gfpshare.util.MyFileFilter;
047:
048: import com.l2fprod.gui.plaf.skin.Skin;
049: import com.l2fprod.gui.plaf.skin.SkinLookAndFeel;
050:
051: /**
052: *
053: * @author Igor Regis da Silva Simões
054: */
055: public class LookAndFeelLoader {
056: /**
057: * Instância única
058: */
059: private static LookAndFeelLoader plafLoader = null;
060:
061: /**
062: * String com o caminho do diretório onde estão os LookAndFeels a serem carregados
063: */
064: private String lookAndFeelDiretorio = null;
065:
066: /**
067: * Coleção de themes para o LookAndFeel metal
068: */
069: private MetalTheme[] themes = null;
070:
071: /**
072: * Creates a new instance of LookAndFeelLoader
073: */
074: private LookAndFeelLoader() {
075: //Não fazemos nada
076: }
077:
078: /**
079: * Retorna uma instancia de LookAndFeelLoader
080: * @return LookAndFeelLoader
081: */
082: public static final LookAndFeelLoader getLookAndFeelLoader() {
083: if (plafLoader == null)
084: plafLoader = new LookAndFeelLoader();
085: return plafLoader;
086: }
087:
088: /**
089: * Retorna uma string com o caminho completo para o diretorio onde encontram-se os LookAndFeel a serem carregados
090: * @return string.
091: */
092: public String getLookAndFeelDiretorio() {
093: return lookAndFeelDiretorio;
094: }
095:
096: /**
097: * Determina o caminho completo para o diretorio onde encontram-se os LookAndFeel a serem carregados
098: * @param LookAndFeelDiretorio String com o caminho para o diretório
099: */
100: public void setLookAndFeelDiretorio(String LookAndFeelDiretorio) {
101: this .lookAndFeelDiretorio = LookAndFeelDiretorio;
102: loadLookAndFeels();
103: }
104:
105: /**
106: * Retorna o nome de todos os LookAndFeel´s já instalados
107: * @return Array de strings com os nomes
108: */
109: public String[] getLookAndFeelInstalados() {
110: LookAndFeelInfo[] info = UIManager.getInstalledLookAndFeels();
111: String[] temp = new String[info.length];
112:
113: for (int i = 0; i < info.length; i++) {
114: temp[i] = info[i].getName();
115: }
116:
117: return temp;
118: }
119:
120: /**
121: * Instala todos os LookAndFeel disponíveis
122: */
123: private void loadLookAndFeels() {
124: Object[] lookAndFeels = FileManager.lsMenosR(
125: this .lookAndFeelDiretorio, "LookAndFeel.class");
126:
127: for (int i = 0; i < lookAndFeels.length; i++) {
128: String lookAndFeeldir = lookAndFeels[i].toString();
129:
130: int inicio = lookAndFeeldir.toLowerCase().indexOf(
131: this .lookAndFeelDiretorio)
132: + this .lookAndFeelDiretorio.length() + 2;
133: int fim = lookAndFeeldir.indexOf("LookAndFeel");
134:
135: String lookandfeelName = lookAndFeeldir
136: .replace('\\', '.')
137: .substring(inicio, lookAndFeeldir.indexOf(".class"));
138: UIManager.installLookAndFeel(lookAndFeeldir.substring(
139: lookAndFeeldir.lastIndexOf('\\') + 1, fim),
140: lookandfeelName);
141: }
142: }
143:
144: /**
145: * Seta o theme para um LookAndFeel metal
146: * @param lookAndFeelName Nome do LookAndFeel
147: * @param themeName Nome do thema a ser aplicado
148: * @param c Componente root da aplicação
149: * @throws ClassNotFoundException
150: */
151: public void setMetalTheme(String lookAndFeelName, String themeName,
152: Component c) throws ClassNotFoundException {
153: setLookAndFeel(lookAndFeelName, c);
154: if (themes == null)
155: getMetalThemes();
156:
157: for (int i = 0; i < themes.length; i++)
158: if (themes[i].getName().equals(themeName))
159: MetalLookAndFeel.setCurrentTheme(themes[i]);
160: try {
161: UIManager.setLookAndFeel(UIManager.getLookAndFeel());
162: } catch (UnsupportedLookAndFeelException ule) {
163: //TODO Exceção
164: }
165:
166: SwingUtilities.updateComponentTreeUI(c);
167: }
168:
169: /**
170: * Seta o LookAndFeel corrente de uma aplicação
171: * @param lookAndFeelName Nome do LookAndFeel a ser aplicado
172: * @param c Componente root do sistema
173: * @throws ClassNotFoundException
174: */
175: public void setLookAndFeel(String lookAndFeelName, Component c)
176: throws ClassNotFoundException {
177: String lookAndFeel = null;
178: Class classeLookAndFeel = null;
179:
180: LookAndFeelInfo[] info = UIManager.getInstalledLookAndFeels();
181:
182: for (int i = 0; i < info.length; i++)
183: if (info[i].getName().equals(lookAndFeelName))
184: lookAndFeel = info[i].getClassName();
185:
186: if (lookAndFeel == null)
187: throw new ClassNotFoundException("LookAndFeel "
188: + lookAndFeelName + " não encontrado.");
189:
190: classeLookAndFeel = DynamicClassLoader.getClassLoader()
191: .loadClass(lookAndFeel);
192:
193: try {
194: LookAndFeel plaf = (LookAndFeel) classeLookAndFeel
195: .newInstance();
196: if (classeLookAndFeel.getSimpleName().indexOf(
197: "SkinLookAndFeel") != -1)
198: try {
199: SkinLookAndFeel.getSkin();
200: } catch (Throwable t) {
201: setSkinTheme("aqua", c);
202: }
203: UIManager.setLookAndFeel(plaf);
204: UIManager.setInstalledLookAndFeels(info);
205: SwingUtilities.updateComponentTreeUI(c);
206: } catch (UnsupportedLookAndFeelException ule) {
207: ule.printStackTrace();
208: } catch (InstantiationException ie) {
209: ie.printStackTrace();
210: } catch (Exception e) {
211: e.printStackTrace();
212: }
213: try {
214: setAsDefault(lookAndFeelName);
215: } catch (IOException e) {
216: // TODO excecao
217: }
218: }
219:
220: private void setAsDefault(String lookAndFeel) throws IOException {
221: File filePath = new File(System.getProperty("user.dir")
222: + File.separator + "laf.conf");
223: Properties file = new Properties();
224: FileOutputStream fos = new FileOutputStream(filePath);
225: file.setProperty("laf", lookAndFeel);
226: file.store(fos, null);
227: fos.close();
228: }
229:
230: private String getDefaultLookAndFeel() {
231: File filePath = new File(System.getProperty("user.dir")
232: + File.separator + "laf.conf");
233: Properties file = new Properties();
234: FileInputStream fis;
235: try {
236: fis = new FileInputStream(filePath);
237: file.load(fis);
238: fis.close();
239: return file.getProperty("laf");
240: } catch (IOException e) {
241: //Fazemos nada
242: }
243: return "Metal";
244: }
245:
246: public void loadDefaultLAF(Component c)
247: throws ClassNotFoundException {
248: setLookAndFeel(getDefaultLookAndFeel(), c);
249: }
250:
251: /**
252: * Retorna o conteúdo do diretorio de lookAndFeel como um array de URL´s
253: * @return Array de URL´s
254: */
255: public URL[] getLookAndFeelClassPath() {
256: File[] lookAndFeelFile = (new File(this .lookAndFeelDiretorio))
257: .listFiles(new MyFileFilter("jar"));
258:
259: URL[] classPath = new URL[lookAndFeelFile.length];
260:
261: for (int i = 0; i < lookAndFeelFile.length; i++)
262: try {
263: classPath[i] = lookAndFeelFile[i].toURL();
264: } catch (MalformedURLException mue) {
265: //TODO Exceção
266: }
267: return classPath;
268: }
269:
270: /**
271: * Reorna os Themes de Metal instalados.
272: * @return Array contendo os MetalThemes
273: */
274: public MetalTheme[] getMetalThemes() {
275: //Lista de temas
276: ArrayList listaDeTemas = new ArrayList();
277:
278: //este trecho serve para pegar os Temas quye estiverem no classpath dinamico
279: Enumeration temas = null;
280: temas = DynamicClassLoader
281: .getSystemResourcesEndingWith("Theme.class");
282:
283: //Passamos os nomes dos temas para um ArrayList
284: while (temas.hasMoreElements()) {
285: listaDeTemas.add(temas.nextElement());
286: }
287:
288: //Agora vamos tentar instanaciar cada tema passado e adicionamos a um array temporario de MetalThemes.
289: //Caso de erro nós ignoramos o tema.
290: MetalTheme[] temasTemp = new MetalTheme[listaDeTemas.size()];
291: int n = 0;
292: for (int j = 0; j < listaDeTemas.size(); j++, n++) {
293: String nomeClasse = listaDeTemas.get(j).toString();
294: //Os temas podem estar dentro...
295: if (nomeClasse.startsWith("jar")) {
296: nomeClasse = nomeClasse.substring(
297: nomeClasse.indexOf('!') + 2,
298: nomeClasse.indexOf(".class")).replace('/', '.');
299: }//ou fora de jar files
300: else {
301: nomeClasse = nomeClasse.substring(0,
302: nomeClasse.indexOf(".class"))
303: .replace('\\', '.');
304: }
305: //Tentamos instanciar o tema
306: try {
307: temasTemp[n] = (MetalTheme) Class.forName(nomeClasse)
308: .newInstance();
309: } catch (Exception e2) {
310: n--;
311: }
312: }
313:
314: //Aqui nós carregamos os temas padrao da aplicação
315: if (themes != null)
316: return themes;
317: if (System.getProperty("java.vm.version").indexOf("1.5") != -1)
318: themes = new MetalTheme[2 + n];// n = numero de temas carregados dinamicamente
319: else
320: themes = new MetalTheme[1 + n];
321: try {
322: int i = 0;
323: themes[i++] = (MetalTheme) Class.forName(
324: "javax.swing.plaf.metal.DefaultMetalTheme")
325: .newInstance();
326: if (System.getProperty("java.vm.version").indexOf("1.5") != -1)
327: themes[i++] = (MetalTheme) Class.forName(
328: "javax.swing.plaf.metal.OceanTheme")
329: .newInstance();
330:
331: for (int j = 0; j < n; j++, i++) {
332: themes[i] = temasTemp[j];
333: }
334: } catch (Exception e) {
335: //TODO Excecao
336: e.printStackTrace();
337: }
338:
339: return themes;
340: }
341:
342: /**
343: * Retorna os nomes de todos os temas do lookAndFeel Skin instalados.
344: * @return String[] com os nomes dos temas
345: */
346: public String[] getSkinThemeNames() {
347:
348: Object[] temas = FileManager.lsMenosR(
349: getLookAndFeelDiretorio(), "themepack.zip");
350: String[] nomes = new String[temas.length];
351:
352: for (int i = 0; i < temas.length; i++) {
353: String nome = new File(temas[i].toString()).getName();
354: nomes[i] = nome.substring(0, nome.indexOf("themepack.zip"));
355: }
356: return nomes;
357: }
358:
359: /**
360: * Seta o theme para um LookAndFeel Skin
361: * @param themeName Nome do thema a ser aplicado
362: * @param c Componente root da aplicação
363: * @throws Exception
364: */
365: public void setSkinTheme(String themeName, Component c)
366: throws Exception {
367: String[] temas = getSkinThemeNames();
368:
369: for (int i = 0; i < temas.length; i++) {
370: if (temas[i].equals(themeName)) {
371: Skin theSkinToUse = SkinLookAndFeel
372: .loadThemePack(getLookAndFeelDiretorio()
373: + File.separator + themeName
374: + "themepack.zip");
375: SkinLookAndFeel.setSkin(theSkinToUse);
376: }
377: }
378: setLookAndFeel("Skin", c);
379: }
380: }
|