带下拉箭头的按钮(JSplitButton)
2011-01-15 23:58
295 查看
最近需要用到带下拉箭头的按钮这样的组件,本来以为java是自带的有,在网上搜了N次,就是没有收到,最后就只有自己写了。写了几次,几次都觉得难看,后来又去网上搜,还是很令我失望,最后自己又硬着头皮来重写原来的了。现在终于写了一个自己比较满意的出来。先来看哈截图。
效果基本上还看得过去。
下面是具体代码:
再贴出测试类代码如下:
一切OK了。
效果基本上还看得过去。
下面是具体代码:
/** * All rights reserved,2010,mengke */ package com.mengke.j2se.swing; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.util.ArrayList; import java.util.List; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JSeparator; /** *@author mengke * @email wqjsir@foxmail.com *@version 2011-1-15下午11:35:31 */ public class JSplitButton extends JButton { private static final long serialVersionUID = -7431955200320586601L; private JLabel textLabel = new JLabel(); private JLabel arrowButton = new JLabel(); private JPanel separatePanel = new JPanel(new BorderLayout()); private JPanel textPanel = new JPanel(new GridBagLayout()); private JPanel arrowButtonPanel = new JPanel(new GridBagLayout()); private JSeparator separator = new JSeparator(JSeparator.NORTH); private boolean separatorVisible = true; private boolean locationLeft = true; private JPopupMenu optionPopMenu; private JPopupMenu buttonPopMenu; private List<ActionListener> listeners = new ArrayList<ActionListener>(); private static Color DEFAULT_BORDER_COLOR = Color.LIGHT_GRAY; private Color borderColor =DEFAULT_BORDER_COLOR; public JSplitButton() { decorate(); } public JSplitButton(String text) { textLabel.setText(text); decorate(); } public JSplitButton(Icon icon) { textLabel.setIcon(icon); decorate(); } public JSplitButton(String text, Icon icon) { textLabel.setText(text); textLabel.setIcon(icon); decorate(); } protected void decorate() { setLayout(new GridBagLayout()); separatePanel.setOpaque(false); arrowButtonPanel.setOpaque(false); textPanel.setOpaque(false); //这里主要是给分割条占一个位置,如果不约束的话,则在显示和隐藏分割条时,按钮界面就会扭动 separatePanel.setPreferredSize(new Dimension(2, 10)); separatePanel.add(separator, BorderLayout.CENTER); arrowButton.setIcon(new ImageIcon("./images/option_7x7.png")); arrowButtonPanel.add(arrowButton, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 2, 0, 2), 0, 0)); arrowButtonPanel.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 1)); textPanel.add(textLabel, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 2, 0, 2), 0, 0)); textPanel.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 0)); add(textPanel, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); add(separatePanel, new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.VERTICAL, new Insets(0, 0, 0, 0), 0, 0)); add(arrowButtonPanel, new GridBagConstraints(2, 0, 1, 1, 1, 1, GridBagConstraints.EAST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); setMargin(new Insets(0, 0, 0, 0)); addMouseListener(new MouseAdapter() { public void mouseEntered(MouseEvent e) { if (isEnabled()) { separator.setVisible(true); } } public void mouseExited(MouseEvent e) { EventQueue.invokeLater(new Runnable() { @Override public void run() { arrowButton.setIcon(new ImageIcon("./images/option_7x7.png")); if (!isSeparatorVisible()) { separator.setVisible(false); } textPanel.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 0)); arrowButtonPanel.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 1)); } }); } @Override public void mouseClicked(final MouseEvent e) { EventQueue.invokeLater(new Runnable() { @Override public void run() { int x = separatePanel.getX(); if (e.getPoint().x > x) { arrowButton.setIcon(new ImageIcon("./images/option_7x9.png")); if (optionPopMenu != null) { if(locationLeft){ optionPopMenu.show(JSplitButton.this, 0, JSplitButton.this.getHeight()); }else{ optionPopMenu.show(arrowButtonPanel, 0, arrowButtonPanel.getHeight()); } } } else { for (ActionListener action : listeners) { ActionEvent actionEvent = new ActionEvent(JSplitButton.this, ActionEvent.ACTION_FIRST, ""); action.actionPerformed(actionEvent); } if(buttonPopMenu!=null){ buttonPopMenu.show(JSplitButton.this, 0, JSplitButton.this.getHeight()); } } } }); } @Override public void mouseReleased(MouseEvent e) { EventQueue.invokeLater(new Runnable() { @Override public void run() { arrowButton.setIcon(new ImageIcon("./images/option_7x7.png")); arrowButton.updateUI(); } }); } }); addMouseMotionListener(new MouseMotionListener() { @Override public void mouseDragged(MouseEvent e) { } @Override public void mouseMoved(MouseEvent e) { int x = separatePanel.getX(); if (e.getPoint().x > x) { arrowButtonPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 1,borderColor)); textPanel.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 0)); } else { textPanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, borderColor)); arrowButtonPanel.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 1)); } } }); } /** * 获得中间的分割条是否显示。为true时表示,一直显示,为false时表示单鼠标进入才显示。默认为true,即一直显示 * * @return */ public boolean isSeparatorVisible() { return separatorVisible; } /** * 设置中间的分割条是否显示。为true时表示,一直显示,为false时表示单鼠标进入才显示。默认为true,即一直显示 * * @param separatorVisible */ public void setSeparatorVisible(boolean separatorVisible) { this.separatorVisible = separatorVisible; separator.setVisible(separatorVisible); } /** * 获取右边箭头按钮菜单的菜单显示对其方式。true表示与按钮左边对齐,false表示与箭头按钮对齐。默认为左对齐 * @return */ public boolean isLocationLeft() { return locationLeft; } /** * 设置右边箭头按钮菜单的菜单显示对其方式。true表示与按钮左边对齐,false表示与箭头按钮对齐。默认为左对齐 * @param locationLeft */ public void setLocationLeft(boolean locationLeft) { this.locationLeft = locationLeft; } /** * 获得鼠标进入按钮时绘制的边框的颜色。默认为Color.LIGHT_GRAY * * @return */ public Color getBorderColor() { return borderColor; } /** * 设置鼠标进入按钮时绘制的边框的颜色。默认为Color.LIGHT_GRAY * * @param borderColor */ public void setBorderColor(Color borderColor) { if(borderColor==null){ throw new IllegalArgumentException("边框颜色不能为空"); } this.borderColor = borderColor; } /** * 添加按钮监听事件,这里添加到的是按钮左边部分的事件监听。 */ public void addActionListener(ActionListener action) { listeners.add(action); } /** * 移除按钮监听事件。 */ public void removeActionListener(ActionListener action) { listeners.remove(action); } /** * 设置按钮的文本内容。这里设置到按钮左边部分。 */ @Override public void setText(String text) { textLabel.setText(text); } /** * 覆盖父类的设置图标方法。设置按钮的图标,这里是设置按钮左边部分图标。 */ @Override public void setIcon(Icon icon){ textLabel.setIcon(icon); } /** * 设置点击右边箭头按钮时的菜单 * * @param popupMenu */ public void setOptionPopMenu(JPopupMenu popupMenu) { this.optionPopMenu = popupMenu; } /** * 获取右边箭头按钮的菜单 * * @return */ public JPopupMenu getOptionPopMenu() { return optionPopMenu; } /** * 获得按钮左边部分菜单 * * @return */ public JPopupMenu getButtonPopMenu() { return buttonPopMenu; } /** * 设置箭头左边部分菜单 * * @param buttonPopMenu */ public void setButtonPopMenu(JPopupMenu buttonPopMenu) { this.buttonPopMenu = buttonPopMenu; } }
再贴出测试类代码如下:
/** * All rights reserved,2010,mengke */ package com.mengke.j2se.ui.test; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JFrame; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import com.mengke.j2se.swing.JSplitButton; /** *@author mengke * @email wqjsir@foxmail.com *@version 2011-1-15下午11:35:31 */ public class JSplitButtonTest { public static void main(String[] args) { JSplitButton button = new JSplitButton("splitButton"); button.setSeparatorVisible(false); button.setBorderColor(Color.green); button.setLocationLeft(false); //button.setIcon(new ImageIcon("./images/option_7x7.png")); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("点击了按钮左边部分"); } }); JFrame frame = new JFrame(); JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER,20,20)); JPopupMenu popMenu = new JPopupMenu(); popMenu.add(new JMenuItem("Item1")); popMenu.add(new JMenuItem("Item2")); popMenu.add(new JMenuItem("Item3")); button.setOptionPopMenu(popMenu); panel.add(button); frame.add(panel); frame.setSize(new Dimension(200, 300)); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }
一切OK了。
相关文章推荐
- 带下拉箭头的按钮(JSplitButton)
- Qt 按钮菜单如何与按钮右边界对齐,并去掉下拉箭头
- 在工具栏上添加下拉箭头按钮
- VC实现工具栏的下拉箭头按钮
- 如何实现工具栏的下拉箭头按钮
- C#在button按钮上显示箭头
- Bootstrap 按钮组与下拉按钮(Button Groups & Button Dropdowns)
- 如何实现工具栏的下拉箭头按钮
- Delphi 下拉按钮实现-TRzMenuButton
- wpf 点击button,下拉Popup显示按钮或信息
- C#在button按钮上显示箭头
- backBarButtonItem 只要箭头不要文本,且点击空白区域不会触发按钮(强迫症后退按钮)
- VC.NET界面编程中关于的ToolBar(工具栏)的编程应用(二)2008/07/01 19:22 上回说到给工具栏上添加IE风格的下拉菜单按钮,我们通过设置工具栏按钮的风格已经完成了下拉菜单按钮的添加,现在我们准备为下拉菜单按钮中响应下拉箭头部分的实现
- button按钮通过JSP给table添加下拉列表
- webparts的最小化,恢复按钮消失(无下拉箭头)
- 如何重载ComboBox 使其下拉按钮(带下箭头的)和下拉列表的垂直滚动条的宽度改变?(自绘ComboBox)
- Bootstrap 组件 - 按钮组与下拉按钮(Button Groups & Button Dropdowns)
- 回到顶部,当页面下拉到一定高度时,就会出现回到顶部的按钮,点击回到顶部之后,会有一个速度的变化回滚到顶部,如果正在回到顶部时,鼠标的滚轮转动了就会停止回到顶部
- iOS中修改头部tabBarButton 默认按钮的颜色和默认字体颜色
- Android开发中Button按钮绑定监听器的方式完全解析