swing自定义组件集合

1. 日期选择文本框

package com.example.mybatis;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.plaf.ButtonUI;
import javax.swing.plaf.ComboBoxUI;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;

public class DateField extends JPanel {
    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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";
    private JTextField tfDate;
    private JButton button;
    private JDialog dlg;
    private JPanel paCalendar;
    private Integer fontSize = 15;
    private boolean show;
    private JComboBox cboYear;
    private JComboBox cboMonth;
    private JLabel[] lbls = new JLabel[7];
    private JToggleButton[] toggles = new JToggleButton[42];
    private Border border;
    private Color bgColor;
    private int width = 150, height = 25;
    private int year;
    private int month;
    private int date;
    private int dayOfWeek;
    private String[] week = {"日", "一", "二", "三", "四", "五", "六"};

    public DateField() {
        year = Calendar.getInstance().get(Calendar.YEAR);
        month = Calendar.getInstance().get(Calendar.MONTH) + 1;
        date = Calendar.getInstance().get(Calendar.DATE);
        dayOfWeek = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
        initUI();
        initDateDialog();
        updateField();
    }

    private void initUI() {
        tfDate = new JTextField();
        tfDate.setEditable(false);
        tfDate.setBackground(Color.WHITE);
        border = tfDate.getBorder();
        tfDate.setBorder(null);
        tfDate.setFont(new Font("宋体", Font.PLAIN, fontSize));
        button = new JButton();
        button.setIcon(base64ToImage());
        button.setPreferredSize(new Dimension(height, height));
        button.addActionListener(e -> {
            if (show == false) {
                dlg.setLocation(DateField.this.getLocationOnScreen().x, DateField.this.getLocationOnScreen().y + DateField.this.height);
                dlg.setAlwaysOnTop(true);
                dlg.setVisible(true);
            } else {
                dlg.dispose();
            }
            updateField();
            show = !show;
        });

        this.bgColor = this.getBackground();

        this.setOpaque(false);
        this.setLayout(new BorderLayout(0, 0));
        this.setBorder(border);
        this.add(tfDate, BorderLayout.CENTER);
        this.add(button, BorderLayout.EAST);
    }

    private void initDateDialog() {
        dlg = new JDialog();
        dlg.setUndecorated(true);
        paCalendar = new JPanel(new BorderLayout());
        paCalendar.setBorder(this.border);
        paCalendar.setBackground(this.bgColor);

        int borderWidth = 3;
        // 初始化两个下拉组件用于年和月的选择
        JPanel paHeader = new JPanel(new GridLayout(1, 2, borderWidth, borderWidth));
        paHeader.setOpaque(false);
        paHeader.setPreferredSize(new Dimension(this.width, this.height + borderWidth));
        paHeader.setBorder(BorderFactory.createEmptyBorder(borderWidth, borderWidth, borderWidth, borderWidth));
        paHeader.add(cboYear = new JComboBox());
        paHeader.add(cboMonth = new JComboBox());
        initYearModel();
        initMonthModel();
        paCalendar.add(paHeader, BorderLayout.NORTH);

        // 初始化日期组件
        JPanel paDay = new JPanel();
        paDay.setOpaque(false);
        paDay.setPreferredSize(new Dimension(this.height * 7, this.height * 7));
        initDate(paDay);
        paCalendar.add(paDay, BorderLayout.CENTER);

        dlg.setContentPane(paCalendar);
        dlg.pack();
        dlg.addWindowFocusListener(new WindowAdapter() {
            public void windowLostFocus(WindowEvent e) {
                dlg.dispose();
            }
        });
    }

    private void initYearModel() {
        for (int y = 1970; y < 2033; y++)
            cboYear.addItem(y);
        cboYear.setSelectedItem(year);
        cboYear.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                year = Integer.parseInt(cboYear.getSelectedItem().toString());
                updateComponent();
            }

        });
    }

    private void initMonthModel() {
        for (int m = 1; m <= 12; m++)
            cboMonth.addItem(m);
        cboMonth.setSelectedItem(month);
        cboMonth.addItemListener(new ItemListener() {

            public void itemStateChanged(ItemEvent e) {
                month = Integer.parseInt(cboMonth.getSelectedItem().toString());
                updateComponent();
            }
        });
    }

    private void initDate(JPanel pa) {
        pa.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
        // 显示日历的标签栏
        for (int i = 0; i < week.length; i++) {
            lbls[i] = new JLabel(week[i]);
            lbls[i].setHorizontalAlignment(SwingConstants.CENTER);
            lbls[i].setOpaque(true);
            lbls[i].setBackground(Color.WHITE);
            lbls[i].setPreferredSize(new Dimension(this.height, this.height));
            pa.add(lbls[i]);
        }
        // 加载日历按钮
        ButtonGroup group = new ButtonGroup();
        for (int i = 0; i < 42; i++) {
            toggles[i] = new JToggleButton();
            toggles[i].setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
            toggles[i].setPreferredSize(new Dimension(this.height, this.height));
            toggles[i].addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    date = Integer.parseInt(((JToggleButton) e.getSource()).getText().toString());
                    dlg.dispose();
                    updateField();
                }
            });
            group.add(toggles[i]);
            pa.add(toggles[i]);
        }
        updateComponent();
    }

    private void updateComponent() {
        if (cboYear == null || cboMonth == null)
            return;
        Calendar cal = Calendar.getInstance();
        cal.set(year, month - 1, 1);
        // 根据当月的第一天是星期几来判断日历按钮的数字该从第几个按钮开始显示
        int off = cal.get(Calendar.DAY_OF_WEEK) - 1;
        // 计算当月总共有几天
        int end = 30;
        if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
            end = 31;
        if (month == 2) {
            if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
                end = 29;
            else
                end = 28;
        }
        for (int i = 0; i < 42; i++) {
            if (i >= off && i <= end + off - 1) {
                int day = i - off + 1;
                toggles[i].setText(day + "");
                toggles[i].setEnabled(true);
            } else {
                toggles[i].setText("");
                toggles[i].setEnabled(false);
            }
        }
        // 使当天的按钮呈现被按下的效果
        int day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + off - 1;
        toggles[day].setSelected(true);
    }

    // 更新文本框内的文字
    private void updateField() {
        StringBuilder builder = new StringBuilder();
        builder.append(this.year + "年");
        builder.append(this.month + "月");
        builder.append(this.date + "日");
        Calendar cal = Calendar.getInstance();
        cal.set(this.year, this.month - 1, this.date);
        builder.append(" 星期" + week[cal.get(Calendar.DAY_OF_WEEK) - 1]);
        tfDate.setText(builder.toString());
    }

    private ImageIcon base64ToImage() {
        byte[] bytes = Base64.getDecoder().decode(buttonImg);
        //构建字节数组输入流
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        //通过ImageIO把字节数组输入流转为BufferedImage
        BufferedImage bufferedImage = null;
        try {
            bufferedImage = ImageIO.read(bais);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        Image image = bufferedImage.getScaledInstance(height, height, Image.SCALE_DEFAULT);
        ImageIcon imageIcon = new ImageIcon(image);
        return imageIcon;
    }

    public void setPreferredSize(Dimension preferredSize) {
        super.setPreferredSize(preferredSize);
        this.width = (int) preferredSize.getWidth();
        this.height = (int) preferredSize.getHeight();
    }

    /**
     * 设置字体
     *
     * @param fontSize
     */
    public void setFontSize(Integer fontSize) {
        tfDate.setFont(new Font("宋体", Font.PLAIN, fontSize));
        this.fontSize = fontSize;
    }

    /**
     * 设置文本框边框
     *
     * @param border
     */
    public void setBorder(Border border) {
        super.setBorder(border);
    }

    /**
     * 设置日历边框
     *
     * @param border
     */
    public void setCalendarBorder(Border border) {
        if (paCalendar != null) {
            paCalendar.setBorder(border);
        }
    }

    /**
     * 按钮UI样式
     *
     * @param clzUIName
     */
    public void setButtonUI(String clzUIName) {
        try {
            button.setUI((ButtonUI) Class.forName(clzUIName).newInstance());
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 日期按钮UI样式
     *
     * @param clzUIName
     */
    public void setDateButtonUI(String clzUIName) {
        try {
            for (int i = 0; i < 42; i++) {
                toggles[i].setUI((ButtonUI) Class.forName(clzUIName).newInstance());
            }
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 设置下拉框UI样式
     *
     * @param clzUIName
     */
    public void setComboBoxUI(String clzUIName) {
        try {
            cboYear.setUI((ComboBoxUI) Class.forName(clzUIName).newInstance());
            cboMonth.setUI((ComboBoxUI) Class.forName(clzUIName).newInstance());
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置日历弹框的星期表头颜色
     *
     * @param fg 前景色,文本颜色
     * @param bg 背景色
     */
    public void setLableColor(Color fg, Color bg) {
        for (int i = 0; i < lbls.length; i++) {
            lbls[i].setForeground(fg);
            lbls[i].setBackground(bg);
        }
    }

    /**
     * 设置日期弹框按钮图标
     */
    public void setIcon(Image icon) {
        button.setIcon(new ImageIcon(icon));
    }

    /**
     * 获取选择的日期
     */
    public Date getDate() {
        Calendar cal = Calendar.getInstance();
        cal.set(this.year, this.month, this.date);
        return cal.getTime();
    }
}

2. 自定义切换按钮

package com.example.myswing;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;

public class ToggleButton extends JPanel {
    //绘制参数设定
    public Color bgColor = new Color(0xFFFFFF); //主背景色
    public Color lineColor = new Color(0xFFFFFF); //描边
    public Color darkColor = new Color(0xE1E1E1); //灰色填充
    public Color lightColor = new Color(0x33B4FF); //高亮填充
    public int padding = 2;  //轮廓线与内部圆的距离
    private boolean selected = true; // 开关, ON/OFF

    //添加鼠标事件
    public ToggleButton() {
        this.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                onMouseClicked();
            }

        });
    }

    @Override//绘制
    protected void paintComponent(Graphics g) {
        // TODO Auto-generated method stub
        super.paintComponent(g);
        int width = this.getWidth();
        int height = this.getHeight();
        Graphics2D g2d = (Graphics2D) g;

        //平滑绘制(反锯齿)
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // 算出一个2:1的最大矩形
        // Rectangle r = new Rectangle(0,0, 100, 50);
        int w = width;
        int h = width / 2;
        if (h > height) {
            h = height;
            w = height * 2;
        }
        Rectangle r = new Rectangle((width - w) / 2, (height - h) / 2, w, h);
        //里面两个并排圆, 外层轮廓为曲线
        //左半区
        Rectangle r1 = new Rectangle(r.x, r.y, r.width / 2, r.height);
        //右半区
        Rectangle r2 = new Rectangle(r.x + r.width / 2, r.y, r.width / 2, r.height);
        //绘制外部轮廓线
        Shape arc1 = new Arc2D.Double(r1, 90, 180, Arc2D.OPEN);
        Shape arc2 = new Arc2D.Double(r2, 270, 180, Arc2D.OPEN);

        Path2D outline = new Path2D.Double(); //外轮廓,使用拼装路径
        outline.append(arc1.getPathIterator(null), false);
        outline.append(arc2.getPathIterator(null), true);  // 右半圆弧
        outline.closePath();
        g2d.setPaint(lineColor);
        g2d.draw(outline);
        g2d.setPaint(bgColor);
        g2d.fill(outline);
        //选择绘制的按钮
        if (selected) {
            drawCircleInside(g2d, r2, padding, lineColor, lightColor);
        } else {
            drawCircleInside(g2d, r1, padding, lineColor, darkColor);
        }
    }

    /**
     * 判断是否选中
     */
    public boolean isSelected() {
        return this.selected;
    }

    /**
     * 设置是否选中
     */
    public void setSelected(boolean selected) {
        this.selected = selected;
        repaint();
    }

    /**
     * 切换
     */
    public void toggle() {
        this.selected = !this.selected;
        repaint();
    }


    /**
     * 画内部的小圆
     */
    private void drawCircleInside(Graphics2D g2d, Rectangle rect, int deflate, Paint lineColor, Paint fillColor) {
        // 做一个备份,不会修改传入的rect
        Rectangle r = new Rectangle(rect);
        r.x += deflate;
        r.y += deflate;
        r.width -= (deflate * 2);
        r.height -= (deflate * 2);
        Shape shape = new Ellipse2D.Double(r.x, r.y, r.width, r.height);
        // 描边
        g2d.setPaint(lineColor);
        g2d.draw(shape);
        // 填充
        g2d.setPaint(fillColor);
        g2d.fill(shape);
    }

    //自定义接口
    public interface StateListener {
        void stateChanged(Object source);
    }
    private StateListener stateListener;//属性
    public void setStateListener(StateListener listener) {
        this.stateListener = listener;
    }
    //鼠标点击事件
    private void onMouseClicked() {
        toggle(); //点击时,切换状态
        //自定义接口
        if (stateListener != null) {
            stateListener.stateChanged(this);
        }
    }

}

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

package com.example.mybatis;

import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

public class CheckBoxBar extends JPanel {
    private JCheckBox allJCheckBox;
    private Border border;
    private int width = 200;
    private int height = 100;
    private List<JCheckBox> jCheckBoxList;

    public CheckBoxBar(List<JCheckBox> jCheckBoxList) {
        if (jCheckBoxList.size() < 2) {
            throw new RuntimeException("jCheckBoxList 大小不得小于2。");
        }
        this.allJCheckBox = jCheckBoxList.get(0);
        jCheckBoxList.remove(0);
        this.jCheckBoxList = jCheckBoxList;
        this.border = BorderFactory.createRaisedBevelBorder();
        initUI();

    }

    private void initUI() {
        this.setPreferredSize(new Dimension(width, height));
        this.setBorder(border);
        this.setLayout(new FlowLayout(FlowLayout.LEFT));
        allJCheckBox.addActionListener(new AllJCheckBoxListener());
        this.add(allJCheckBox);
        for (JCheckBox jCheckBox : jCheckBoxList) {
            jCheckBox.addActionListener(new OtherJCheckBoxListener());
            this.add(jCheckBox);
        }
    }

    class AllJCheckBoxListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            JCheckBox jCheck = (JCheckBox) e.getSource();
            if (jCheck.isSelected()) {
                for (JCheckBox jCheckBox : jCheckBoxList) {
                    jCheckBox.setSelected(true);
                }
            } else {
                for (JCheckBox jCheckBox : jCheckBoxList) {
                    jCheckBox.setSelected(false);
                }
            }
        }
    }

    class OtherJCheckBoxListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            JCheckBox jCheck = (JCheckBox) e.getSource();
            if (jCheck.isSelected() && isAllSelected()) {
                allJCheckBox.setSelected(true);
            } else {
                allJCheckBox.setSelected(false);
            }
        }
    }

    private boolean isAllSelected() {
        return jCheckBoxList.stream().allMatch(new Predicate<JCheckBox>() {
            @Override
            public boolean test(JCheckBox jCheckBox) {
                return jCheckBox.isSelected();
            }
        });
    }

    /**
     * 获取所有选中的值
     */
    public List<String> getSelectedValue() {
        List<String> list = new ArrayList<>();
        for (JCheckBox jCheckBox : jCheckBoxList) {
            if (jCheckBox.isSelected()) {
                list.add(jCheckBox.getText());
            }
        }
        return list;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郑重其事,鹏程万里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值