[Schmitzm-commits] r1759 - in trunk/schmitzm-core/src/main/java/de/schmitzm: lang swing
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Wed Oct 19 15:32:57 CEST 2011
Author: mojays
Date: 2011-10-19 15:32:56 +0200 (Wed, 19 Oct 2011)
New Revision: 1759
Added:
trunk/schmitzm-core/src/main/java/de/schmitzm/lang/ApplicationProps.java
trunk/schmitzm-core/src/main/java/de/schmitzm/swing/ApplicationFrame.java
Modified:
trunk/schmitzm-core/src/main/java/de/schmitzm/swing/SwingUtil.java
Log:
Some new utility methods moved from WIME to SwingUtil.
New frame super class ApplicationFrame.
New super class ApplicationProps.
Added: trunk/schmitzm-core/src/main/java/de/schmitzm/lang/ApplicationProps.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/lang/ApplicationProps.java 2011-10-15 18:13:01 UTC (rev 1758)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/lang/ApplicationProps.java 2011-10-19 13:32:56 UTC (rev 1759)
@@ -0,0 +1,349 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ *
+ * This file is part of the SCHMITZM library - a collection of utility
+ * classes based on Java 1.6, focusing (not only) on Java Swing
+ * and the Geotools library.
+ *
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ *
+ * Contributors:
+ * Martin O. J. Schmitz - initial API and implementation
+ * Stefan A. Tzeggai - additional utility classes
+ ******************************************************************************/
+
+package de.schmitzm.lang;
+
+import java.awt.Component;
+import java.awt.Window;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Properties;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.log4j.Logger;
+
+import de.schmitzm.swing.ExceptionDialog;
+import de.schmitzm.temp.BaseTypeUtil;
+
+/**
+ * General implementation for application properties.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ */
+public abstract class ApplicationProps<KEYS> {
+ private static final String INTERNER_FEHLER_DIE_INTERNE_EINSTELLUNGSDATEI_KONNTE_NICHT_GEFUNDEN_WERDEN = "Interner Fehler: Die interne Einstellungsdatei konnte nicht gefunden werden.";
+ private static final Logger LOGGER = Logger.getLogger(ApplicationProps.class);
+
+ /** TODO: Rethink where this "default" shall be used. */
+ public static final String DEFAULT_CHARSET_NAME = "UTF-8";
+
+ /**
+ * This stores the properties
+ */
+ private final Properties properties = new Properties();
+
+ private boolean autoSave;
+ private FileOutputStream FOS = null;
+ private boolean haveToCloseFOS = false;
+ private File propertiesFile = null;
+ private Component owner;
+
+ /**
+ * Creates a new application properties instance.
+ * @param load if <code>true</code> {@link #load()} is
+ * immediately called
+ */
+ public ApplicationProps(boolean load, boolean autoSave) {
+ setAutoSave(autoSave);
+ if ( load )
+ load();
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ synchronized (FOS) {
+ if (haveToCloseFOS) {
+ FOS.close();
+ haveToCloseFOS = false;
+ }
+ }
+ }
+
+ /**
+ * Returns a GUI-owner for error messages.
+ */
+ public Component getOwner() {
+ return owner;
+ }
+
+ /**
+ * Sets a GUI-owner for error messages.
+ */
+ public void setOwner(Window owner) {
+ this.owner = owner;
+ }
+
+ /**
+ * Returns whether the parameter file is automatically saved
+ * after each set-call.
+ */
+ public boolean getAutoSave() {
+ return autoSave;
+ }
+
+ /**
+ * Sets whether the parameter file is automatically saved
+ * after each set-call.
+ */
+ public void setAutoSave(boolean autoSave) {
+ this.autoSave = autoSave;
+ }
+
+ //***************************************************
+ //************* GETTER ******************************
+ //***************************************************
+
+ public <T> T get(KEYS key, Class<T> destType) {
+ Object value = properties.get(key.toString());
+ if ( value == null )
+ return null;
+ if ( destType != null && destType.isInstance(value) )
+ return (T)value;
+ try {
+ return BaseTypeUtil.convertFromString(value.toString(), destType);
+ } catch( Exception err ) {
+ LOGGER.warn(
+ "The property value saved for " + key
+ + " can't be converted to " + LangUtil.getSimpleClassName(destType)
+ + " Returning default value.");
+ return null;
+ }
+ }
+
+ public <T> T get(KEYS key, Class<T> destType, T defaultValue) {
+ if ( destType == null && defaultValue != null)
+ destType = (Class<T>)defaultValue.getClass();
+ T value = get(key,destType);
+ if ( value == null )
+ return defaultValue;
+ return value;
+ }
+
+ public <T> T get(KEYS key, T defaultValue) {
+ return get(key,null,defaultValue);
+ }
+
+ public Boolean getBool(KEYS key, Boolean... defaultValue) {
+ if ( defaultValue.length == 0 )
+ return get(key,Boolean.class);
+ return get(key,Boolean.class,defaultValue[0]);
+ }
+
+ public Integer getInt(KEYS key, Integer... defaultValue) {
+ if ( defaultValue.length == 0 )
+ return get(key,Integer.class);
+ return get(key,Integer.class,defaultValue[0]);
+ }
+
+ public Double getDouble(KEYS key, Double... defaultValue) {
+ if ( defaultValue.length == 0 )
+ return get(key,Double.class);
+ return get(key,Double.class,defaultValue[0]);
+ }
+
+ public String getString(KEYS key, String... defaultValue) {
+ if ( defaultValue.length == 0 )
+ return get(key,String.class);
+ return get(key,String.class,defaultValue[0]);
+ }
+
+ //***************************************************
+ //************* SETTER ******************************
+ //***************************************************
+ /**
+ * Set the value in the underlying {@link Properties}
+ * and store it.
+ */
+ public void set(KEYS key, Object value) {
+ properties.setProperty(key.toString(), value.toString());
+ if ( getAutoSave() )
+ store();
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// Property storage //////////////////
+ /////////////////////////////////////////////////////
+ /**
+ * Returns a default properties file copied to
+ * user home if no such file already exists.
+ */
+ public abstract URL getDefaultPropertiesFile();
+
+ /**
+ * Returns the name of the folder in the user home,
+ * where the properties file is stored.
+ */
+ public abstract String getPropertiesFolderName();
+
+ /**
+ * Returns the name of the file in the user home,
+ * where the properties are stored in.
+ */
+ public abstract String getPropertiesFilename();
+
+ /**
+ * Returns a description which is added to the top of
+ * the properties file.
+ */
+ public abstract String getPropertiesFileDescription();
+
+ /**
+ * Returns the directory the user properties file is
+ * stored in.
+ */
+ public File getApplicationPropertiesDir() {
+ File applicationPropertiesDirectory = new File(new File(
+ System.getProperty("user.home")), getPropertiesFolderName());
+ if (!applicationPropertiesDirectory.exists())
+ applicationPropertiesDirectory.mkdirs();
+ return applicationPropertiesDirectory;
+ }
+
+ /**
+ * Returns the user properties file.
+ */
+ protected File getPropertiesFile() {
+ if (propertiesFile == null) {
+ File applicationPropertiesDirectory = getApplicationPropertiesDir();
+ propertiesFile = new File(applicationPropertiesDirectory,
+ getPropertiesFilename());
+
+ if (!propertiesFile.exists()) {
+ resetProperties();
+ } else {
+ FileInputStream inStream = null;
+ try {
+ inStream = new FileInputStream(getPropertiesFile());
+ properties.load(inStream);
+ } catch (Exception e) {
+ ExceptionDialog.show(null, e);
+ } finally {
+ if (inStream != null)
+ try {
+ inStream.close();
+ } catch (IOException ioe) {
+ LOGGER.error("Unable to close FileInputStream of "
+ + getPropertiesFile(), ioe);
+ }
+ }
+ }
+ }
+ return propertiesFile;
+ }
+
+ /**
+ * Loads the properties from the file.
+ * @see #getPropertiesFile()
+ */
+ public void load() {
+ /**
+ * It is not a problem if the propertiesFile for the can't
+ * be loaded
+ */
+ try {
+ properties.load(new FileInputStream(getPropertiesFile()));
+ } catch (FileNotFoundException e) {
+ } catch (IOException e) {
+ LOGGER.error(e);
+ }
+ }
+
+ /**
+ * Deletes the .properties in the ApplicationPreferences directory and
+ * creates a default .properties file
+ *
+ * @param guiOwner
+ * If not <code>null</code> a JDialog message will inform the
+ * user.
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ */
+ public void resetProperties() {
+ // Create the new one
+ // e.printStackTrace();
+ LOGGER.info("Resetting " + getPropertiesFile().getAbsolutePath());
+ // If we don't have a .properties file, we copy the one from the jar
+ URL inJar = null;
+ try {
+ inJar = getDefaultPropertiesFile();
+ // LOGGER.debug("inJar = " + inJar);
+ if (inJar == null)
+ throw new RuntimeException(
+ INTERNER_FEHLER_DIE_INTERNE_EINSTELLUNGSDATEI_KONNTE_NICHT_GEFUNDEN_WERDEN);
+ FileUtils.copyURLToFile(inJar, getPropertiesFile());
+ /**
+ * After creating the new default file, we may not forget to read it
+ * ;-)
+ */
+ properties.load(new FileInputStream(getPropertiesFile()));
+ } catch (final IOException e1) {
+ if (getOwner() != null) {
+ ExceptionDialog.show(getOwner(), e1);
+ } else {
+ LOGGER.error(
+ INTERNER_FEHLER_DIE_INTERNE_EINSTELLUNGSDATEI_KONNTE_NICHT_GEFUNDEN_WERDEN,
+ e1);
+ }
+ }
+ // Create the new one
+ // LOGGER.error(e);
+ LOGGER.info("Resetting " + getPropertiesFile().getAbsolutePath());
+ // Delete the old one
+ getPropertiesFile().delete();
+ store();
+ }
+
+
+ /**
+ * Save the changes to the .properties file
+ */
+ public void store() {
+ // LOGGER.debug("STORE AS PROPS");
+ try {
+ FOS = new FileOutputStream(getPropertiesFile());
+ haveToCloseFOS = true;
+
+ properties.store(FOS,getPropertiesFileDescription());
+ } catch (IOException e) {
+ LOGGER.error("Can't write to " + getPropertiesFile().toString(), e);
+ } finally {
+ if (haveToCloseFOS)
+ try {
+ FOS.close();
+ haveToCloseFOS = false;
+ } catch (IOException e) {
+ LOGGER.error("Can't close FOS!", e);
+ ExceptionDialog.show(getOwner(), e);
+ }
+ }
+ }
+}
Added: trunk/schmitzm-core/src/main/java/de/schmitzm/swing/ApplicationFrame.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/swing/ApplicationFrame.java 2011-10-15 18:13:01 UTC (rev 1758)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/swing/ApplicationFrame.java 2011-10-19 13:32:56 UTC (rev 1759)
@@ -0,0 +1,135 @@
+package de.schmitzm.swing;
+
+import java.awt.AWTEvent;
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.Action;
+import javax.swing.BorderFactory;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JMenuBar;
+
+import de.schmitzm.swing.menu.ToolBarsPanel;
+
+/**
+ * Super class for a main application frame with {@link BorderLayout},
+ * which contains
+ * <ul>
+ * <li>an (empty) {@link JMenuBar}</li>
+ * <li>an (empty) {@link #toolBarsPanel} at {@link BorderLayout#NORTH}</li>
+ * <li>a status label at {@link BorderLayout#SOUTH}</li>
+ * </ul>
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ *
+ */
+public abstract class ApplicationFrame extends JFrame {
+ /** Holds the main content pane. */
+ protected Container contentPane = null;
+ /** Holds a panel, which can contain several tool bars.
+ * @see BorderLayout#NORTH */
+ protected ToolBarsPanel toolBarsPanel = null;
+ /** Global action listener, calling {@link #performAction(ActionEvent)}
+ * which can be used for the frame actions. */
+ protected ActionListener menuActionListener;
+ /** Holds the status bar on the bottom of the frame.
+ * @see BorderLayout#SOUTH */
+ protected JLabel statusBar = null;
+
+ /**
+ * Creates a new frame.
+ */
+ public ApplicationFrame() {
+ this(null);
+ }
+
+ /**
+ * Creates a new frame.
+ * @param title frame title
+ */
+ public ApplicationFrame(String title) {
+ this(title,true);
+ }
+
+ /**
+ * Creates a new frame.
+ * @param title frame title
+ * @param pack indicates whether {@link #pack()} is called
+ */
+ protected ApplicationFrame(String title, boolean pack) {
+ super(title);
+ contentPane = getContentPane();
+ contentPane.setLayout(new BorderLayout());
+
+ setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
+ enableEvents(AWTEvent.WINDOW_EVENT_MASK);
+
+ JPanel statusContainer = new JPanel(new BorderLayout());
+ statusContainer.setBorder(BorderFactory.createLoweredBevelBorder());
+ this.statusBar = new JLabel(" ");
+ this.statusBar.setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 5));
+ statusContainer.add(statusBar, BorderLayout.CENTER);
+ contentPane.add(statusContainer, BorderLayout.SOUTH);
+
+ this.toolBarsPanel = new ToolBarsPanel();
+ contentPane.add(toolBarsPanel, BorderLayout.NORTH);
+
+ this.setJMenuBar( new JMenuBar() );
+ this.menuActionListener = new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ performAction(e);
+ }
+ };
+
+ initActions();
+ updateActions();
+
+ if( pack )
+ pack();
+ }
+
+ /**
+ * Creates an {@link Action} which uses the global {@link #menuActionListener}.
+ * @param title action title
+ * @param commandID command id
+ * @param desc action description for tooltip
+ * @param icon icon for buttons or menues
+ */
+ protected Action createAction(String title, String commandID, String desc, Icon icon) {
+ return SwingUtil.createAction(title, this.menuActionListener, commandID, desc, icon);
+ }
+
+ /**
+ * Creates an {@link Action} which uses the global {@link #menuActionListener}.
+ * @param title action title
+ * @param commandID command id
+ * @param desc action description for tooltip
+ * @param iconName name of icon file for buttons or menues (icon must be located
+ * under {@code 'resource/icons/small/..'} in {@link SwingUtil} resource path)
+ */
+ protected Action createAction(String title, String commandID, String desc, String iconName) {
+ String iconPath = "resource/icons/small/"+iconName;
+ ImageIcon icon = SwingUtil.createImageIconFromResourcePath(iconPath, null);
+ return SwingUtil.createAction(title, this.menuActionListener, commandID, desc, icon);
+ }
+
+ /**
+ * Initializes the actions, menu entries and tool bars.
+ */
+ protected abstract void initActions();
+
+ /**
+ * Can be called to update the enable state of the
+ * actions.
+ */
+ public abstract void updateActions();
+
+ /**
+ * Called by the {@link #menuActionListener}.
+ */
+ protected abstract void performAction(ActionEvent e);
+}
Modified: trunk/schmitzm-core/src/main/java/de/schmitzm/swing/SwingUtil.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/swing/SwingUtil.java 2011-10-15 18:13:01 UTC (rev 1758)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/swing/SwingUtil.java 2011-10-19 13:32:56 UTC (rev 1759)
@@ -47,6 +47,7 @@
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.io.File;
@@ -68,10 +69,13 @@
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
+import javax.swing.Action;
import javax.swing.CellEditor;
import javax.swing.DefaultCellEditor;
+import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
+import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFormattedTextField;
@@ -86,6 +90,8 @@
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
+import javax.swing.JToggleButton;
+import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
@@ -1625,7 +1631,72 @@
return DUMMY_LABEL.getBackground();
}
- /**
+ /**
+ * Creates a menu item.
+ *
+ * @param title
+ * title for the menu item
+ * @param actionListener
+ * listener to perform the action
+ * @param commandID
+ * identifies the action in the action listener (if the listener
+ * is used for multiple actions)
+ * @param desc
+ * optional (tooltip) description
+ * @param icon
+ * optional icon
+ */
+ public static Action createAction(String title,
+ final ActionListener actionListener, String commandID, String desc,
+ Icon icon) {
+ AbstractAction action = new AbstractAction(title) {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ actionListener.actionPerformed(e);
+ }
+ };
+ action.putValue(Action.ACTION_COMMAND_KEY, commandID);
+ if (desc != null) {
+ action.putValue(Action.LONG_DESCRIPTION, desc);
+ action.putValue(Action.SHORT_DESCRIPTION, desc);
+ }
+ if (icon != null)
+ action.putValue(Action.SMALL_ICON, icon);
+ return action;
+ }
+
+ /**
+ * Creates a checkbox menu item for an action.
+ */
+ public static JCheckBoxMenuItem createCheckboxMenuItem(Action action, boolean selected) {
+ action.putValue(AbstractAction.SELECTED_KEY, selected);
+ JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(action);
+ return menuItem;
+ }
+
+ /**
+ * Creates a {@link JToggleButton} for the use in a {@link JToolBar}.
+ * Regardless of the {@linkplain AbstractAction#NAME action name},
+ * the button will only show the icon.
+ */
+ public static JToggleButton createToggleToolbarButton(Action action, boolean selected) {
+ action.putValue(AbstractAction.SELECTED_KEY, selected);
+ return createToggleToolbarButton(action);
+ }
+
+ /**
+ * Creates a {@link JToggleButton} for the use in a {@link JToolBar}.
+ * Regardless of the {@linkplain AbstractAction#NAME action name},
+ * the button will only show the icon.
+ */
+ public static JToggleButton createToggleToolbarButton(Action action) {
+ JToggleButton button = new JToggleButton(action);
+ if ( button.getIcon() != null )
+ button.setText(null);
+ return button;
+ }
+
+ /**
* Create a {@link JMenu} that allows to switch the Log-Level of the root
* logger.
*/
More information about the Schmitzm-commits
mailing list