/* * Open Source Physics software is free software as described near the bottom of this code file. * * For additional information and documentation on Open Source Physics please see: * <http://www.opensourcephysics.org/> */ package org.opensourcephysics.controls; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.logging.Level; import javax.swing.ButtonGroup; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JRadioButtonMenuItem; import javax.swing.JScrollPane; import javax.swing.JTextPane; import javax.swing.SwingUtilities; import javax.swing.WindowConstants; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.Style; import javax.swing.text.StyleConstants; import javax.swing.text.StyleContext; import org.opensourcephysics.tools.ToolsRes; /** * MessageFrame displays text messages. * * The static MessageFrame object displays logger messages when a program is run as a applet. * * @author W. Christian * @version 1.0 */ public class MessageFrame extends JFrame { static final Color DARK_GREEN = new Color(0, 128, 0), DARK_BLUE = new Color(0, 0, 128), DARK_RED = new Color(128, 0, 0); static Style black, red, blue, green, magenta, gray; static volatile MessageFrame APPLET_MESSAGEFRAME; //static Level levelOSP = Level.CONFIG; static int levelOSP = Level.CONFIG.intValue(); private static int SEVERE = Level.SEVERE.intValue(), WARNING = Level.WARNING.intValue(), INFO = Level.INFO.intValue(), CONFIG = Level.CONFIG.intValue(), FINE = Level.FINE.intValue(), FINER = Level.FINER.intValue(), FINEST = Level.FINEST.intValue(); private static ArrayList<JRadioButtonMenuItem> buttonList = new ArrayList<JRadioButtonMenuItem>(); private JTextPane textPane = new JTextPane(); private MessageFrame() { // create the panel, text pane and scroller setTitle(ControlsRes.getString("MessageFrame.DefaultTitle")); //$NON-NLS-1$ JPanel logPanel = new JPanel(new BorderLayout()); logPanel.setPreferredSize(new Dimension(480, 240)); setContentPane(logPanel); logPanel.setPreferredSize(new Dimension(200, 300)); logPanel.setMinimumSize(new Dimension(100, 100)); textPane.setEditable(false); textPane.setAutoscrolls(true); black = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE); red = textPane.addStyle("red", black); //$NON-NLS-1$ StyleConstants.setForeground(red, DARK_RED); blue = textPane.addStyle("blue", black); //$NON-NLS-1$ StyleConstants.setForeground(blue, DARK_BLUE); green = textPane.addStyle("green", black); //$NON-NLS-1$ StyleConstants.setForeground(green, DARK_GREEN); magenta = textPane.addStyle("magenta", black); //$NON-NLS-1$ StyleConstants.setForeground(magenta, Color.MAGENTA); gray = textPane.addStyle("gray", black); //$NON-NLS-1$ StyleConstants.setForeground(gray, Color.GRAY); JScrollPane textScroller = new JScrollPane(textPane); textScroller.setWheelScrollingEnabled(true); logPanel.add(textScroller, BorderLayout.CENTER); pack(); } /** * Shows the static APPLET_MESSAGEFRAME that is being used to show logger messages in applet mode. * @param b boolean */ public static JFrame showLog(boolean b) { if((APPLET_MESSAGEFRAME==null)||!APPLET_MESSAGEFRAME.isDisplayable()) { createAppletMessageFrame(); } APPLET_MESSAGEFRAME.setVisible(b); return APPLET_MESSAGEFRAME; } private static void createAppletMessageFrame() { APPLET_MESSAGEFRAME = new MessageFrame(); APPLET_MESSAGEFRAME.setSize(300, 200); APPLET_MESSAGEFRAME.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE); JMenuBar menuBar = new JMenuBar(); APPLET_MESSAGEFRAME.setJMenuBar(menuBar); final JMenu editMenu = new JMenu(ControlsRes.getString("MessageFrame.Edit_menu")); //$NON-NLS-1$ menuBar.add(editMenu); final JMenuItem clearItem = new JMenuItem(ControlsRes.getString("MessageFrame.Clear_menu_item")); //$NON-NLS-1$ editMenu.add(clearItem); clearItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { APPLET_MESSAGEFRAME.textPane.setText(""); //$NON-NLS-1$ } }); final JMenu levelMenu = new JMenu(ControlsRes.getString("MessageFrame.Level_menu")); //$NON-NLS-1$ menuBar.add(levelMenu); ButtonGroup menubarGroup = new ButtonGroup(); for(int i = 0; i<OSPLog.levels.length; i++) { JRadioButtonMenuItem item = new JRadioButtonMenuItem(OSPLog.levels[i].getName()); buttonList.add(item); levelMenu.add(item, 0); menubarGroup.add(item); if(levelOSP==OSPLog.levels[i].intValue()) { item.setSelected(true); } item.setActionCommand(OSPLog.levels[i].getName()); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setLevel(Level.parse(e.getActionCommand())); } }); } ToolsRes.addPropertyChangeListener("locale", new PropertyChangeListener() { //$NON-NLS-1$ public void propertyChange(PropertyChangeEvent e) { APPLET_MESSAGEFRAME.setTitle(ControlsRes.getString("MessageFrame.DefaultTitle")); //$NON-NLS-1$ editMenu.setText(ControlsRes.getString("MessageFrame.Edit_menu")); //$NON-NLS-1$ clearItem.setText(ControlsRes.getString("MessageFrame.Clear_menu")); //$NON-NLS-1$ levelMenu.setText(ControlsRes.getString("MessageFrame.Level_menu")); //$NON-NLS-1$ } }); } /** * Gets the visible property. * * @return boolean */ public static boolean isLogVisible() { if(APPLET_MESSAGEFRAME==null) { return false; } return APPLET_MESSAGEFRAME.isVisible(); } /** * Clears the text. */ public static void clear() { if(APPLET_MESSAGEFRAME!=null) { APPLET_MESSAGEFRAME.textPane.setText(""); //$NON-NLS-1$ } } /** * Sets the logger level; * @param level Level */ public static void setLevel(Level level) { levelOSP = level.intValue(); for(int i = 0, n = Math.min(OSPLog.levels.length, buttonList.size()); i<n; i++) { if(levelOSP==OSPLog.levels[i].intValue()) { (buttonList.get(i)).setSelected(true); } } } /** * Gets the logger level value. * @return the current level value */ public static int getLevelValue() { return levelOSP; } /** * Logs an severe error message. * @param msg String */ public static void severe(String msg) { if(levelOSP<=SEVERE) { appletLog(msg, MessageFrame.red); } } /** * Logs a warning message. * @param msg String */ public static void warning(String msg) { if(levelOSP<=WARNING) { appletLog(msg, MessageFrame.red); } } /** * Logs an information message. * @param msg String */ public static void info(String msg) { if(levelOSP<=INFO) { appletLog(msg, MessageFrame.black); } } /** * Logs a configuration message. * @param msg String */ public static void config(String msg) { if(levelOSP<=CONFIG) { appletLog(msg, MessageFrame.green); } } /** * Logs a fine debugging message. * @param msg String */ public static void fine(String msg) { if(levelOSP<=FINE) { appletLog(msg, MessageFrame.blue); } } /** * Logs a finer debugging message. * @param msg String */ public static void finer(String msg) { if(levelOSP<=FINER) { appletLog(msg, MessageFrame.blue); } } /** * Logs a finest debugging message. * @param msg String */ public static void finest(String msg) { if(levelOSP<=FINEST) { appletLog(msg, MessageFrame.blue); } } private static void appletLog(final String msg, final Style style) { if((APPLET_MESSAGEFRAME==null)||!APPLET_MESSAGEFRAME.isDisplayable()) { createAppletMessageFrame(); } Runnable refreshText = new Runnable() { public synchronized void run() { try { Document doc = APPLET_MESSAGEFRAME.textPane.getDocument(); doc.insertString(doc.getLength(), msg+'\n', style); // scroll to display new message Rectangle rect = APPLET_MESSAGEFRAME.textPane.getBounds(); rect.y = rect.height; APPLET_MESSAGEFRAME.textPane.scrollRectToVisible(rect); } catch(BadLocationException ex) { System.err.println(ex); } } }; if(SwingUtilities.isEventDispatchThread()) { refreshText.run(); } else { SwingUtilities.invokeLater(refreshText); } } /* * public static void main(String[] args) { * MessageFrame.fine("test fine"); * APPLET_LOG.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); * } */ } /* * Open Source Physics software is free software; you can redistribute * it and/or modify it under the terms of the GNU General Public License (GPL) as * published by the Free Software Foundation; either version 2 of the License, * or(at your option) any later version. * * Code that uses any portion of the code in the org.opensourcephysics package * or any subpackage (subdirectory) of this package must must also be be released * under the GNU GPL license. * * This software 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 General Public License * along with this; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA * or view the license online at http://www.gnu.org/copyleft/gpl.html * * Copyright (c) 2007 The Open Source Physics project * http://www.opensourcephysics.org */