当前位置:   article > 正文

swing自定义组件集合

swing自定义组件集合

1. 日期选择文本框

  1. package com.example.mybatis;
  2. import javax.imageio.ImageIO;
  3. import javax.swing.*;
  4. import javax.swing.border.Border;
  5. import javax.swing.plaf.ButtonUI;
  6. import javax.swing.plaf.ComboBoxUI;
  7. import java.awt.*;
  8. import java.awt.event.*;
  9. import java.awt.image.BufferedImage;
  10. import java.io.ByteArrayInputStream;
  11. import java.io.IOException;
  12. import java.util.Base64;
  13. import java.util.Calendar;
  14. import java.util.Date;
  15. public class DateField extends JPanel {
  16. private String buttonImg = "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kAASBJAggAQBJIAEASSABAEkgAQBJAggQQAJIEEACSBBAAkgQQAJAkgQQAJIEEACSBBAAkgQBJAAEgSQABIEkAASBJAAEgQBJIAEASSABAEkgAQBJAggQQAJIEEACSBBAAkgQQAJAkgQQAJIEEACSBBAAkgQQIIAEgSQABIEkAASBJAAEgSQIIAEASSABAEkgAQBJIAEASQIIEEACSBBAAkgQQAJIEEQQAJIEEACSBBAAkgQQAJIEASQABIEkAASBJDKCaSPP7wdsr0W/goglRik2+GVExQASCUG6avwygmSAFKJQfokvAJIEECCABJAggASQIIAEkACSAAJAkgQQAJIEEACSBBAAkgACSABJIAEASSABAEkgAQBJIAEkAASQAJIEEACSBBAAkgQQAJIAAkgASSABAEkgAQBJIAEASQIIAEkgASQIIAEkCCABJAggAQBJIAEkAASBJAAEgSQABJAAkgQQIIAEkCCABJAggASQAJIAAkCSBBAAkgQQAJIEEACSAAJIAEkgAQBJIAEASSApBTVbafdbK5uv4/3s31/Mvuzf8ifT1+/y+TPPu00F0AqX5C+TkzXQbyf3WH+Z6/gtrLJ/A9/BCCVL0gLzc+nH/N+dmDQ9M8e47Zyk+mfveN0gFS+IC0GSAAJIAEkgASQABJAAkgACSABJIAEkAASQAJIAAkgASSABJAAEkACSAAJIAEkCCABJIAEkAASQAJIAAkgASSABJAggASQABJAAkgACSABJIAEkAASQIIAEkACSAAJIAEkgASQABJAAkgACQJIAAkgASSABJAAEkACSAAJIAEkwAGQABJAAkgACSABJIAEkAASQAJIAAkgASSABJAAEkACSAAJIAEkgASQABJAAkgACSABJIAEkAASQIIAEkACSAAJIAEkgASQSgbSXu4PPw1wACSAlFWRCj5FwAZAAkgQQAJIAAkgASSABJAAEkCCABJAggASQAJIAAkgASSABJAAEgSQABIEkAASQAJIAAkgQQAJIEEACSBBAAkgASSABJAAEgSQABIEkAASBJAAEkACSAAJIEEACSBBAAkgQQAJIAEkgASQABIEkAASBJAAEkACSAAJIAEkgASQIIAEkCCABJAAEkACSAAJIAEkgAQBJIAEASSABJAAEkACSBBAAkgQQAJIEEACSAAJIAEkgAQBJIAEWR2kx80H6c+8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";
  17. private JTextField tfDate;
  18. private JButton button;
  19. private JDialog dlg;
  20. private JPanel paCalendar;
  21. private Integer fontSize = 15;
  22. private boolean show;
  23. private JComboBox cboYear;
  24. private JComboBox cboMonth;
  25. private JLabel[] lbls = new JLabel[7];
  26. private JToggleButton[] toggles = new JToggleButton[42];
  27. private Border border;
  28. private Color bgColor;
  29. private int width = 150, height = 25;
  30. private int year;
  31. private int month;
  32. private int date;
  33. private int dayOfWeek;
  34. private String[] week = {"日", "一", "二", "三", "四", "五", "六"};
  35. public DateField() {
  36. year = Calendar.getInstance().get(Calendar.YEAR);
  37. month = Calendar.getInstance().get(Calendar.MONTH) + 1;
  38. date = Calendar.getInstance().get(Calendar.DATE);
  39. dayOfWeek = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
  40. initUI();
  41. initDateDialog();
  42. updateField();
  43. }
  44. private void initUI() {
  45. tfDate = new JTextField();
  46. tfDate.setEditable(false);
  47. tfDate.setBackground(Color.WHITE);
  48. border = tfDate.getBorder();
  49. tfDate.setBorder(null);
  50. tfDate.setFont(new Font("宋体", Font.PLAIN, fontSize));
  51. button = new JButton();
  52. button.setIcon(base64ToImage());
  53. button.setPreferredSize(new Dimension(height, height));
  54. button.addActionListener(e -> {
  55. if (show == false) {
  56. dlg.setLocation(DateField.this.getLocationOnScreen().x, DateField.this.getLocationOnScreen().y + DateField.this.height);
  57. dlg.setAlwaysOnTop(true);
  58. dlg.setVisible(true);
  59. } else {
  60. dlg.dispose();
  61. }
  62. updateField();
  63. show = !show;
  64. });
  65. this.bgColor = this.getBackground();
  66. this.setOpaque(false);
  67. this.setLayout(new BorderLayout(0, 0));
  68. this.setBorder(border);
  69. this.add(tfDate, BorderLayout.CENTER);
  70. this.add(button, BorderLayout.EAST);
  71. }
  72. private void initDateDialog() {
  73. dlg = new JDialog();
  74. dlg.setUndecorated(true);
  75. paCalendar = new JPanel(new BorderLayout());
  76. paCalendar.setBorder(this.border);
  77. paCalendar.setBackground(this.bgColor);
  78. int borderWidth = 3;
  79. // 初始化两个下拉组件用于年和月的选择
  80. JPanel paHeader = new JPanel(new GridLayout(1, 2, borderWidth, borderWidth));
  81. paHeader.setOpaque(false);
  82. paHeader.setPreferredSize(new Dimension(this.width, this.height + borderWidth));
  83. paHeader.setBorder(BorderFactory.createEmptyBorder(borderWidth, borderWidth, borderWidth, borderWidth));
  84. paHeader.add(cboYear = new JComboBox());
  85. paHeader.add(cboMonth = new JComboBox());
  86. initYearModel();
  87. initMonthModel();
  88. paCalendar.add(paHeader, BorderLayout.NORTH);
  89. // 初始化日期组件
  90. JPanel paDay = new JPanel();
  91. paDay.setOpaque(false);
  92. paDay.setPreferredSize(new Dimension(this.height * 7, this.height * 7));
  93. initDate(paDay);
  94. paCalendar.add(paDay, BorderLayout.CENTER);
  95. dlg.setContentPane(paCalendar);
  96. dlg.pack();
  97. dlg.addWindowFocusListener(new WindowAdapter() {
  98. public void windowLostFocus(WindowEvent e) {
  99. dlg.dispose();
  100. }
  101. });
  102. }
  103. private void initYearModel() {
  104. for (int y = 1970; y < 2033; y++)
  105. cboYear.addItem(y);
  106. cboYear.setSelectedItem(year);
  107. cboYear.addItemListener(new ItemListener() {
  108. public void itemStateChanged(ItemEvent e) {
  109. year = Integer.parseInt(cboYear.getSelectedItem().toString());
  110. updateComponent();
  111. }
  112. });
  113. }
  114. private void initMonthModel() {
  115. for (int m = 1; m <= 12; m++)
  116. cboMonth.addItem(m);
  117. cboMonth.setSelectedItem(month);
  118. cboMonth.addItemListener(new ItemListener() {
  119. public void itemStateChanged(ItemEvent e) {
  120. month = Integer.parseInt(cboMonth.getSelectedItem().toString());
  121. updateComponent();
  122. }
  123. });
  124. }
  125. private void initDate(JPanel pa) {
  126. pa.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
  127. // 显示日历的标签栏
  128. for (int i = 0; i < week.length; i++) {
  129. lbls[i] = new JLabel(week[i]);
  130. lbls[i].setHorizontalAlignment(SwingConstants.CENTER);
  131. lbls[i].setOpaque(true);
  132. lbls[i].setBackground(Color.WHITE);
  133. lbls[i].setPreferredSize(new Dimension(this.height, this.height));
  134. pa.add(lbls[i]);
  135. }
  136. // 加载日历按钮
  137. ButtonGroup group = new ButtonGroup();
  138. for (int i = 0; i < 42; i++) {
  139. toggles[i] = new JToggleButton();
  140. toggles[i].setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
  141. toggles[i].setPreferredSize(new Dimension(this.height, this.height));
  142. toggles[i].addActionListener(new ActionListener() {
  143. public void actionPerformed(ActionEvent e) {
  144. date = Integer.parseInt(((JToggleButton) e.getSource()).getText().toString());
  145. dlg.dispose();
  146. updateField();
  147. }
  148. });
  149. group.add(toggles[i]);
  150. pa.add(toggles[i]);
  151. }
  152. updateComponent();
  153. }
  154. private void updateComponent() {
  155. if (cboYear == null || cboMonth == null)
  156. return;
  157. Calendar cal = Calendar.getInstance();
  158. cal.set(year, month - 1, 1);
  159. // 根据当月的第一天是星期几来判断日历按钮的数字该从第几个按钮开始显示
  160. int off = cal.get(Calendar.DAY_OF_WEEK) - 1;
  161. // 计算当月总共有几天
  162. int end = 30;
  163. if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
  164. end = 31;
  165. if (month == 2) {
  166. if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
  167. end = 29;
  168. else
  169. end = 28;
  170. }
  171. for (int i = 0; i < 42; i++) {
  172. if (i >= off && i <= end + off - 1) {
  173. int day = i - off + 1;
  174. toggles[i].setText(day + "");
  175. toggles[i].setEnabled(true);
  176. } else {
  177. toggles[i].setText("");
  178. toggles[i].setEnabled(false);
  179. }
  180. }
  181. // 使当天的按钮呈现被按下的效果
  182. int day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + off - 1;
  183. toggles[day].setSelected(true);
  184. }
  185. // 更新文本框内的文字
  186. private void updateField() {
  187. StringBuilder builder = new StringBuilder();
  188. builder.append(this.year + "年");
  189. builder.append(this.month + "月");
  190. builder.append(this.date + "日");
  191. Calendar cal = Calendar.getInstance();
  192. cal.set(this.year, this.month - 1, this.date);
  193. builder.append(" 星期" + week[cal.get(Calendar.DAY_OF_WEEK) - 1]);
  194. tfDate.setText(builder.toString());
  195. }
  196. private ImageIcon base64ToImage() {
  197. byte[] bytes = Base64.getDecoder().decode(buttonImg);
  198. //构建字节数组输入流
  199. ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
  200. //通过ImageIO把字节数组输入流转为BufferedImage
  201. BufferedImage bufferedImage = null;
  202. try {
  203. bufferedImage = ImageIO.read(bais);
  204. } catch (IOException e) {
  205. throw new RuntimeException(e);
  206. }
  207. Image image = bufferedImage.getScaledInstance(height, height, Image.SCALE_DEFAULT);
  208. ImageIcon imageIcon = new ImageIcon(image);
  209. return imageIcon;
  210. }
  211. public void setPreferredSize(Dimension preferredSize) {
  212. super.setPreferredSize(preferredSize);
  213. this.width = (int) preferredSize.getWidth();
  214. this.height = (int) preferredSize.getHeight();
  215. }
  216. /**
  217. * 设置字体
  218. *
  219. * @param fontSize
  220. */
  221. public void setFontSize(Integer fontSize) {
  222. tfDate.setFont(new Font("宋体", Font.PLAIN, fontSize));
  223. this.fontSize = fontSize;
  224. }
  225. /**
  226. * 设置文本框边框
  227. *
  228. * @param border
  229. */
  230. public void setBorder(Border border) {
  231. super.setBorder(border);
  232. }
  233. /**
  234. * 设置日历边框
  235. *
  236. * @param border
  237. */
  238. public void setCalendarBorder(Border border) {
  239. if (paCalendar != null) {
  240. paCalendar.setBorder(border);
  241. }
  242. }
  243. /**
  244. * 按钮UI样式
  245. *
  246. * @param clzUIName
  247. */
  248. public void setButtonUI(String clzUIName) {
  249. try {
  250. button.setUI((ButtonUI) Class.forName(clzUIName).newInstance());
  251. } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
  252. e.printStackTrace();
  253. }
  254. }
  255. /**
  256. * 日期按钮UI样式
  257. *
  258. * @param clzUIName
  259. */
  260. public void setDateButtonUI(String clzUIName) {
  261. try {
  262. for (int i = 0; i < 42; i++) {
  263. toggles[i].setUI((ButtonUI) Class.forName(clzUIName).newInstance());
  264. }
  265. } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
  266. // TODO Auto-generated catch block
  267. e.printStackTrace();
  268. }
  269. }
  270. /**
  271. * 设置下拉框UI样式
  272. *
  273. * @param clzUIName
  274. */
  275. public void setComboBoxUI(String clzUIName) {
  276. try {
  277. cboYear.setUI((ComboBoxUI) Class.forName(clzUIName).newInstance());
  278. cboMonth.setUI((ComboBoxUI) Class.forName(clzUIName).newInstance());
  279. } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
  280. e.printStackTrace();
  281. }
  282. }
  283. /**
  284. * 设置日历弹框的星期表头颜色
  285. *
  286. * @param fg 前景色,文本颜色
  287. * @param bg 背景色
  288. */
  289. public void setLableColor(Color fg, Color bg) {
  290. for (int i = 0; i < lbls.length; i++) {
  291. lbls[i].setForeground(fg);
  292. lbls[i].setBackground(bg);
  293. }
  294. }
  295. /**
  296. * 设置日期弹框按钮图标
  297. */
  298. public void setIcon(Image icon) {
  299. button.setIcon(new ImageIcon(icon));
  300. }
  301. /**
  302. * 获取选择的日期
  303. */
  304. public Date getDate() {
  305. Calendar cal = Calendar.getInstance();
  306. cal.set(this.year, this.month, this.date);
  307. return cal.getTime();
  308. }
  309. }

2. 自定义切换按钮

  1. package com.example.myswing;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.event.MouseAdapter;
  5. import java.awt.event.MouseEvent;
  6. import java.awt.geom.Arc2D;
  7. import java.awt.geom.Ellipse2D;
  8. import java.awt.geom.Path2D;
  9. public class ToggleButton extends JPanel {
  10. //绘制参数设定
  11. public Color bgColor = new Color(0xFFFFFF); //主背景色
  12. public Color lineColor = new Color(0xFFFFFF); //描边
  13. public Color darkColor = new Color(0xE1E1E1); //灰色填充
  14. public Color lightColor = new Color(0x33B4FF); //高亮填充
  15. public int padding = 2; //轮廓线与内部圆的距离
  16. private boolean selected = true; // 开关, ON/OFF
  17. //添加鼠标事件
  18. public ToggleButton() {
  19. this.addMouseListener(new MouseAdapter() {
  20. @Override
  21. public void mouseClicked(MouseEvent e) {
  22. onMouseClicked();
  23. }
  24. });
  25. }
  26. @Override//绘制
  27. protected void paintComponent(Graphics g) {
  28. // TODO Auto-generated method stub
  29. super.paintComponent(g);
  30. int width = this.getWidth();
  31. int height = this.getHeight();
  32. Graphics2D g2d = (Graphics2D) g;
  33. //平滑绘制(反锯齿)
  34. g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  35. // 算出一个2:1的最大矩形
  36. // Rectangle r = new Rectangle(0,0, 100, 50);
  37. int w = width;
  38. int h = width / 2;
  39. if (h > height) {
  40. h = height;
  41. w = height * 2;
  42. }
  43. Rectangle r = new Rectangle((width - w) / 2, (height - h) / 2, w, h);
  44. //里面两个并排圆, 外层轮廓为曲线
  45. //左半区
  46. Rectangle r1 = new Rectangle(r.x, r.y, r.width / 2, r.height);
  47. //右半区
  48. Rectangle r2 = new Rectangle(r.x + r.width / 2, r.y, r.width / 2, r.height);
  49. //绘制外部轮廓线
  50. Shape arc1 = new Arc2D.Double(r1, 90, 180, Arc2D.OPEN);
  51. Shape arc2 = new Arc2D.Double(r2, 270, 180, Arc2D.OPEN);
  52. Path2D outline = new Path2D.Double(); //外轮廓,使用拼装路径
  53. outline.append(arc1.getPathIterator(null), false);
  54. outline.append(arc2.getPathIterator(null), true); // 右半圆弧
  55. outline.closePath();
  56. g2d.setPaint(lineColor);
  57. g2d.draw(outline);
  58. g2d.setPaint(bgColor);
  59. g2d.fill(outline);
  60. //选择绘制的按钮
  61. if (selected) {
  62. drawCircleInside(g2d, r2, padding, lineColor, lightColor);
  63. } else {
  64. drawCircleInside(g2d, r1, padding, lineColor, darkColor);
  65. }
  66. }
  67. /**
  68. * 判断是否选中
  69. */
  70. public boolean isSelected() {
  71. return this.selected;
  72. }
  73. /**
  74. * 设置是否选中
  75. */
  76. public void setSelected(boolean selected) {
  77. this.selected = selected;
  78. repaint();
  79. }
  80. /**
  81. * 切换
  82. */
  83. public void toggle() {
  84. this.selected = !this.selected;
  85. repaint();
  86. }
  87. /**
  88. * 画内部的小圆
  89. */
  90. private void drawCircleInside(Graphics2D g2d, Rectangle rect, int deflate, Paint lineColor, Paint fillColor) {
  91. // 做一个备份,不会修改传入的rect
  92. Rectangle r = new Rectangle(rect);
  93. r.x += deflate;
  94. r.y += deflate;
  95. r.width -= (deflate * 2);
  96. r.height -= (deflate * 2);
  97. Shape shape = new Ellipse2D.Double(r.x, r.y, r.width, r.height);
  98. // 描边
  99. g2d.setPaint(lineColor);
  100. g2d.draw(shape);
  101. // 填充
  102. g2d.setPaint(fillColor);
  103. g2d.fill(shape);
  104. }
  105. //自定义接口
  106. public interface StateListener {
  107. void stateChanged(Object source);
  108. }
  109. private StateListener stateListener;//属性
  110. public void setStateListener(StateListener listener) {
  111. this.stateListener = listener;
  112. }
  113. //鼠标点击事件
  114. private void onMouseClicked() {
  115. toggle(); //点击时,切换状态
  116. //自定义接口
  117. if (stateListener != null) {
  118. stateListener.stateChanged(this);
  119. }
  120. }
  121. }

3. 复选框栏(全选功能)

  1. package com.example.mybatis;
  2. import javax.swing.*;
  3. import javax.swing.border.Border;
  4. import java.awt.*;
  5. import java.awt.event.ActionEvent;
  6. import java.awt.event.ActionListener;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9. import java.util.function.Predicate;
  10. public class CheckBoxBar extends JPanel {
  11. private JCheckBox allJCheckBox;
  12. private Border border;
  13. private int width = 200;
  14. private int height = 100;
  15. private List<JCheckBox> jCheckBoxList;
  16. public CheckBoxBar(List<JCheckBox> jCheckBoxList) {
  17. if (jCheckBoxList.size() < 2) {
  18. throw new RuntimeException("jCheckBoxList 大小不得小于2。");
  19. }
  20. this.allJCheckBox = jCheckBoxList.get(0);
  21. jCheckBoxList.remove(0);
  22. this.jCheckBoxList = jCheckBoxList;
  23. this.border = BorderFactory.createRaisedBevelBorder();
  24. initUI();
  25. }
  26. private void initUI() {
  27. this.setPreferredSize(new Dimension(width, height));
  28. this.setBorder(border);
  29. this.setLayout(new FlowLayout(FlowLayout.LEFT));
  30. allJCheckBox.addActionListener(new AllJCheckBoxListener());
  31. this.add(allJCheckBox);
  32. for (JCheckBox jCheckBox : jCheckBoxList) {
  33. jCheckBox.addActionListener(new OtherJCheckBoxListener());
  34. this.add(jCheckBox);
  35. }
  36. }
  37. class AllJCheckBoxListener implements ActionListener {
  38. @Override
  39. public void actionPerformed(ActionEvent e) {
  40. JCheckBox jCheck = (JCheckBox) e.getSource();
  41. if (jCheck.isSelected()) {
  42. for (JCheckBox jCheckBox : jCheckBoxList) {
  43. jCheckBox.setSelected(true);
  44. }
  45. } else {
  46. for (JCheckBox jCheckBox : jCheckBoxList) {
  47. jCheckBox.setSelected(false);
  48. }
  49. }
  50. }
  51. }
  52. class OtherJCheckBoxListener implements ActionListener {
  53. @Override
  54. public void actionPerformed(ActionEvent e) {
  55. JCheckBox jCheck = (JCheckBox) e.getSource();
  56. if (jCheck.isSelected() && isAllSelected()) {
  57. allJCheckBox.setSelected(true);
  58. } else {
  59. allJCheckBox.setSelected(false);
  60. }
  61. }
  62. }
  63. private boolean isAllSelected() {
  64. return jCheckBoxList.stream().allMatch(new Predicate<JCheckBox>() {
  65. @Override
  66. public boolean test(JCheckBox jCheckBox) {
  67. return jCheckBox.isSelected();
  68. }
  69. });
  70. }
  71. /**
  72. * 获取所有选中的值
  73. */
  74. public List<String> getSelectedValue() {
  75. List<String> list = new ArrayList<>();
  76. for (JCheckBox jCheckBox : jCheckBoxList) {
  77. if (jCheckBox.isSelected()) {
  78. list.add(jCheckBox.getText());
  79. }
  80. }
  81. return list;
  82. }
  83. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/918264
推荐阅读
相关标签
  

闽ICP备14008679号