Java/Swing Components/Status Bar
Версия от 18:01, 31 мая 2010; (обсуждение)
Содержание
A status bar is made of multiple zones
/**
* 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. <BR>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:
*
* <code>
* setZones(new String[]{"A","B"},
* new JComponent[]{new JLabel(), new JLabel()},
* new String[]{"33%","*"});
* </code>
*
* 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. <BR>Constraint based layout which allow the space to be
* splitted using percentages. The following are allowed when adding components
* to container:
* <ul>
* <li>container.add(component); <br>in this case, the component will be
* sized to its preferred size
* <li>container.add(component, "100"); <br>in this case, the component will
* have a width (or height) of 100
* <li>container.add(component, "25%"); <br>in this case, the component will
* have a width (or height) of 25 % of the container width (or height) <br>
* <li>container.add(component, "*"); <br>in this case, the component will
* take the remaining space. if several components use the "*" constraint the
* space will be divided among the components.
* </ul>
*
* @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. <br>
*
*/
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);
}
}
Paint your own status bar
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);
}
}
Single instance status bar
/*
* 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.
* <p>
* 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
Statusbar component
/*
* 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 <TT>null</TT> <TT>Font</TT> 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();
}
}
}
Status Bar Demo
/*
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);
}
}