packagecom.tfj.demo;importjava.awt.BasicStroke;importjava.awt.BorderLayout;importjava.awt.Color;importjava.awt.Component;importjava.awt.Cursor;importjava.awt.Dimension;importjava.awt.Font;importjava.awt.Graphics;importjava.awt.Graphics2D;importjava.awt.GridLayout;importjava.awt.Point;importjava.awt.Polygon;importjava.awt.Stroke;importjava.awt.Toolkit;importjava.awt.event.FocusEvent;importjava.awt.event.FocusListener;importjava.awt.event.MouseAdapter;importjava.awt.event.MouseEvent;importjava.awt.event.MouseListener;importjava.awt.event.MouseMotionListener;importjava.text.SimpleDateFormat;importjava.util.ArrayList;importjava.util.Calendar;importjava.util.Comparator;importjava.util.Date;importjava.util.List;importjavax.swing.BorderFactory;importjavax.swing.JButton;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JPanel;importjavax.swing.Popup;importjavax.swing.PopupFactory;importjavax.swing.SwingUtilities;importjavax.swing.event.AncestorEvent;importjavax.swing.event.AncestorListener;/***@authorJacksile E-mail:tufujietec@foxmail.com
* @date 2016年4月13日 下午3:32:23
* @function*/
public class DateChooserDay extendsJPanel {private static final long serialVersionUID = 4529266044762990227L;privateDate initDate;private Calendar now =Calendar.getInstance();privateCalendar select;private JPanel monthPanel;//月历
private JP1 jp1;//四块面板,组成
privateJP2 jp2;privateJP3 jp3;privateJP4 jp4;private Font font = new Font("宋体", Font.PLAIN, 12);private final LabelManager lm = newLabelManager();private JLabel showDate; //,toSelect;
privateSimpleDateFormat sdf;private boolean isShow = false;privatePopup pop;private static final int WIDTH = 400;private static final int HEIGHT = 100;/*** Creates a new instance of DateChooser*/
publicDateChooserDay() {this(newDate());
}publicDateChooserDay(Date date) {this(date, "yyyy年MM月dd日");
}publicDateChooserDay(String format) {this(newDate(), format);
}publicDateChooserDay(Date date, String format) {
initDate=date;
sdf= newSimpleDateFormat(format);
select=Calendar.getInstance();
select.setTime(initDate);
initPanel();
initLabel();
}/*** 是否允许用户选择*/
public void setEnabled(booleanb) {super.setEnabled(b);
showDate.setEnabled(b);
}/*** 得到当前选择框的日期*/
publicDate getDate() {returnselect.getTime();
}//根据初始化的日期,初始化面板
private voidinitPanel() {
monthPanel= new JPanel(newBorderLayout());
monthPanel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
JPanel up= new JPanel(newBorderLayout());
up.add(jp1= newJP1(), BorderLayout.NORTH);
up.add(jp2= newJP2(), BorderLayout.CENTER);
monthPanel.add(jp3= newJP3(), BorderLayout.CENTER);
monthPanel.add(up, BorderLayout.NORTH);
monthPanel.add(jp4= newJP4(), BorderLayout.SOUTH);this.addAncestorListener(newAncestorListener() {public voidancestorAdded(AncestorEvent event) {
}public voidancestorRemoved(AncestorEvent event) {
}//只要祖先组件一移动,马上就让popup消失
public voidancestorMoved(AncestorEvent event) {
hidePanel();
}
});
}//初始化标签
private voidinitLabel() {
showDate= newJLabel(sdf.format(initDate));
showDate.setRequestFocusEnabled(true);
showDate.addMouseListener(newMouseAdapter() {public voidmousePressed(MouseEvent me) {
showDate.requestFocusInWindow();
}
});//toSelect=new JLabel(sdf.format(initDate));//toSelect.setBorder(BorderFactory.createLineBorder(Color.BLACK));//toSelect.setRequestFocusEnabled(true);
this.setBackground(Color.WHITE);this.add(showDate, BorderLayout.CENTER);//this.add(toSelect,BorderLayout.EAST);
this.setPreferredSize(new Dimension(90, 25));this.setBorder(BorderFactory.createLineBorder(Color.GRAY));
showDate.addMouseListener(newMouseAdapter() {public voidmouseEntered(MouseEvent me) {if(showDate.isEnabled()) {
showDate.setCursor(newCursor(Cursor.HAND_CURSOR));
showDate.setForeground(Color.RED);
}
}public voidmouseExited(MouseEvent me) {if(showDate.isEnabled()) {
showDate.setCursor(newCursor(Cursor.DEFAULT_CURSOR));
showDate.setForeground(Color.BLACK);
}
}public voidmousePressed(MouseEvent me) {if(showDate.isEnabled()) {
showDate.setForeground(Color.CYAN);if(isShow) {
hidePanel();
}else{
showPanel(showDate);
}
}
}public voidmouseReleased(MouseEvent me) {if(showDate.isEnabled()) {
showDate.setForeground(Color.BLACK);
}
}
});
showDate.addFocusListener(newFocusListener() {public voidfocusLost(FocusEvent e) {
hidePanel();
}public voidfocusGained(FocusEvent e) {
}
});
}//根据新的日期刷新
private voidrefresh() {
jp1.updateDate();
jp3.updateDate();
SwingUtilities.updateComponentTreeUI(this);
}//提交日期
private voidcommit() {
System.out.println("选中的日期是:" +sdf.format(select.getTime()));
showDate.setText(sdf.format(select.getTime()));
hidePanel();
}//隐藏日期选择面板
private voidhidePanel() {if (pop != null) {
isShow= false;
pop.hide();
pop= null;
}
}//显示日期选择面板
private voidshowPanel(Component owner) {if (pop != null) {
pop.hide();
}
Point show= new Point(0, showDate.getHeight());
SwingUtilities.convertPointToScreen(show, showDate);
Dimension size=Toolkit.getDefaultToolkit().getScreenSize();int x =show.x;int y =show.y;if (x < 0) {
x= 0;
}if (x > size.width - 295) {
x= size.width - 295;
}if (y < size.height - 170) {
}else{
y-= 188;
}
pop=PopupFactory.getSharedInstance().getPopup(owner, monthPanel, x, y);
pop.show();
isShow= true;
}/*** 最上面的面板用来显示月份的增减*/
private class JP1 extendsJPanel {
JLabel yearleft, yearright, monthleft, monthright, center, centercontainer;publicJP1() {super(newBorderLayout());this.setBackground(new Color(160, 185, 215));
initJP1();
}private voidinitJP1() {
yearleft= new JLabel(" <
yearleft.setToolTipText("上一年");
yearright= new JLabel(">> ", JLabel.CENTER);
yearright.setToolTipText("下一年");
yearleft.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
yearright.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
monthleft= new JLabel("
monthleft.setToolTipText("上一月");
monthright= new JLabel("> ", JLabel.LEFT);
monthright.setToolTipText("下一月");
monthleft.setBorder(BorderFactory.createEmptyBorder(2, 30, 0, 0));
monthright.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 30));
centercontainer= new JLabel("", JLabel.CENTER);
centercontainer.setLayout(newBorderLayout());
center= new JLabel("", JLabel.CENTER);
centercontainer.add(monthleft, BorderLayout.WEST);
centercontainer.add(center, BorderLayout.CENTER);
centercontainer.add(monthright, BorderLayout.EAST);this.add(yearleft, BorderLayout.WEST);this.add(centercontainer, BorderLayout.CENTER);this.add(yearright, BorderLayout.EAST);this.setPreferredSize(new Dimension(295, 25));
updateDate();
yearleft.addMouseListener(newMouseAdapter() {public voidmouseEntered(MouseEvent me) {
yearleft.setCursor(newCursor(Cursor.HAND_CURSOR));
yearleft.setForeground(Color.RED);
}public voidmouseExited(MouseEvent me) {
yearleft.setCursor(newCursor(Cursor.DEFAULT_CURSOR));
yearleft.setForeground(Color.BLACK);
}public voidmousePressed(MouseEvent me) {
select.add(Calendar.YEAR,-1);
yearleft.setForeground(Color.WHITE);
refresh();
}public voidmouseReleased(MouseEvent me) {
yearleft.setForeground(Color.BLACK);
}
});
yearright.addMouseListener(newMouseAdapter() {public voidmouseEntered(MouseEvent me) {
yearright.setCursor(newCursor(Cursor.HAND_CURSOR));
yearright.setForeground(Color.RED);
}public voidmouseExited(MouseEvent me) {
yearright.setCursor(newCursor(Cursor.DEFAULT_CURSOR));
yearright.setForeground(Color.BLACK);
}public voidmousePressed(MouseEvent me) {
select.add(Calendar.YEAR,1);
yearright.setForeground(Color.WHITE);
refresh();
}public voidmouseReleased(MouseEvent me) {
yearright.setForeground(Color.BLACK);
}
});
monthleft.addMouseListener(newMouseAdapter() {public voidmouseEntered(MouseEvent me) {
monthleft.setCursor(newCursor(Cursor.HAND_CURSOR));
monthleft.setForeground(Color.RED);
}public voidmouseExited(MouseEvent me) {
monthleft.setCursor(newCursor(Cursor.DEFAULT_CURSOR));
monthleft.setForeground(Color.BLACK);
}public voidmousePressed(MouseEvent me) {
select.add(Calendar.MONTH,-1);
monthleft.setForeground(Color.WHITE);
refresh();
}public voidmouseReleased(MouseEvent me) {
monthleft.setForeground(Color.BLACK);
}
});
monthright.addMouseListener(newMouseAdapter() {public voidmouseEntered(MouseEvent me) {
monthright.setCursor(newCursor(Cursor.HAND_CURSOR));
monthright.setForeground(Color.RED);
}public voidmouseExited(MouseEvent me) {
monthright.setCursor(newCursor(Cursor.DEFAULT_CURSOR));
monthright.setForeground(Color.BLACK);
}public voidmousePressed(MouseEvent me) {
select.add(Calendar.MONTH,1);
monthright.setForeground(Color.WHITE);
refresh();
}public voidmouseReleased(MouseEvent me) {
monthright.setForeground(Color.BLACK);
}
});
}private voidupdateDate() {
center.setText(select.get(Calendar.YEAR)+ "年" + (select.get(Calendar.MONTH) + 1) + "月");
}
}private class JP2 extendsJPanel {publicJP2() {this.setPreferredSize(new Dimension(295, 20));
}protected voidpaintComponent(Graphics g) {
g.setFont(font);
g.drawString("星期日 星期一 星期二 星期三 星期四 星期五 星期六", 5, 10);
g.drawLine(0, 15, getWidth(), 15);
}
}private class JP3 extendsJPanel {publicJP3() {super(new GridLayout(6, 7));this.setPreferredSize(new Dimension(295, 100));
initJP3();
}private voidinitJP3() {
updateDate();
}public voidupdateDate() {this.removeAll();
lm.clear();
Date temp=select.getTime();
Calendar select=Calendar.getInstance();
select.setTime(temp);
select.set(Calendar.DAY_OF_MONTH,1);int index =select.get(Calendar.DAY_OF_WEEK);int sum = (index == 1 ? 8: index);
select.add(Calendar.DAY_OF_MONTH,0 -sum);for (int i = 0; i < 42; i++) {
select.add(Calendar.DAY_OF_MONTH,1);
lm.addLabel(newMyLabel(select.get(Calendar.YEAR), select.get(Calendar.MONTH),
select.get(Calendar.DAY_OF_MONTH)));
}for(MyLabel my : lm.getLabels()) {this.add(my);
}
select.setTime(temp);
}
}private class MyLabel extends JLabel implements Comparator, MouseListener, MouseMotionListener {private intyear, month, day;private booleanisSelected;public MyLabel(int year, int month, intday) {super("" +day, JLabel.CENTER);this.year =year;this.day =day;this.month =month;this.addMouseListener(this);this.addMouseMotionListener(this);this.setFont(font);if (month ==select.get(Calendar.MONTH)) {this.setForeground(Color.BLACK);
}else{this.setForeground(Color.LIGHT_GRAY);
}if (day ==select.get(Calendar.DAY_OF_MONTH)) {this.setBackground(new Color(160, 185, 215));
}else{this.setBackground(Color.WHITE);
}
}public booleangetIsSelected() {returnisSelected;
}public void setSelected(boolean b, booleanisDrag) {
isSelected=b;if (b && !isDrag) {int temp =select.get(Calendar.MONTH);
select.set(year, month, day);if (temp ==month) {
SwingUtilities.updateComponentTreeUI(jp3);
}else{
refresh();
}
}this.repaint();
}protected voidpaintComponent(Graphics g) {if (day == select.get(Calendar.DAY_OF_MONTH) && month ==select.get(Calendar.MONTH)) {//如果当前日期是选择日期,则高亮显示
g.setColor(new Color(160, 185, 215));
g.fillRect(0, 0, getWidth(), getHeight());
}if (year == now.get(Calendar.YEAR) && month ==now.get(Calendar.MONTH)&& day ==now.get(Calendar.DAY_OF_MONTH)) {//如果日期和当前日期一样,则用红框
Graphics2D gd =(Graphics2D) g;
gd.setColor(Color.RED);
Polygon p= newPolygon();
p.addPoint(0, 0);
p.addPoint(getWidth()- 1, 0);
p.addPoint(getWidth()- 1, getHeight() - 1);
p.addPoint(0, getHeight() - 1);
gd.drawPolygon(p);
}if (isSelected) {//如果被选中了就画出一个虚线框出来
Stroke s = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 1.0f,new float[] { 2.0f, 2.0f }, 1.0f);
Graphics2D gd=(Graphics2D) g;
gd.setStroke(s);
gd.setColor(Color.BLACK);
Polygon p= newPolygon();
p.addPoint(0, 0);
p.addPoint(getWidth()- 1, 0);
p.addPoint(getWidth()- 1, getHeight() - 1);
p.addPoint(0, getHeight() - 1);
gd.drawPolygon(p);
}super.paintComponent(g);
}public booleancontains(Point p) {return this.getBounds().contains(p);
}private voidupdate() {
repaint();
}public voidmouseClicked(MouseEvent e) {
}public voidmousePressed(MouseEvent e) {
isSelected= true;
update();
}public voidmouseReleased(MouseEvent e) {
Point p= SwingUtilities.convertPoint(this, e.getPoint(), jp3);
lm.setSelect(p,false);
commit();
}public voidmouseEntered(MouseEvent e) {
}public voidmouseExited(MouseEvent e) {
}public voidmouseDragged(MouseEvent e) {
Point p= SwingUtilities.convertPoint(this, e.getPoint(), jp3);
lm.setSelect(p,true);
}public voidmouseMoved(MouseEvent e) {
}public intcompare(MyLabel o1, MyLabel o2) {
Calendar c1=Calendar.getInstance();
c1.set(o1.year, o2.month, o1.day);
Calendar c2=Calendar.getInstance();
c2.set(o2.year, o2.month, o2.day);returnc1.compareTo(c2);
}
}private classLabelManager {private Listlist;publicLabelManager() {
list= new ArrayList();
}public ListgetLabels() {returnlist;
}public voidaddLabel(MyLabel my) {
list.add(my);
}public voidclear() {
list.clear();
}public void setSelect(MyLabel my, booleanb) {for(MyLabel m : list) {if(m.equals(my)) {
m.setSelected(true, b);
}else{
m.setSelected(false, b);
}
}
}public void setSelect(Point p, booleanb) {//如果是拖动,则要优化一下,以提高效率
if(b) {//表示是否能返回,不用比较完所有的标签,能返回的标志就是把上一个标签和//将要显示的标签找到了就可以了
boolean findPrevious = false, findNext = false;for(MyLabel m : list) {if(m.contains(p)) {
findNext= true;if(m.getIsSelected()) {
findPrevious= true;
}else{
m.setSelected(true, b);
}
}else if(m.getIsSelected()) {
findPrevious= true;
m.setSelected(false, b);
}if (findPrevious &&findNext) {return;
}
}
}else{
MyLabel temp= null;for(MyLabel m : list) {if(m.contains(p)) {
temp=m;
}else if(m.getIsSelected()) {
m.setSelected(false, b);
}
}if (temp != null) {
temp.setSelected(true, b);
}
}
}
}private class JP4 extendsJPanel {publicJP4() {super(newBorderLayout());this.setPreferredSize(new Dimension(295, 20));this.setBackground(new Color(160, 185, 215));
SimpleDateFormat sdf= new SimpleDateFormat("yyyy年MM月dd日");final JLabel jl = new JLabel("今天: " + sdf.format(newDate()));
jl.setToolTipText("点击选择今天日期");this.add(jl, BorderLayout.CENTER);
jl.addMouseListener(newMouseAdapter() {public voidmouseEntered(MouseEvent me) {
jl.setCursor(newCursor(Cursor.HAND_CURSOR));
jl.setForeground(Color.RED);
}public voidmouseExited(MouseEvent me) {
jl.setCursor(newCursor(Cursor.DEFAULT_CURSOR));
jl.setForeground(Color.BLACK);
}public voidmousePressed(MouseEvent me) {
jl.setForeground(Color.WHITE);
select.setTime(newDate());
refresh();
commit();
}public voidmouseReleased(MouseEvent me) {
jl.setForeground(Color.BLACK);
}
});
}
}public static voidmain(String[] args) {final DateChooserDay mp = new DateChooserDay("yyyy-MM-dd");
JFrame jf= new JFrame("日期选择器");
jf.add(mp, BorderLayout.CENTER);
jf.add(new JButton("点击下面可选择时间"), BorderLayout.NORTH);
jf.setSize(WIDTH, HEIGHT);
jf.setLocationRelativeTo(null);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}