/* This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV This program is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, see http://www.gnu.org/licenses or write to the Free Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ package com.servoy.j2db.preference; import java.awt.BorderLayout; import java.awt.Font; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.net.URL; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.LookAndFeel; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UIManager.LookAndFeelInfo; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.plaf.metal.MetalLookAndFeel; import com.servoy.j2db.IApplication; import com.servoy.j2db.gui.JFontChooser; import com.servoy.j2db.smart.J2DBClient; import com.servoy.j2db.smart.WebStart; import com.servoy.j2db.util.PersistHelper; import com.servoy.j2db.util.Settings; import com.servoy.j2db.util.SortedList; import com.servoy.j2db.util.StringComparator; import com.servoy.j2db.util.Utils; import com.servoy.j2db.util.gui.IPropertyEditorDialog; /** * Panel to show Look and Feel preferences in the SmartClient * * @author jcompagner */ public class LFPreferencePanel extends PreferencePanel implements ItemListener, ActionListener { private final IApplication _application; private DefaultComboBoxModel _dcbm; private LookAndFeelInfo _current; private JLabel _errorLabel; private Font _selectedFont; private Font _choosenFont; private Map themes; private JComboBox lnfBox; private JComboBox themesBox; private JButton fontButton; private ChangeListener listener; private boolean changed = false; public LFPreferencePanel(IApplication app) { super(); _application = app; createUI(); } private void createUI() { setLayout(new BorderLayout()); List lafs = _application.getLAFManager().getLAFInfos(_application); _dcbm = new DefaultComboBoxModel(); _dcbm.addElement(new LookAndFeelInfoWrapper(null)); String sCurrent = UIManager.getLookAndFeel().getClass().getName(); String sSystemLAF = UIManager.getSystemLookAndFeelClassName(); Iterator it = lafs.iterator(); while (it.hasNext()) { LookAndFeelInfo li = (LookAndFeelInfo)it.next(); _dcbm.addElement(new LookAndFeelInfoWrapper(li)); if (!sSystemLAF.equals(sCurrent) && sCurrent.equals(li.getClassName())) { _current = li; } } String font = _application.getSettings().getProperty("font"); if (WebStart.isRunningWebStart()) { URL webstartbase = _application.getServerURL(); font = _application.getSettings().getProperty(webstartbase.getHost() + webstartbase.getPort() + "_font", font); } _selectedFont = PersistHelper.createFont(font); lnfBox = new JComboBox(_dcbm); String msg = getFontButtonText(); if (msg == null) msg = _application.getI18NMessage("servoy.preference.lookandfeel.msg.undefined"); //$NON-NLS-1$ fontButton = new JButton(msg); fontButton.addActionListener(this); fontButton.setActionCommand("font"); themes = _application.getLAFManager().getLoadedThemes(_application); SortedList sl = new SortedList(StringComparator.INSTANCE); sl.add(""); //$NON-NLS-1$ Iterator th = themes.keySet().iterator(); while (th.hasNext()) { sl.add(th.next()); } DefaultComboBoxModel modelThemes = new DefaultComboBoxModel(sl.toArray()); String n = ""; //$NON-NLS-1$ if (WebStart.isRunningWebStart()) { URL webstartbase = _application.getServerURL(); n = _application.getSettings().getProperty(webstartbase.getHost() + webstartbase.getPort() + "_lnf.theme", ""); //$NON-NLS-1$ //$NON-NLS-2$ } else { n = _application.getSettings().getProperty("lnf.theme", ""); //$NON-NLS-1$//$NON-NLS-2$ } int indx = n.lastIndexOf('.'); if (indx != -1) n = n.substring(indx + 1); modelThemes.setSelectedItem(n); themesBox = new JComboBox(modelThemes); JPanel comp = new JPanel(false); comp.setLayout(new GridLayout(3, 1, J2DBClient.BUTTON_SPACING, J2DBClient.BUTTON_SPACING)); comp.add(lnfBox); comp.add(themesBox); comp.add(fontButton); if (_current != null) lnfBox.setSelectedItem(new LookAndFeelInfoWrapper(_current)); lnfBox.addItemListener(this); themesBox.addItemListener(this); JPanel label = new JPanel(false); label.setLayout(new GridLayout(3, 1, J2DBClient.BUTTON_SPACING, J2DBClient.BUTTON_SPACING)); label.add(new JLabel(_application.getI18NMessage("servoy.preference.lookandfeel.label.lnf"), SwingConstants.RIGHT)); //$NON-NLS-1$ label.add(new JLabel(_application.getI18NMessage("servoy.preference.lookandfeel.label.theme"), SwingConstants.RIGHT)); //$NON-NLS-1$ label.add(new JLabel(_application.getI18NMessage("servoy.preference.lookandfeel.label.defaultFont"), SwingConstants.RIGHT)); //$NON-NLS-1$ JPanel panel = new JPanel(false); panel.setLayout(new BorderLayout(5, 5)); panel.add(label, BorderLayout.WEST); panel.add(comp, BorderLayout.CENTER); this.add(panel, BorderLayout.NORTH); _errorLabel = new JLabel(""); //$NON-NLS-1$ this.add(_errorLabel, BorderLayout.SOUTH); } @Override public void addChangeListener(ChangeListener l) { listener = l; } private void fireChangeEvent() { changed = true; listener.stateChanged(new ChangeEvent(this)); } @Override public int getRequiredUserAction() { int retval = PreferencePanel.NO_USER_ACTION_REQUIRED; if (changed) { retval = PreferencePanel.APPLICATION_RESTART_NEEDED; } changed = false; return retval; } @Override public boolean handleCancel() { String msg = getFontButtonText(); if (msg == null) msg = _application.getI18NMessage("servoy.preference.lookandfeel.msg.undefined"); //$NON-NLS-1$ fontButton.setText(msg); if (_current != null) lnfBox.setSelectedItem(_current); String n = _application.getSettings().getProperty("lnf.theme", ""); //$NON-NLS-1$//$NON-NLS-2$ int indx = n.lastIndexOf('.'); if (indx != -1) n = n.substring(indx + 1); themesBox.setSelectedItem(n); return true; } protected String getFontButtonText() { String msg = null; if (_selectedFont != null) { String style = null; if (_selectedFont.isItalic()) style = "Italic"; if (_selectedFont.isBold()) { if (style != null) style = "Italic&Bold"; else style = "Bold"; } if (style == null) style = "Regular"; msg = _selectedFont.getFontName() + " (" + style + "," + _selectedFont.getSize() + ")"; //$NON-NLS-1$ } return msg; } @Override public String getTabName() { return _application.getI18NMessage("servoy.preference.lookandfeel.tabName"); //$NON-NLS-1$ } @Override public boolean handleOK() { boolean update = false; // If the L&F or the font size change, we need to remove all dialog bounds, // because there is a chance that the dialogs will have different sizes under the // new L&F or with the new font. If only the theme changes, there should be no // such situation. boolean removeAllBounds = false; LookAndFeelInfo selected = ((LookAndFeelInfoWrapper)lnfBox.getSelectedItem()).getLookAndFeelInfo(); String themeName = (String)themesBox.getSelectedItem(); String themeClassName = (String)themes.get(themeName); String currentTheme = _application.getSettings().getProperty("lnf.theme", ""); //$NON-NLS-1$//$NON-NLS-2$ if (_choosenFont != null && !_choosenFont.equals(_selectedFont)) { update = true; removeAllBounds = true; _selectedFont = _choosenFont; _choosenFont = null; } if (_current != selected) { update = true; removeAllBounds = true; _current = selected; } String clientPrefix = ""; if (WebStart.isRunningWebStart()) { URL webstartbase = _application.getServerURL(); clientPrefix = webstartbase.getHost() + webstartbase.getPort() + "_"; //$NON-NLS-1$ } if (themeClassName != null) { if (!themeClassName.equals(currentTheme)) { update = true; _application.getSettings().setProperty(clientPrefix + "lnf.theme", themeClassName); //$NON-NLS-1$ } } else { _application.getSettings().setProperty(clientPrefix + "lnf.theme", "");//clear $NON-NLS-1$//$NON-NLS-2$ } if (update) { String s_laf = UIManager.getSystemLookAndFeelClassName(); if (selected != null) s_laf = selected.getClassName(); if (_application.putClientProperty(LookAndFeelInfo.class.getName(), s_laf) && _application.putClientProperty(Font.class.getName(), _selectedFont)) { String c_laf = (_current == null ? "" : _current.getClassName()); _application.getSettings().setProperty(clientPrefix + "selectedlnf", c_laf); //$NON-NLS-1$ if (_selectedFont != null) { _application.getSettings().setProperty(clientPrefix + "font", PersistHelper.createFontString(_selectedFont)); //$NON-NLS-1$ } } else { _application.getSettings().setProperty(clientPrefix + "lnf.theme", currentTheme); //$NON-NLS-1$ } if (removeAllBounds) { ((Settings)_application.getSettings()).deleteAllBounds(); } } return true; } public void actionPerformed(ActionEvent evt) { if ("font".equals(evt.getActionCommand())) { fireChangeEvent(); Font fnt = _selectedFont; if (_choosenFont != null) fnt = _choosenFont; JFontChooser chooser = new JFontChooser(SwingUtilities.getWindowAncestor(LFPreferencePanel.this), fnt); int but = chooser.showDialog(SwingUtilities.getWindowAncestor(LFPreferencePanel.this), _application.getI18NMessage("servoy.preference.lookandfeel.chooseFont"), false); //$NON-NLS-1$ if (but == IPropertyEditorDialog.OK_OPTION) { _choosenFont = chooser.getSelectedFont(); if (_choosenFont != null) { JButton button = (JButton)evt.getSource(); button.setText(_choosenFont.getName() + " " + _application.getI18NMessage("servoy.preference.lookandfeel.fontsize") + _choosenFont.getSize()); //$NON-NLS-1$ } } } } public void itemStateChanged(ItemEvent e) { if (e.getSource() == lnfBox && e.getStateChange() == ItemEvent.SELECTED) { fireChangeEvent(); enableButtons(); } } private void enableButtons() { LookAndFeelInfo lafi = ((LookAndFeelInfoWrapper)lnfBox.getSelectedItem()).getLookAndFeelInfo(); boolean metalLnF = false; try { if (lafi != null) { LookAndFeel laf = _application.getLAFManager().createInstance(lafi.getClassName()); metalLnF = (laf instanceof MetalLookAndFeel); } themesBox.setEnabled(metalLnF); fontButton.setEnabled(!metalLnF); } catch (Exception e) { themesBox.setEnabled(false); fontButton.setEnabled(false); } } private class LookAndFeelInfoWrapper { private final LookAndFeelInfo info; LookAndFeelInfoWrapper(LookAndFeelInfo l) { info = l; } @Override public String toString() { if (info == null) return _application.getI18NMessage("servoy.button.default"); //$NON-NLS-1$ return Utils.stringReplace(info.getName(), "LookAndFeel", ""); } public LookAndFeelInfo getLookAndFeelInfo() { return info; } @Override public boolean equals(Object other) { if (other instanceof LookAndFeelInfoWrapper) { LookAndFeelInfoWrapper otherLAFW = (LookAndFeelInfoWrapper)other; if (info == null && otherLAFW.info == null) { return true; } if (info != null && otherLAFW.info != null && info.getClassName().equals(otherLAFW.info.getClassName())) { return true; } } return false; } } }