/* Wotonomy: OpenStep design patterns for pure Java applications. Copyright (C) 2000 Blacksmith, Inc. This library 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 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see http://www.gnu.org */ package net.wotonomy.ui.swing.components; import java.awt.BorderLayout; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.lang.reflect.Method; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.Timer; import javax.swing.UIManager; import javax.swing.border.EmptyBorder; /** * StatusButtonPanel extends ButtonPanel to provide a space to display status * messages in a consistent manner.
*
* Messages are erased after a certain predefined interval, defaulting to 10 * seconds. * * @author michael@mpowers.net * @author $Author: cgruber $ * @version $Revision: 904 $ */ public class StatusButtonPanel extends ButtonPanel { /** * This is the action command to all listeners when the status text is changed. */ public static final String STATUS_CHANGED = "STATUS_CHANGED"; // note: weirdness happens if you initialize // this variable. Because it is set by initLayout // and initLayout is called by the superclass constructor, // this variable would get initialized after initLayout // is called... protected Component statusComponent; // = null; protected Timer timer = null; protected int interval = 10000; // adjust as needed /** * Constructs a StatusButtonPanel. Three buttons are created so the panel is * filled when used in a GUI-builder environment. */ public StatusButtonPanel() { super(); setupTimer(); } /** * Constructs a StatusButtonPanel using specified buttons. * * @param buttonList An array containing the strings to be used in labeling the * buttons. */ public StatusButtonPanel(String[] buttonList) { super(buttonList); setupTimer(); } /** * Initializes the timer instance variable. */ protected void setupTimer() { timer = new Timer(interval, this); timer.addActionListener(this); timer.setRepeats(false); timer.start(); } /** * Returns the number of milliseconds before the status message is cleared. The * default is 10000. * * @return The current delay interval in milliseconds. */ public int getDelayInterval() { return interval; } /** * Sets the number of milliseconds before the status message is cleared. * * @param millis The new delay interval in milliseconds. */ public void setDelayInterval(int millis) { interval = millis; timer.setDelay(interval); } /** * Returns the visual component used to display the status. * * @return A component used for displaying status. */ public Component getStatusComponent() { return statusComponent; } /** * Receives ActionEvents from the internal timer. * * @param e The action event in question. */ public void actionPerformed(ActionEvent e) { if (e.getSource() == timer) { setText(""); return; } // otherwise continue with superclass implementation super.actionPerformed(e); } /** * This method is responsible for the initial layout of the panel. Subclasses * can implement different layouts, but this method is responsible for * initializing buttonPanelLayout to a valid layout manager and setting this * panel to use it. This method must should initialize statusComponent to a * component that ideally has get/setText methods, although this is not * required. */ protected void initLayout() { statusComponent = new JTextField(); JTextField textField = (JTextField) statusComponent; textField.setColumns(20); textField.setBackground(getBackground()); textField.setEditable(false); // statusComponent = new PickListPanel(); // for testing this.setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = GridBagConstraints.RELATIVE; gbc.gridy = GridBagConstraints.RELATIVE; gbc.gridwidth = 1; gbc.gridheight = 1; gbc.weightx = 1.0; gbc.weighty = 0.0; gbc.anchor = GridBagConstraints.CENTER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.insets = new Insets(0, 5, 0, 10); gbc.ipadx = 0; gbc.ipady = 0; //1.2 new GridBagConstraints(GridBagConstraints.RELATIVE, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, //1.2 GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 10), 0, 0 ); this.add(statusComponent, gbc); buttonContainer = new JPanel(); buttonPanelLayout = new BetterFlowLayout(); buttonContainer.setLayout(buttonPanelLayout); buttonPanelLayout.setAlignment(BetterFlowLayout.RIGHT); ((BetterFlowLayout) buttonPanelLayout).setWidthUniform(true); gbc.weightx = 0.0; gbc.insets = new Insets(0, 0, 0, 0); this.add(buttonContainer, gbc); } /** * Sets the text to appear in the status area. * * @param newText A string to appear in the status area. Nulls are allowed. */ public void setText(String newText) { // TODO: should use property introspection instead // use reflection to call the "setText" method, if any. try { Class c = statusComponent.getClass(); Method m = c.getMethod("setText", new Class[] { new String().getClass() }); m.invoke(statusComponent, new Object[] { newText }); broadcastEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, STATUS_CHANGED)); statusComponent.paint(statusComponent.getGraphics()); } catch (Exception exc) { // "setText" method does not exist; do nothing. } // if non-empty string, start the timer if (!"".equals(newText)) { timer.restart(); } } /** * Gets the text in the status area. * * @return The string being displayed in the status area. */ public String getText() { // TODO: should use property introspection instead String value = ""; // use reflection to call the "setText" method, if any. try { Class c = statusComponent.getClass(); Method m = c.getMethod("getText", (Class[]) null); value = (String) m.invoke(statusComponent, (Object[]) null); } catch (Exception exc) { // "getText" method does not exist; do nothing. } return value; } // for testing public static void main(String[] argv) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception exc) { } JFrame dialog = new JFrame(); BorderLayout bl = new BorderLayout(20, 20); // StatusButtonPanel panel = new StatusButtonPanel(); // System.out.println( panel.statusComponent ); StatusButtonPanel panel = new StatusButtonPanel(new String[] { "Okay", "Cancel" }); dialog.getContentPane().setLayout(bl); dialog.getContentPane().add(panel, BorderLayout.SOUTH); dialog.setLocation(50, 50); // dialog.setSize( 450, 150 ); dialog.pack(); dialog.setVisible(true); panel.setBorder(new EmptyBorder(5, 5, 5, 5)); panel.setAlignment(BetterFlowLayout.RIGHT); // panel.getButton( "One" ).setEnabled( false ); panel.setText("File saved."); System.out.println(panel.getText()); } }