Java/Swing Components/Status Bar
Содержание
A status bar is made of multiple zones
<source lang="java">
/**
* L2FProd.ru Common Components 7.3 License. * * Copyright 2005-2007 L2FProd.ru * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
import java.awt.BorderLayout; import java.awt.Color; import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; import java.awt.Insets; import java.awt.LayoutManager2; import java.util.ArrayList; import java.util.Hashtable; import java.util.Iterator; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.rupoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.plaf.UIResource; import javax.swing.text.JTextComponent; import javax.swing.text.View; import javax.swing.text.html.HTMLDocument; /**
* StatusBar.
A status bar is made of multiple zones. A zone can be any * JComponent. */
public class StatusBar extends JComponent {
/**
* The key used to identified the default zone
*/
public final static String DEFAULT_ZONE = "default";
private Hashtable idToZones;
private Border zoneBorder;
/**
* Construct a new StatusBar
*
*/
public StatusBar() {
setLayout(LookAndFeelTweaks.createHorizontalPercentLayout());
idToZones = new Hashtable();
setZoneBorder(BorderFactory.createLineBorder(Color.lightGray));
}
public void setZoneBorder(Border border) {
zoneBorder = border;
}
/**
* Adds a new zone in the StatusBar
*
* @param id
* @param zone
* @param constraints one of the constraint support by the
* {@link com.l2fprod.rumon.swing.PercentLayout}
*/
public void addZone(String id, Component zone, String constraints) {
// is there already a zone with this id?
Component previousZone = getZone(id);
if (previousZone != null) {
remove(previousZone);
idToZones.remove(id);
}
if (zone instanceof JComponent) {
JComponent jc = (JComponent)zone;
if (jc.getBorder() == null || jc.getBorder() instanceof UIResource) {
if (jc instanceof JLabel) {
jc.setBorder(
new CompoundBorder(zoneBorder, new EmptyBorder(0, 2, 0, 2)));
((JLabel)jc).setText(" ");
} else {
jc.setBorder(zoneBorder);
}
}
}
add(zone, constraints);
idToZones.put(id, zone);
}
public Component getZone(String id) {
return (Component)idToZones.get(id);
}
/**
* For example:
*
*
* setZones(new String[]{"A","B"},
* new JComponent[]{new JLabel(), new JLabel()},
* new String[]{"33%","*"});
*
*
* would construct a new status bar with two zones (two JLabels)
* named A and B, the first zone A will occupy 33 percents of the
* overall size of the status bar and B the left space.
*
* @param ids a value of type "String[]"
* @param zones a value of type "JComponent[]"
* @param constraints a value of type "String[]"
*/
public void setZones(String[] ids, Component[] zones, String[] constraints) {
removeAll();
idToZones.clear();
for (int i = 0, c = zones.length; i < c; i++) {
addZone(ids[i], zones[i], constraints[i]);
}
}
} /**
* L2FProd.ru Common Components 7.3 License. * * Copyright 2005-2007 L2FProd.ru * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
/**
* PercentLayout.*
Constraint based layout which allow the space to be * splitted using percentages. The following are allowed when adding components * to container:
-
*
- container.add(component);
in this case, the component will be * sized to its preferred size * - container.add(component, "100");
in this case, the component will * have a width (or height) of 100 * - container.add(component, "25%");
in this case, the component will * have a width (or height) of 25 % of the container width (or height)
* - container.add(component, "*");
in this case, the component will * take the remaining space. if several components use the "*" constraint the * space will be divided among the components. *
* * @javabean.class * name="PercentLayout" * shortDescription="A layout supports constraints expressed in percent." */ class PercentLayout implements LayoutManager2 { /** * Useful constant to layout the components horizontally (from top to * bottom). */ public final static int HORIZONTAL = 0; /** * Useful constant to layout the components vertically (from left to right). */ public final static int VERTICAL = 1; static class Constraint { protected Object value; private Constraint(Object value) { this.value = value; } } static class NumberConstraint extends Constraint { public NumberConstraint(int d) { this(new Integer(d)); } public NumberConstraint(Integer d) { super(d); } public int intValue() { return ((Integer)value).intValue(); } } static class PercentConstraint extends Constraint { public PercentConstraint(float d) { super(new Float(d)); } public float floatValue() { return ((Float)value).floatValue(); } } private final static Constraint REMAINING_SPACE = new Constraint("*"); private final static Constraint PREFERRED_SIZE = new Constraint(""); private int orientation; private int gap; private Hashtable m_ComponentToConstraint; /** * Creates a new HORIZONTAL PercentLayout with a gap of 0. */ public PercentLayout() { this(HORIZONTAL, 0); } public PercentLayout(int orientation, int gap) { setOrientation(orientation); this.gap = gap; m_ComponentToConstraint = new Hashtable(); } public void setGap(int gap) { this.gap = gap; } /** * @javabean.property * bound="true" * preferred="true" */ public int getGap() { return gap; } public void setOrientation(int orientation) { if (orientation != HORIZONTAL && orientation != VERTICAL) { throw new IllegalArgumentException("Orientation must be one of HORIZONTAL or VERTICAL"); } this.orientation = orientation; } /** * @javabean.property * bound="true" * preferred="true" */ public int getOrientation() { return orientation; } public Constraint getConstraint(Component component) { return (Constraint)m_ComponentToConstraint.get(component); } public void setConstraint(Component component, Object constraints) { if (constraints instanceof Constraint) { m_ComponentToConstraint.put(component, constraints); } else if (constraints instanceof Number) { setConstraint( component, new NumberConstraint(((Number)constraints).intValue())); } else if ("*".equals(constraints)) { setConstraint(component, REMAINING_SPACE); } else if ("".equals(constraints)) { setConstraint(component, PREFERRED_SIZE); } else if (constraints instanceof String) { String s = (String)constraints; if (s.endsWith("%")) { float value = Float.valueOf(s.substring(0, s.length() - 1)) .floatValue() / 100; if (value > 1 || value < 0) throw new IllegalArgumentException("percent value must be >= 0 and <= 100"); setConstraint(component, new PercentConstraint(value)); } else { setConstraint(component, new NumberConstraint(Integer.valueOf(s))); } } else if (constraints == null) { // null constraint means preferred size setConstraint(component, PREFERRED_SIZE); } else { throw new IllegalArgumentException("Invalid Constraint"); } } public void addLayoutComponent(Component component, Object constraints) { setConstraint(component, constraints); } /** * Returns the alignment along the x axis. This specifies how the component * would like to be aligned relative to other components. The value should be * a number between 0 and 1 where 0 represents alignment along the origin, 1 * is aligned the furthest away from the origin, 0.5 is centered, etc. */ public float getLayoutAlignmentX(Container target) { return 1.0f / 2.0f; } /** * Returns the alignment along the y axis. This specifies how the component * would like to be aligned relative to other components. The value should be * a number between 0 and 1 where 0 represents alignment along the origin, 1 * is aligned the furthest away from the origin, 0.5 is centered, etc. */ public float getLayoutAlignmentY(Container target) { return 1.0f / 2.0f; } /** * Invalidates the layout, indicating that if the layout manager has cached * information it should be discarded. */ public void invalidateLayout(Container target) { } /** * Adds the specified component with the specified name to the layout. * * @param name the component name * @param comp the component to be added */ public void addLayoutComponent(String name, Component comp) { } /** * Removes the specified component from the layout. * * @param comp the component ot be removed */ public void removeLayoutComponent(Component comp) { m_ComponentToConstraint.remove(comp); } /** * Calculates the minimum size dimensions for the specified panel given the * components in the specified parent container. * * @param parent the component to be laid out * @see #preferredLayoutSize */ public Dimension minimumLayoutSize(Container parent) { return preferredLayoutSize(parent); } /** * Returns the maximum size of this component. * * @see java.awt.ruponent#getMinimumSize() * @see java.awt.ruponent#getPreferredSize() * @see java.awt.LayoutManager */ public Dimension maximumLayoutSize(Container parent) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } public Dimension preferredLayoutSize(Container parent) { Component[] components = parent.getComponents(); Insets insets = parent.getInsets(); int width = 0; int height = 0; Dimension componentPreferredSize; boolean firstVisibleComponent = true; for (int i = 0, c = components.length; i < c; i++) { if (components[i].isVisible()) { componentPreferredSize = components[i].getPreferredSize(); if (orientation == HORIZONTAL) { height = Math.max(height, componentPreferredSize.height); width += componentPreferredSize.width; if (firstVisibleComponent) { firstVisibleComponent = false; } else { width += gap; } } else { height += componentPreferredSize.height; width = Math.max(width, componentPreferredSize.width); if (firstVisibleComponent) { firstVisibleComponent = false; } else { height += gap; } } } } return new Dimension( width + insets.right + insets.left, height + insets.top + insets.bottom); } public void layoutContainer(Container parent) { Insets insets = parent.getInsets(); Dimension d = parent.getSize(); // calculate the available sizes d.width = d.width - insets.left - insets.right; d.height = d.height - insets.top - insets.bottom; // pre-calculate the size of each components Component[] components = parent.getComponents(); int[] sizes = new int[components.length]; // calculate the available size int totalSize = (HORIZONTAL == orientation ? d.width : d.height) - (components.length - 1) * gap; int availableSize = totalSize; // PENDING(fred): the following code iterates 4 times on the component // array, need to find something more efficient! // give priority to components who want to use their preferred size or who // have a predefined size for (int i = 0, c = components.length; i < c; i++) { if (components[i].isVisible()) { Constraint constraint = (Constraint)m_ComponentToConstraint.get(components[i]); if (constraint == null || constraint == PREFERRED_SIZE) { sizes[i] = (HORIZONTAL == orientation ? components[i].getPreferredSize().width : components[i].getPreferredSize().height); availableSize -= sizes[i]; } else if (constraint instanceof NumberConstraint) { sizes[i] = ((NumberConstraint)constraint).intValue(); availableSize -= sizes[i]; } } } // then work with the components who want a percentage of the remaining // space int remainingSize = availableSize; for (int i = 0, c = components.length; i < c; i++) { if (components[i].isVisible()) { Constraint constraint = (Constraint)m_ComponentToConstraint.get(components[i]); if (constraint instanceof PercentConstraint) { sizes[i] = (int)(remainingSize * ((PercentConstraint)constraint) .floatValue()); availableSize -= sizes[i]; } } } // finally share the remaining space between the other components ArrayList remaining = new ArrayList(); for (int i = 0, c = components.length; i < c; i++) { if (components[i].isVisible()) { Constraint constraint = (Constraint)m_ComponentToConstraint.get(components[i]); if (constraint == REMAINING_SPACE) { remaining.add(new Integer(i)); sizes[i] = 0; } } } if (remaining.size() > 0) { int rest = availableSize / remaining.size(); for (Iterator iter = remaining.iterator(); iter.hasNext();) { sizes[((Integer)iter.next()).intValue()] = rest; } } // all calculations are done, apply the sizes int currentOffset = (HORIZONTAL == orientation ? insets.left : insets.top); for (int i = 0, c = components.length; i < c; i++) { if (components[i].isVisible()) { if (HORIZONTAL == orientation) { components[i].setBounds( currentOffset, insets.top, sizes[i], d.height); } else { components[i].setBounds( insets.left, currentOffset, d.width, sizes[i]); } currentOffset += gap + sizes[i]; } } }
}
/** * L2FProd.ru Common Components 7.3 License. * * Copyright 2005-2007 L2FProd.ru * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
/** * LookAndFeelTweaks.
* */ class LookAndFeelTweaks { public final static Border PANEL_BORDER = BorderFactory.createEmptyBorder(3, 3, 3, 3); public final static Border WINDOW_BORDER = BorderFactory.createEmptyBorder(4, 10, 10, 10); public final static Border EMPTY_BORDER = BorderFactory.createEmptyBorder(); public static void tweak() { Object listFont = UIManager.get("List.font"); UIManager.put("Table.font", listFont); UIManager.put("ToolTip.font", listFont); UIManager.put("TextField.font", listFont); UIManager.put("FormattedTextField.font", listFont); UIManager.put("Viewport.background", "Table.background"); } public static PercentLayout createVerticalPercentLayout() { return new PercentLayout(PercentLayout.VERTICAL, 8); } public static PercentLayout createHorizontalPercentLayout() { return new PercentLayout(PercentLayout.HORIZONTAL, 8); }
// public static ButtonAreaLayout createButtonAreaLayout() { // return new ButtonAreaLayout(6); // }
public static BorderLayout createBorderLayout() { return new BorderLayout(8, 8); } public static void setBorder(JComponent component) { if (component instanceof JPanel) { component.setBorder(PANEL_BORDER); } } public static void setBorderLayout(Container container) { container.setLayout(new BorderLayout(3, 3)); } public static void makeBold(JComponent component) { component.setFont(component.getFont().deriveFont(Font.BOLD)); } public static void makeMultilineLabel(JTextComponent area) { area.setFont(UIManager.getFont("Label.font")); area.setEditable(false); area.setOpaque(false); if (area instanceof JTextArea) { ((JTextArea)area).setWrapStyleWord(true); ((JTextArea)area).setLineWrap(true); } } public static void htmlize(JComponent component) { htmlize(component, UIManager.getFont("Button.font")); } public static void htmlize(JComponent component, Font font) { String stylesheet = "body { margin-top: 0; margin-bottom: 0; margin-left: 0; margin-right: 0; font-family: " + font.getName() + "; font-size: " + font.getSize() + "pt; }" + "a, p, li { margin-top: 0; margin-bottom: 0; margin-left: 0; margin-right: 0; font-family: " + font.getName() + "; font-size: " + font.getSize() + "pt; }"; try { HTMLDocument doc = null; if (component instanceof JEditorPane) { if (((JEditorPane)component).getDocument() instanceof HTMLDocument) { doc = (HTMLDocument) ((JEditorPane)component).getDocument(); } } else { View v = (View)component.getClientProperty( javax.swing.plaf.basic.BasicHTML.propertyKey); if (v != null && v.getDocument() instanceof HTMLDocument) { doc = (HTMLDocument)v.getDocument(); } } if (doc != null) { doc.getStyleSheet().loadRules( new java.io.StringReader(stylesheet), null); } // end of if (doc != null) } catch (Exception e) { e.printStackTrace(); } } public static Border addMargin(Border border) { return new CompoundBorder(border, PANEL_BORDER); } } </source>
Paint your own status bar
<source lang="java">
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; class JStatusBar extends JPanel {
public JStatusBar() { setLayout(new BorderLayout()); setPreferredSize(new Dimension(10, 23)); JPanel rightPanel = new JPanel(new BorderLayout()); rightPanel.setOpaque(false); add(rightPanel, BorderLayout.EAST); } protected void paintComponent(Graphics g) { super.paintComponent(g); int y = 0; g.setColor(new Color(156, 154, 140)); g.drawLine(0, y, getWidth(), y); y++; g.setColor(new Color(196, 194, 183)); g.drawLine(0, y, getWidth(), y); }
} public class Main {
public static void main(String[] args) { JFrame frame = new JFrame(); frame.setSize(600, 200); Container contentPane = frame.getContentPane(); contentPane.setLayout(new BorderLayout()); JStatusBar statusBar = new JStatusBar(); contentPane.add(statusBar, BorderLayout.SOUTH); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }
}
</source>
Single instance status bar
<source lang="java">
/*
* Copyright 2002 Sun Microsystems, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE OR * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF * THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed, licensed or * intended for use in the design, construction, operation or * maintenance of any nuclear facility. */
import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.*; /**
* Single instance status bar.*
* This class is also a MouseListener which listens to MOUSE_ENTERED * and MOUSE_EXITED events from Action derived components so that * the value of the Action.LONG_DESCRIPTION key is sent as a message * to the status bar. * <p> * To enable this behavior, add the StatusBar * instance as a MouseListener to the component that was created from * an Action. * * @version 1.6 01/15/03 * @author Mark Davidson */ public class StatusBar extends JPanel implements MouseListener { private JLabel label; private Dimension preferredSize; private static StatusBar INSTANCE; public StatusBar() { this.setLayout(new FlowLayout(FlowLayout.LEFT)); this.setBorder(BorderFactory.createEtchedBorder()); // Set a large blank label to set the preferred size. label = new JLabel(" "); preferredSize = new Dimension(getWidth(label.getText()), 2 * getFontHeight()); this.add(label); } /** * Return the instance of the StatusBar. If this has not been explicity * set then it will be created. * * @return the StatusBar instance. * @see #setInstance */ public static StatusBar getInstance() { if (INSTANCE == null) { INSTANCE = new StatusBar(); } return INSTANCE; } /** * Sets the StatusBar instance. */ public static void setInstance(StatusBar status) { INSTANCE = status; } /** * Returns the string width * @param s the string * @return the string width */ protected int getWidth(String s) { FontMetrics fm = this.getFontMetrics(this.getFont()); if (fm == null) { return 0; } return fm.stringWidth(s); } /** * Returns the height of a line of text * @return the height of a line of text */ protected int getFontHeight() { FontMetrics fm = this.getFontMetrics(this.getFont()); if (fm == null) { return 0; } return fm.getHeight(); } /** * Returns the perferred size * @return the preferred size */ public Dimension getPreferredSize() { return preferredSize; } /** * Sets non-transient status bar message * @param message the message to display on the status bar */ public void setMessage(String message) { label.setText(message); } // // MouseListener methods // public void mouseClicked(MouseEvent evt) {} public void mousePressed(MouseEvent evt) {} public void mouseReleased(MouseEvent evt) {} public void mouseExited(MouseEvent evt) { setMessage(""); } /** * Takes the LONG_DESCRIPTION of the Action based components * and sends them to the Status bar */ public void mouseEntered(MouseEvent evt) { if (evt.getSource() instanceof AbstractButton) { AbstractButton button = (AbstractButton)evt.getSource(); Action action = button.getAction(); if (action != null) { String message = (String)action.getValue(Action.LONG_DESCRIPTION); setMessage(message); } } } /** * Helper method to recursively register all MenuElements with * a mouse listener. */ public void registerMouseListener(MenuElement[] elements) { for (int i = 0; i < elements.length; i++) { if (elements[i] instanceof JMenuItem) { ((JMenuItem)elements[i]).addMouseListener(this); } registerMouseListener(elements[i].getSubElements()); } } /** * Helper method to register all components with a mouse listener. */ public void registerMouseListener(Component[] components) { for (int i = 0; i < components.length; i++) { if (components[i] instanceof AbstractButton) { ((AbstractButton)components[i]).addMouseListener(this); } } } } // end class StatusBar </source>
Statusbar component
<source lang="java">
/*
* Copyright (C) 2001-2003 Colin Bell * colbell@users.sourceforge.net * * 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
import java.awt.*; import javax.swing.*; import javax.swing.border.BevelBorder; import javax.swing.border.Border; /**
* This is a statusbar component with a text control for messages. * * @author */
public class StatusBar extends JPanel {
/** * Message to display if there is no msg to display. Defaults to a * blank string. */ private String _msgWhenEmpty = " "; /** Label showing the message in the statusbar. */ private final JLabel _textLbl = new JLabel(); private final JProgressBar _progressBar = new JProgressBar(); private final JPanel _pnlLabelOrProgress = new JPanel(); /** Constraints used to add new controls to this statusbar. */ private final GridBagConstraints _gbc = new GridBagConstraints(); private Font _font; /** * Default ctor. */ public StatusBar() { super(new GridBagLayout()); createGUI(); } /** * Set the font for controls in this statusbar. * * @param font The font to use. * * @throws IllegalArgumentException * Thrown if null Font passed. */ public synchronized void setFont(Font font) { if (font == null) { throw new IllegalArgumentException("Font == null"); } super.setFont(font); _font = font; updateSubcomponentsFont(this); } /** * Set the text to display in the message label. * * @param text Text to display in the message label. */ public synchronized void setText(String text) { String myText = null; if (text != null) { myText = text.trim(); } if (myText != null && myText.length() > 0) { _textLbl.setText(myText); } else { clearText(); } } /** * Returns the text label"s current value * @return */ public synchronized String getText() { return _textLbl.getText(); } public synchronized void clearText() { _textLbl.setText(_msgWhenEmpty); } public synchronized void setTextWhenEmpty(String value) { final boolean wasEmpty = _textLbl.getText().equals(_msgWhenEmpty); if (value != null && value.length() > 0) { _msgWhenEmpty = value; } else { _msgWhenEmpty = " "; } if (wasEmpty) { clearText(); } } public synchronized void addJComponent(JComponent comp) { if (comp == null) { throw new IllegalArgumentException("JComponent == null"); } comp.setBorder(createComponentBorder()); if (_font != null) { comp.setFont(_font); updateSubcomponentsFont(comp); } super.add(comp, _gbc); } public static Border createComponentBorder() { return BorderFactory.createCompoundBorder( BorderFactory.createBevelBorder(BevelBorder.LOWERED), BorderFactory.createEmptyBorder(0, 4, 0, 4)); } private void createGUI() { clearText(); Dimension progSize = _progressBar.getPreferredSize(); progSize.height = _textLbl.getPreferredSize().height; _progressBar.setPreferredSize(progSize); _progressBar.setStringPainted(true); _pnlLabelOrProgress.setLayout(new GridLayout(1,1)); _pnlLabelOrProgress.add(_textLbl); // The message area is on the right of the statusbar and takes // up all available space. _gbc.anchor = GridBagConstraints.WEST; _gbc.weightx = 1.0; _gbc.fill = GridBagConstraints.HORIZONTAL; _gbc.gridy = 0; _gbc.gridx = 0; addJComponent(_pnlLabelOrProgress); // Any other components are on the right. _gbc.weightx = 0.0; _gbc.anchor = GridBagConstraints.CENTER; _gbc.gridx = GridBagConstraints.RELATIVE; } private void updateSubcomponentsFont(Container cont) { Component[] comps = cont.getComponents(); for (int i = 0; i < comps.length; ++i) { comps[i].setFont(_font); if (comps[i] instanceof Container) { updateSubcomponentsFont((Container)comps[i]); } } } public void setStatusBarProgress(String msg, int minimum, int maximum, int value) { if(false == _pnlLabelOrProgress.getComponent(0) instanceof JProgressBar) { _pnlLabelOrProgress.remove(0); _pnlLabelOrProgress.add(_progressBar); validate(); } _progressBar.setMinimum(minimum); _progressBar.setMaximum(maximum); _progressBar.setValue(value); if(null != msg) { _progressBar.setString(msg); } else { _progressBar.setString(""); } } public void setStatusBarProgressFinished() { if(_pnlLabelOrProgress.getComponent(0) instanceof JProgressBar) { _pnlLabelOrProgress.remove(0); _pnlLabelOrProgress.add(_textLbl); validate(); repaint(); } }
}
</source>
Status Bar Demo
<source lang="java">
/* Swing Hacks Tips and Tools for Killer GUIs By Joshua Marinacci, Chris Adamson First Edition June 2005 Series: Hacks ISBN: 0-596-00907-0 Pages: 542 website: http://www.oreilly.ru/catalog/swinghks/
- /
import java.awt.BorderLayout; import java.awt.Color; import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; import java.awt.SystemColor; import javax.swing.Icon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.UIManager; import com.sun.java.swing.plaf.windows.WindowsLookAndFeel; public class StatusBarSimulator {
public static void main(String[] args) { try { UIManager.setLookAndFeel(new WindowsLookAndFeel()); } catch (Exception e) { } JFrame frame = new JFrame(); frame.setBounds(200, 200, 600, 200); frame.setTitle("Status bar simulator"); Container contentPane = frame.getContentPane(); contentPane.setLayout(new BorderLayout()); StatusBar statusBar = new StatusBar(); contentPane.add(statusBar, BorderLayout.SOUTH); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }
} class StatusBar extends JPanel {
public StatusBar() { setLayout(new BorderLayout()); setPreferredSize(new Dimension(10, 23)); JPanel rightPanel = new JPanel(new BorderLayout()); rightPanel.add(new JLabel(new AngledLinesWindowsCornerIcon()), BorderLayout.SOUTH); rightPanel.setOpaque(false); add(rightPanel, BorderLayout.EAST); setBackground(SystemColor.control); } protected void paintComponent(Graphics g) { super.paintComponent(g); int y = 0; g.setColor(new Color(156, 154, 140)); g.drawLine(0, y, getWidth(), y); y++; g.setColor(new Color(196, 194, 183)); g.drawLine(0, y, getWidth(), y); y++; g.setColor(new Color(218, 215, 201)); g.drawLine(0, y, getWidth(), y); y++; g.setColor(new Color(233, 231, 217)); g.drawLine(0, y, getWidth(), y); y = getHeight() - 3; g.setColor(new Color(233, 232, 218)); g.drawLine(0, y, getWidth(), y); y++; g.setColor(new Color(233, 231, 216)); g.drawLine(0, y, getWidth(), y); y = getHeight() - 1; g.setColor(new Color(221, 221, 220)); g.drawLine(0, y, getWidth(), y); }
} class AngledLinesWindowsCornerIcon implements Icon {
private static final Color WHITE_LINE_COLOR = new Color(255, 255, 255); private static final Color GRAY_LINE_COLOR = new Color(172, 168, 153); private static final int WIDTH = 13; private static final int HEIGHT = 13; public int getIconHeight() { return WIDTH; } public int getIconWidth() { return HEIGHT; } public void paintIcon(Component c, Graphics g, int x, int y) { g.setColor(WHITE_LINE_COLOR); g.drawLine(0, 12, 12, 0); g.drawLine(5, 12, 12, 5); g.drawLine(10, 12, 12, 10); g.setColor(GRAY_LINE_COLOR); g.drawLine(1, 12, 12, 1); g.drawLine(2, 12, 12, 2); g.drawLine(3, 12, 12, 3); g.drawLine(6, 12, 12, 6); g.drawLine(7, 12, 12, 7); g.drawLine(8, 12, 12, 8); g.drawLine(11, 12, 12, 11); g.drawLine(12, 12, 12, 12); }
}
</source>