Re: JToolbar style for icon JButton
Albert a ?crit :
Le 21/10/2009 15:47, Steve W. Jackson a ?crit :
In article<4adf0f46$0$975$ba4acef3@news.orange.fr>,
Albert<albert@voila.fr> wrote:
When putting a JButton with an icon (and no text) on a JToolbar, the
button has no (big, winXP) border, has a rollover, a pretty focus. Is it
possible to get these features for a JButton in a JPanel ?
Look at the JToolBar for isRollover and setRollover, which I'm pretty
sure handle that part for you. The rest should be available in JButton
and its super classes.
JToolBar.setRollover just change a client property of itself:
"JToolBar.isRollover".
WindowsToolBarUI in XP style, seems to set empty borders for rollover.
Here is a try at it. I don't there's a ultimate solution, but this a
good base:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ButtonUI;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicButtonUI;
public class RolloverButtonDemo implements Runnable {
public static void main(String[] args) {
EventQueue.invokeLater(new RolloverButtonDemo());
}
private static class SimpleBorder extends AbstractBorder {
private boolean raised;
public SimpleBorder(boolean raised) {
this.raised = raised;
}
public Insets getBorderInsets(Component c) {
Insets insets = new Insets(1, 1, 1, 1);
return insets;
}
public boolean isBorderOpaque() {
return true;
}
public void paintBorder(Component c, Graphics g, int x, int y,
int width, int height) {
super.paintBorder(c, g, x, y, width, height);
Color b = new Color(220, 220, 220);
Color d = c.getBackground().darker();
if (!raised) {
Color tmp = b;
b = d;
d = tmp;
}
g.setColor(b);
int right = x+width-1;
int bottom = y+height-1;
g.drawLine(x, y, right, y); // up
g.drawLine(x, y, x, bottom); // left
g.setColor(d);
g.drawLine(x, bottom, right, bottom); // bottom
g.drawLine(right, y, right, bottom); // right
}
}
private static class RolloverButton extends JButton implements
MouseListener, ChangeListener {
private Border defaultBorder;
private Border rolloverBorder;
private Border pressedBorder;
public RolloverButton(Icon icon) {
super(icon);
init();
}
public RolloverButton(String s, ImageIcon icon) {
super(s, icon);
init();
}
private void init() {
// the UI should not set its border or paint, we handle it
setRolloverEnabled(false);
setFocusPainted(false);
setContentAreaFilled(false);
defaultBorder = new EmptyBorder(4, 4, 4, 4);
Border lowBorder = new SimpleBorder(false);
Border raisedBorder = new SimpleBorder(true);
rolloverBorder = BorderFactory.createCompoundBorder(raisedBorder,
new EmptyBorder(3, 3, 3, 3));
pressedBorder = BorderFactory.createCompoundBorder(lowBorder, new
EmptyBorder(3, 3, 3, 3));
setBorder(defaultBorder);
addMouseListener(this);
addChangeListener(this);
}
public void mouseClicked(MouseEvent arg0) {
}
public void mouseEntered(MouseEvent evt) {
setBorder(rolloverBorder);
}
public void mouseExited(MouseEvent arg0) {
setBorder(defaultBorder);
}
public void mousePressed(MouseEvent arg0) {
if (isEnabled())
setBorder(pressedBorder);
}
public void mouseReleased(MouseEvent evt) {
boolean interact = isDisplayable() && isVisible();
if (interact && contains(evt.getPoint()))
setBorder(rolloverBorder);
else
setBorder(defaultBorder);
}
public void stateChanged(ChangeEvent evt) {
Point pt = MouseInfo.getPointerInfo().getLocation();
SwingUtilities.convertPointFromScreen(pt, this);
boolean interact = isDisplayable() && isVisible();
if (interact && (getModel().isArmed() || getModel().isPressed()))
setBorder(pressedBorder);
else if (interact && (hasFocus() || contains(pt)))
setBorder(rolloverBorder);
else
setBorder(defaultBorder);
}
}
private static class RolloverButtonUI extends BasicButtonUI
implements MouseListener, KeyListener {
private final static RolloverButtonUI m_buttonUI = new
RolloverButtonUI();
private EmptyBorder defaultBorder;
private CompoundBorder rolloverBorder;
private CompoundBorder pressedBorder;
private RolloverButtonUI() {
defaultBorder = new EmptyBorder(4, 4, 4, 4);
Border lowBorder = new SimpleBorder(false);
Border raisedBorder = new SimpleBorder(true);
rolloverBorder = BorderFactory.createCompoundBorder(raisedBorder,
new EmptyBorder(3, 3, 3, 3));
pressedBorder = BorderFactory.createCompoundBorder(lowBorder, new
EmptyBorder(3, 3, 3, 3));
}
public static ComponentUI createUI(JComponent c) {
return m_buttonUI;
}
public void installUI(JComponent c) {
super.installUI(c);
c.addMouseListener(this);
c.addKeyListener(this);
}
// some parts are copied from super
protected void installDefaults(AbstractButton b) {
// load shared instance defaults
String pp = getPropertyPrefix();
defaultTextShiftOffset = UIManager.getInt(pp + "textShiftOffset");
LookAndFeel.installProperty(b,
JButton.CONTENT_AREA_FILLED_CHANGED_PROPERTY, Boolean.FALSE);
LookAndFeel.installProperty(b, "opaque", Boolean.FALSE);
LookAndFeel.installProperty(b,
JButton.ROLLOVER_ENABLED_CHANGED_PROPERTY, Boolean.TRUE);
b.setFocusPainted(false);
b.setBorder(defaultBorder);
}
public void uninstallUI(JComponent c) {
super.uninstallUI(c);
c.setBorder(defaultBorder);
c.removeMouseListener(this);
c.removeKeyListener(this);
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
JComponent c = (JComponent) e.getComponent();
if (c.isEnabled())
c.setBorder(pressedBorder);
}
public void mouseReleased(MouseEvent evt) {
JComponent c = (JComponent) evt.getComponent();
boolean interact = c.isDisplayable() && c.isVisible();
if (interact && c.contains(evt.getPoint()))
c.setBorder(rolloverBorder);
else
c.setBorder(defaultBorder);
}
public void mouseEntered(MouseEvent e) {
JComponent c = (JComponent) e.getComponent();
c.setBorder(rolloverBorder);
c.repaint();
}
public void mouseExited(MouseEvent e) {
JComponent c = (JComponent) e.getComponent();
c.setBorder(defaultBorder);
c.repaint();
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_ENTER || code == KeyEvent.VK_SPACE) {
JComponent c = (JComponent) e.getComponent();
c.setBorder(pressedBorder);
}
}
public void keyReleased(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_ENTER || code == KeyEvent.VK_SPACE) {
JComponent c = (JComponent) e.getComponent();
c.setBorder(rolloverBorder);
}
}
}
/** A normal JButton except it forces its UI */
private static class RolloverButtonWithUI extends JButton {
private static RolloverButtonUI myUI = new RolloverButtonUI();
public RolloverButtonWithUI(Icon icon) {
super(icon);
init();
}
public RolloverButtonWithUI(String s, ImageIcon icon) {
super(s, icon);
init();
}
private void init() {
setOpaque(false);
super.setUI(myUI);
}
@Override
public void setUI(ButtonUI ui) {
myUI.uninstallUI(this);
// font, etc.
super.setUI(ui);
myUI.installUI(this);
}
@Override
public ButtonUI getUI() {
return myUI;
}
}
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setJMenuBar(createMenuBar(frame));
JPanel flowPanel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.gridy = 0;
flowPanel.add(new JLabel("JButton"), c);
JButton bt = new JButton(genIcon(16, 16, Color.red));
flowPanel.add(bt, c);
JButton bt2 = new JButton("click", genIcon(16, 16, Color.red));
flowPanel.add(bt2, c);
JButton bt3 = new JButton("click", genIcon(16, 16, Color.red));
bt3.setEnabled(false);
flowPanel.add(bt3, c);
c.gridy = 1;
flowPanel.add(new JLabel("RolloverButton"), c);
RolloverButton mybt = new RolloverButton(genIcon(16, 16, Color.blue));
flowPanel.add(mybt, c);
RolloverButton mybt2 = new RolloverButton("click", genIcon(16, 16,
Color.blue));
flowPanel.add(mybt2, c);
RolloverButton mybt3 = new RolloverButton("click", genIcon(16, 16,
Color.blue));
mybt3.setEnabled(false);
flowPanel.add(mybt3, c);
c.gridy = 2;
flowPanel.add(new JLabel("RolloverButtonWithUI"), c);
RolloverButtonWithUI btui = new RolloverButtonWithUI(genIcon(16,
16, Color.green));
flowPanel.add(btui, c);
RolloverButtonWithUI btui2 = new RolloverButtonWithUI("click",
genIcon(16, 16, Color.green));
flowPanel.add(btui2, c);
RolloverButtonWithUI btui3 = new RolloverButtonWithUI("click",
genIcon(16, 16, Color.green));
btui3.setEnabled(false);
flowPanel.add(btui3, c);
frame.getContentPane().add(flowPanel, BorderLayout.CENTER);
frame.getContentPane().add(createToolbar(), BorderLayout.NORTH);
frame.setSize(600, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JToolBar createToolbar() {
JToolBar tb = new JToolBar();
JButton bt = new JButton(genIcon(16, 16, Color.red));
tb.add(bt);
JButton bt2 = new JButton("click", genIcon(16, 16, Color.red));
tb.add(bt2);
JButton bt3 = new JButton("click", genIcon(16, 16, Color.red));
bt3.setEnabled(false);
tb.add(bt3);
RolloverButton mybt = new RolloverButton(genIcon(16, 16, Color.blue));
tb.add(mybt);
RolloverButton mybt2 = new RolloverButton("click", genIcon(16, 16,
Color.blue));
tb.add(mybt2);
RolloverButton mybt3 = new RolloverButton("click", genIcon(16, 16,
Color.blue));
mybt3.setEnabled(false);
tb.add(mybt3);
RolloverButtonWithUI btui = new RolloverButtonWithUI(genIcon(16,
16, Color.green));
tb.add(btui);
RolloverButtonWithUI btui2 = new RolloverButtonWithUI("click",
genIcon(16, 16, Color.green));
tb.add(btui2);
RolloverButtonWithUI btui3 = new RolloverButtonWithUI("click",
genIcon(16, 16, Color.green));
btui3.setEnabled(false);
tb.add(btui3);
return tb;
}
private ImageIcon genIcon(int w, int h, Color c) {
BufferedImage bi = new BufferedImage(w, h,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(new Color(0, 0, 0, 0));
g.fillRect(0, 0, w, h);
g.setColor(c);
g.fillOval(0, 0, w, h);
g.dispose();
return new ImageIcon(bi);
}
private JMenuBar createMenuBar(final JFrame frame) {
JMenuBar mb = new JMenuBar();
JMenu menu = new JMenu("Lafs");
LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels();
for (final LookAndFeelInfo info : infos) {
JMenuItem item = new JMenuItem(info.getName());
item.setToolTipText(info.getClassName());
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
UIManager.setLookAndFeel(info.getClassName());
SwingUtilities.updateComponentTreeUI(frame);
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
menu.add(item);
}
mb.add(menu);
return mb;
}
}