Java/Swing Components/Link Button

Материал из Java эксперт
Версия от 18:01, 31 мая 2010; (обсуждение)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Another Link button

/**
 * $ $ License.
 *
 * Copyright $ 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.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruposite;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.ruponentUI;
import javax.swing.plaf.basic.BasicButtonUI;
import javax.swing.plaf.basic.BasicGraphicsUtils;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.text.View;
/**
 * A button targeted to be used as an hyperlink. Most UI will make it
 * transparent and it will react on mouse over by changing the cursor to the
 * hand cursor.
 * 
 * @javabean.class name="JLinkButton" shortDescription="A button looking as an
 *                 hyperlink." stopClass="java.awt.ruponent"
 * 
 * @javabean.attribute name="isContainer" value="Boolean.FALSE" rtexpr="true"
 * 
 * @javabean.icons mono16="JLinkButton16-mono.gif" color16="JLinkButton16.gif"
 *                 mono32="JLinkButton32-mono.gif" color32="JLinkButton32.gif"
 */
public class AnotherLinkButton extends JButton {
  public AnotherLinkButton() {
    super();
  }
  public AnotherLinkButton(String text) {
    super(text);
  }
  public AnotherLinkButton(String text, Icon icon) {
    super(text, icon);
  }
  public AnotherLinkButton(Action a) {
    super(a);
  }
  public AnotherLinkButton(Icon icon) {
    super(icon);
  }
  public void updateUI() {
    setUI(new WindowsLinkButtonUI());
  }
  public static void main(String[] args) throws Exception {
    JFrame frame = new JFrame("JLinkButton");
    frame.getContentPane().setLayout(new BorderLayout());
    frame.getContentPane().add("Center", new AnotherLinkButton("www.jexp.ru"));
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setLocation(100, 100);
    frame.setVisible(true);
  }
}
class BasicLinkButtonUI extends BasicButtonUI {
  public static ComponentUI createUI(JComponent c) {
    return new BasicLinkButtonUI();
  }
  private static Rectangle viewRect = new Rectangle();
  private static Rectangle textRect = new Rectangle();
  private static Rectangle iconRect = new Rectangle();
  private static MouseListener handCursorListener = new HandCursor();
  protected int dashedRectGapX;
  protected int dashedRectGapY;
  protected int dashedRectGapWidth;
  protected int dashedRectGapHeight;
  private Color focusColor;
  protected void installDefaults(AbstractButton b) {
    super.installDefaults(b);
    b.setOpaque(false);
    b.setBorderPainted(false);
    b.setRolloverEnabled(true);
    dashedRectGapX = UIManager.getInt("ButtonUI.dashedRectGapX");
    dashedRectGapY = UIManager.getInt("ButtonUI.dashedRectGapY");
    dashedRectGapWidth = UIManager.getInt("ButtonUI.dashedRectGapWidth");
    dashedRectGapHeight = UIManager.getInt("ButtonUI.dashedRectGapHeight");
    focusColor = UIManager.getColor("ButtonUI.focus");
    b.setHorizontalAlignment(AbstractButton.LEFT);
  }
  protected void installListeners(AbstractButton b) {
    super.installListeners(b);
    b.addMouseListener(handCursorListener);
  }
  protected void uninstallListeners(AbstractButton b) {
    super.uninstallListeners(b);
    b.removeMouseListener(handCursorListener);
  }
  protected Color getFocusColor() {
    return focusColor;
  }
  public void paint(Graphics g, JComponent c) {
    AbstractButton b = (AbstractButton) c;
    ButtonModel model = b.getModel();
    FontMetrics fm = g.getFontMetrics();
    Insets i = c.getInsets();
    viewRect.x = i.left;
    viewRect.y = i.top;
    viewRect.width = b.getWidth() - (i.right + viewRect.x);
    viewRect.height = b.getHeight() - (i.bottom + viewRect.y);
    textRect.x = textRect.y = textRect.width = textRect.height = 0;
    iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
    Font f = c.getFont();
    g.setFont(f);
    // layout the text and icon
    String text = SwingUtilities.layoutCompoundLabel(c, fm, b.getText(), b
        .getIcon(), b.getVerticalAlignment(), b
        .getHorizontalAlignment(), b.getVerticalTextPosition(), b
        .getHorizontalTextPosition(), viewRect, iconRect, textRect, b
        .getText() == null ? 0 : b.getIconTextGap());
    clearTextShiftOffset();
    // perform UI specific press action, e.g. Windows L&F shifts text
    if (model.isArmed() && model.isPressed()) {
      paintButtonPressed(g, b);
    }
    // Paint the Icon
    if (b.getIcon() != null) {
      paintIcon(g, c, iconRect);
    }
    Composite oldComposite = ((Graphics2D) g).getComposite();
    if (model.isRollover()) {
      ((Graphics2D) g).setComposite(AlphaComposite.getInstance(
          AlphaComposite.SRC_OVER, 0.5f));
    }
    if (text != null && !text.equals("")) {
      View v = (View) c.getClientProperty(BasicHTML.propertyKey);
      if (v != null) {
        textRect.x += getTextShiftOffset();
        textRect.y += getTextShiftOffset();
        v.paint(g, textRect);
        textRect.x -= getTextShiftOffset();
        textRect.y -= getTextShiftOffset();
      } else {
        paintText(g, b, textRect, text);
      }
    }
    if (b.isFocusPainted() && b.hasFocus()) {
      // paint UI specific focus
      paintFocus(g, b, viewRect, textRect, iconRect);
    }
    ((Graphics2D) g).setComposite(oldComposite);
  }
  protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect,
      Rectangle textRect, Rectangle iconRect) {
    if (b.getParent() instanceof JToolBar) {
      // Windows doesn"t draw the focus rect for buttons in a toolbar.
      return;
    }
    // focus painted same color as text
    int width = b.getWidth();
    int height = b.getHeight();
    g.setColor(getFocusColor());
    BasicGraphicsUtils.drawDashedRect(g, dashedRectGapX, dashedRectGapY,
        width - dashedRectGapWidth, height - dashedRectGapHeight);
  }
  protected void paintButtonPressed(Graphics g, AbstractButton b) {
    setTextShiftOffset();
  }
  static class HandCursor extends MouseAdapter {
    public void mouseEntered(MouseEvent e) {
      e.getComponent().setCursor(
          Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    }
    public void mouseExited(MouseEvent e) {
      e.getComponent().setCursor(Cursor.getDefaultCursor());
    }
  }
}
class WindowsLinkButtonUI extends BasicLinkButtonUI {
  private static WindowsLinkButtonUI buttonUI = new WindowsLinkButtonUI();
  public static ComponentUI createUI(JComponent c) {
    return buttonUI;
  }
  protected void paintButtonPressed(Graphics g, AbstractButton b) {
    setTextShiftOffset();
  }
}





Hyper Link component

HyperLink in Table

LinkButton

import java.awt.Color;
import java.awt.Cursor;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.net.URL;
import javax.swing.Action;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.plaf.ruponentUI;
import javax.swing.plaf.metal.MetalButtonUI;
public class JLinkButton extends JButton {
  private static final String uiString = "LinkButtonUI";
  public static final int ALWAYS_UNDERLINE = 0;
  public static final int HOVER_UNDERLINE = 1;
  public static final int NEVER_UNDERLINE = 2;
  public static final int SYSTEM_DEFAULT = 3;
  private int linkBehavior;
  private Color linkColor;
  private Color colorPressed;
  private Color visitedLinkColor;
  private Color disabledLinkColor;
  private URL buttonURL;
  private Action defaultAction;
  private boolean isLinkVisited;
  public static void main(String[] a) {
    JFrame f = new JFrame();
    f.getContentPane().setLayout(new GridLayout(0,2));
    f.getContentPane().add(new JLinkButton("www.jexp.ru"));
    f.getContentPane().add(new JLinkButton("www.jexp.ru/ExampleCode/CatalogExampleCode.htm"));
    f.setSize(600, 200);
    f.setVisible(true);
  }
  public JLinkButton() {
    this(null, null, null);
  }
  public JLinkButton(Action action) {
    this();
    setAction(action);
  }
  public JLinkButton(Icon icon) {
    this(null, icon, null);
  }
  public JLinkButton(String s) {
    this(s, null, null);
  }
  public JLinkButton(URL url) {
    this(null, null, url);
  }
  public JLinkButton(String s, URL url) {
    this(s, null, url);
  }
  public JLinkButton(Icon icon, URL url) {
    this(null, icon, url);
  }
  public JLinkButton(String text, Icon icon, URL url) {
    super(text, icon);
    linkBehavior = SYSTEM_DEFAULT;
    linkColor = Color.blue;
    colorPressed = Color.red;
    visitedLinkColor = new Color(128, 0, 128);
    if (text == null && url != null)
      setText(url.toExternalForm());
    setLinkURL(url);
    setCursor(Cursor.getPredefinedCursor(12));
    setBorderPainted(false);
    setContentAreaFilled(false);
    setRolloverEnabled(true);
    addActionListener(defaultAction);
  }
  public void updateUI() {
    setUI(BasicLinkButtonUI.createUI(this));
  }
  private void setDefault() {
    UIManager.getDefaults().put("LinkButtonUI", "BasicLinkButtonUI");
  }
  public String getUIClassID() {
    return "LinkButtonUI";
  }
  protected void setupToolTipText() {
    String tip = null;
    if (buttonURL != null)
      tip = buttonURL.toExternalForm();
    setToolTipText(tip);
  }
  public void setLinkBehavior(int bnew) {
    checkLinkBehaviour(bnew);
    int old = linkBehavior;
    linkBehavior = bnew;
    firePropertyChange("linkBehavior", old, bnew);
    repaint();
  }
  private void checkLinkBehaviour(int beha) {
    if (beha != ALWAYS_UNDERLINE && beha != HOVER_UNDERLINE
        && beha != NEVER_UNDERLINE && beha != SYSTEM_DEFAULT)
      throw new IllegalArgumentException("Not a legal LinkBehavior");
    else
      return;
  }
  public int getLinkBehavior() {
    return linkBehavior;
  }
  public void setLinkColor(Color color) {
    Color colorOld = linkColor;
    linkColor = color;
    firePropertyChange("linkColor", colorOld, color);
    repaint();
  }
  public Color getLinkColor() {
    return linkColor;
  }
  public void setActiveLinkColor(Color colorNew) {
    Color colorOld = colorPressed;
    colorPressed = colorNew;
    firePropertyChange("activeLinkColor", colorOld, colorNew);
    repaint();
  }
  public Color getActiveLinkColor() {
    return colorPressed;
  }
  public void setDisabledLinkColor(Color color) {
    Color colorOld = disabledLinkColor;
    disabledLinkColor = color;
    firePropertyChange("disabledLinkColor", colorOld, color);
    if (!isEnabled())
      repaint();
  }
  public Color getDisabledLinkColor() {
    return disabledLinkColor;
  }
  public void setVisitedLinkColor(Color colorNew) {
    Color colorOld = visitedLinkColor;
    visitedLinkColor = colorNew;
    firePropertyChange("visitedLinkColor", colorOld, colorNew);
    repaint();
  }
  public Color getVisitedLinkColor() {
    return visitedLinkColor;
  }
  public URL getLinkURL() {
    return buttonURL;
  }
  public void setLinkURL(URL url) {
    URL urlOld = buttonURL;
    buttonURL = url;
    setupToolTipText();
    firePropertyChange("linkURL", urlOld, url);
    revalidate();
    repaint();
  }
  public void setLinkVisited(boolean flagNew) {
    boolean flagOld = isLinkVisited;
    isLinkVisited = flagNew;
    firePropertyChange("linkVisited", flagOld, flagNew);
    repaint();
  }
  public boolean isLinkVisited() {
    return isLinkVisited;
  }
  public void setDefaultAction(Action actionNew) {
    Action actionOld = defaultAction;
    defaultAction = actionNew;
    firePropertyChange("defaultAction", actionOld, actionNew);
  }
  public Action getDefaultAction() {
    return defaultAction;
  }
  protected String paramString() {
    String str;
    if (linkBehavior == ALWAYS_UNDERLINE)
      str = "ALWAYS_UNDERLINE";
    else if (linkBehavior == HOVER_UNDERLINE)
      str = "HOVER_UNDERLINE";
    else if (linkBehavior == NEVER_UNDERLINE)
      str = "NEVER_UNDERLINE";
    else
      str = "SYSTEM_DEFAULT";
    String colorStr = linkColor == null ? "" : linkColor.toString();
    String colorPressStr = colorPressed == null ? "" : colorPressed
        .toString();
    String disabledLinkColorStr = disabledLinkColor == null ? ""
        : disabledLinkColor.toString();
    String visitedLinkColorStr = visitedLinkColor == null ? ""
        : visitedLinkColor.toString();
    String buttonURLStr = buttonURL == null ? "" : buttonURL.toString();
    String isLinkVisitedStr = isLinkVisited ? "true" : "false";
    return super.paramString() + ",linkBehavior=" + str + ",linkURL="
        + buttonURLStr + ",linkColor=" + colorStr + ",activeLinkColor="
        + colorPressStr + ",disabledLinkColor=" + disabledLinkColorStr
        + ",visitedLinkColor=" + visitedLinkColorStr
        + ",linkvisitedString=" + isLinkVisitedStr;
  }
}
class BasicLinkButtonUI extends MetalButtonUI {
  private static final BasicLinkButtonUI ui = new BasicLinkButtonUI();
  public BasicLinkButtonUI() {
  }
  public static ComponentUI createUI(JComponent jcomponent) {
    return ui;
  }
  protected void paintText(Graphics g, JComponent com, Rectangle rect,
      String s) {
    JLinkButton bn = (JLinkButton) com;
    ButtonModel bnModel = bn.getModel();
    Color color = bn.getForeground();
    Object obj = null;
    if (bnModel.isEnabled()) {
      if (bnModel.isPressed())
        bn.setForeground(bn.getActiveLinkColor());
      else if (bn.isLinkVisited())
        bn.setForeground(bn.getVisitedLinkColor());
      else
        bn.setForeground(bn.getLinkColor());
    } else {
      if (bn.getDisabledLinkColor() != null)
        bn.setForeground(bn.getDisabledLinkColor());
    }
    super.paintText(g, com, rect, s);
    int behaviour = bn.getLinkBehavior();
    boolean drawLine = false;
    if (behaviour == JLinkButton.HOVER_UNDERLINE) {
      if (bnModel.isRollover())
        drawLine = true;
    } else if (behaviour == JLinkButton.ALWAYS_UNDERLINE || behaviour == JLinkButton.SYSTEM_DEFAULT)
      drawLine = true;
    if (!drawLine)
      return;
    FontMetrics fm = g.getFontMetrics();
    int x = rect.x + getTextShiftOffset();
    int y = (rect.y + fm.getAscent() + fm.getDescent() + getTextShiftOffset()) - 1;
    if (bnModel.isEnabled()) {
      g.setColor(bn.getForeground());
      g.drawLine(x, y, (x + rect.width) - 1, y);
    } else {
      g.setColor(bn.getBackground().brighter());
      g.drawLine(x, y, (x + rect.width) - 1, y);
    }
  }
}