1 package com.ryd.stocktrader.client.util; 2 3 import java.awt.Color; 4 import java.awt.GridLayout; 5 import java.awt.Label; 6 import java.awt.TextField; 7 import java.awt.event.ActionEvent; 8 import java.awt.event.ActionListener; 9 import java.awt.event.MouseAdapter; 10 import java.awt.event.MouseEvent; 11 import java.text.ParseException; 12 import java.text.SimpleDateFormat; 13 import java.util.Calendar; 14 import java.util.Date; 15 import java.util.GregorianCalendar; 16 17 import javax.swing.BorderFactory; 18 import javax.swing.JButton; 19 import javax.swing.JComponent; 20 import javax.swing.JLabel; 21 import javax.swing.JPanel; 22 import javax.swing.JTextField; 23 import javax.swing.SwingConstants; 24 25 public class CalendarPanel extends JPanel { 26 27 /** 28 * 29 */ 30 private static final long serialVersionUID = 1L; 31 32 private JLabel btn_lastYear = null; 33 private JLabel btn_nextYear = null; 34 private JLabel btn_lastMonth = null; 35 private JLabel btn_nextMonth = null; 36 private JLabel lb_datetime = null; 37 private JPanel panel_maincalenderpanel = null; 38 private JLabel lblNewLabel = null; 39 private JLabel label = null; 40 private JLabel label_1 = null; 41 private JLabel label_2 = null; 42 private JLabel label_3 = null; 43 private JLabel label_4 = null; 44 private JLabel label_5 = null; 45 private JLabel btn_close = null; 46 private JButton btn_today = null; 47 private JButton btn_cancel = null; 48 private Object component = null; //日历控件的载体组件,如TextField 49 private String returnDateStr = null; //保存选中的日期 50 private CallBack callBack = null; 51 52 private String patern = "yyyy-MM-dd"; //日期格式 53 private SimpleDateFormat sdf = null; 54 private String nowDatetime = null ; //当前系统日期字符串 55 56 57 /** 58 * 带参数的构造函数,该构造函数将构造一个设置了日历控件的载体组件的CalenderPanel对象实例 59 * @param component 日历控件的载体组件,可以是TextField、JTextField、Label、JLabel 60 * @param patern 日期格式 ,默认为yyyy-MM-dd 61 */ 62 public CalendarPanel(Object component,String patern) { 63 this(patern); 64 this.component = component; 65 } 66 67 68 /** 69 * 带参数的构造函数,该构造函数将构造一个CalenderPanel对象实例,该对象时候没有设置日历控件的载体组件 70 * * @param patern 日期格式,默认为yyyy-MM-dd 71 */ 72 public CalendarPanel(String patern) { 73 super(); 74 75 //初始化日期格式化 76 this.patern = patern; 77 sdf = new SimpleDateFormat(patern); 78 nowDatetime = sdf.format(new Date()); 79 80 setLayout(null); 81 //设置日历控件的整体主面板边框为灰色 82 this.setBorder(BorderFactory.createLineBorder(Color.gray)); 83 //初始化日历控件上的各个组件 84 init(); 85 //创建日历控件的日期部分面板 86 createCalendarPanel(nowDatetime); 87 } 88 89 /** 90 * 无参数的构造函数,该构造函数将构造一个CalenderPanel对象实例,该对象时候没有设置日历控件的载体组件 91 */ 92 public CalendarPanel() { 93 super(); 94 95 //初始化日期格式化 96 sdf = new SimpleDateFormat(patern); 97 nowDatetime = sdf.format(new Date()); 98 99 setLayout(null);100 //设置日历控件的整体主面板边框为灰色101 this.setBorder(BorderFactory.createLineBorder(Color.gray));102 //初始化日历控件上的各个组件103 init();104 //创建日历控件的日期部分面板105 createCalendarPanel(nowDatetime);106 }107 108 /**109 * 获取日历控件的载体组件110 * @return 返回该日历控件中的载体组件,如果没有设置,则返回null;111 */112 public Object getComponent() {113 return component;114 }115 116 /**117 * 设置日历控件的载体组件118 * @param component119 */120 public void setComponent(Object component) {121 this.component = component;122 }123 124 /**125 * 获取选择日期时候的日期字符串126 * @return127 */128 public String getReturnDateStr() {129 return returnDateStr;130 }131 132 /**133 * 获取日历控件的回调接口对象134 * @return135 */136 public CallBack getCallBack() {137 return callBack;138 }139 140 /**141 * 设置日历控件的回调接口对象142 * @param callBack143 */144 public void setCallBack(CallBack callBack) {145 this.callBack = callBack;146 }147 148 149 /**150 * 创建下拉选择日历控件的主体面板(即显示日期部分的面板)151 * @param date 需要显示的日期152 */153 private void createCalendarPanel(String date){154 //每次刷新日期显示,需要重新创建日期部分的面板155 //如果日期部分的面板不为null,可以先将其remove,然后再创建156 if(panel_maincalenderpanel!=null){157 panel_maincalenderpanel.setVisible(false);158 this.remove(panel_maincalenderpanel);159 }160 161 //创建新的日期部分的面板162 panel_maincalenderpanel = new JPanel();163 panel_maincalenderpanel.setBackground(Color.WHITE);164 panel_maincalenderpanel.setBounds(2, 47, 247, 156);165 panel_maincalenderpanel.setLayout(new GridLayout(6,7));166 add(panel_maincalenderpanel);167 168 Date today = null;169 try {170 today = sdf.parse(date);171 } catch (ParseException e1) {172 e1.printStackTrace();173 return;174 }175 176 Calendar c = new GregorianCalendar();177 //将给定日期设置为需要显示的日期178 c.setTime(today);179 //需要将日改成1号,因为我们需要获取给定日期的第一天是星期几180 c.set(c.get(Calendar.YEAR),c.get(Calendar.MONTH), 1);181 182 int firstDayInMonthOfWeek = c.get(Calendar.DAY_OF_WEEK); //给定日期的第一天是星期几183 int daysOfMonth = c.getActualMaximum(Calendar.DAY_OF_MONTH); //给定日期对应月份的天数184 185 //首先生成给定日期第一天之前的空白部分186 //例如:2011-11的第一天就是星期二,那么星期二之前的(星期日,星期一)我们不显示内容,需要生成空白187 for(int i=1;i>");316 btn_nextYear.setBounds(179, 0, 27, 23);317 add(btn_nextYear);318 btn_nextYear.addMouseListener(new MouseAdapter() {319 320 @Override321 public void mouseClicked(MouseEvent e) {322 //改变日历控件面板的显示日期323 changTheDate(Calendar.YEAR,true);324 }325 326 });327 328 //上一月操作组件,这里使用一个JLabel329 btn_lastMonth = new JLabel("<");330 btn_lastMonth.setBounds(39, 0, 27, 23);331 add(btn_lastMonth);332 btn_lastMonth.addMouseListener(new MouseAdapter() {333 334 @Override335 public void mouseClicked(MouseEvent e) {336 //改变日历控件面板的显示日期337 changTheDate(Calendar.MONTH,false);338 }339 340 });341 342 //下一月操作组件,这里使用一个JLabel343 btn_nextMonth = new JLabel(">");344 btn_nextMonth.setBounds(150, 0, 27, 23);345 add(btn_nextMonth);346 btn_nextMonth.addMouseListener(new MouseAdapter() {347 348 @Override349 public void mouseClicked(MouseEvent e) {350 //改变日历控件面板的显示日期351 changTheDate(Calendar.MONTH,true);352 }353 354 });355 356 //显示日期的lable对象357 lb_datetime = new JLabel("");358 lb_datetime.setBounds(58, 2, 86, 19);359 lb_datetime.setHorizontalAlignment(SwingConstants.CENTER);360 add(lb_datetime);361 lb_datetime.setText(nowDatetime);362 363 lblNewLabel = new JLabel("日");364 lblNewLabel.setForeground(Color.RED);365 lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);366 lblNewLabel.setBounds(2, 22, 27, 23);367 add(lblNewLabel);368 369 label = new JLabel("一");370 label.setHorizontalAlignment(SwingConstants.CENTER);371 label.setBounds(39, 22, 27, 23);372 add(label);373 374 label_1 = new JLabel("二");375 label_1.setHorizontalAlignment(SwingConstants.CENTER);376 label_1.setBounds(76, 22, 27, 23);377 add(label_1);378 379 label_2 = new JLabel("三");380 label_2.setHorizontalAlignment(SwingConstants.CENTER);381 label_2.setBounds(113, 22, 27, 23);382 add(label_2);383 384 label_3 = new JLabel("四");385 label_3.setHorizontalAlignment(SwingConstants.CENTER);386 label_3.setBounds(147, 22, 27, 23);387 add(label_3);388 389 label_4 = new JLabel("五");390 label_4.setHorizontalAlignment(SwingConstants.CENTER);391 label_4.setBounds(184, 22, 27, 23);392 add(label_4);393 394 label_5 = new JLabel("六");395 label_5.setForeground(Color.GREEN);396 label_5.setHorizontalAlignment(SwingConstants.CENTER);397 label_5.setBounds(221, 22, 27, 23);398 add(label_5);399 400 btn_close = new JLabel("[X]");401 btn_close.setBounds(222, 0, 27, 23);402 btn_close.setForeground(Color.RED);403 add(btn_close);404 btn_close.addMouseListener(new MouseAdapter() {405 406 @Override407 public void mouseClicked(MouseEvent e) {408 CalendarPanel.this.setVisible(false);409 }410 411 });412 413 414 //用于快速显示今天日期的按钮415 btn_today = new JButton("今天");416 btn_today.setBounds(10, 213, 60, 23);417 btn_today.setContentAreaFilled(false);418 btn_today.setBorder(BorderFactory.createLineBorder(Color.GRAY));419 add(btn_today);420 btn_today.addActionListener(new ActionListener() {421 @Override422 public void actionPerformed(ActionEvent e) {423 createCalendarPanel(nowDatetime);424 lb_datetime.setText(nowDatetime);425 }426 });427 428 429 //用于取消日期选择的按钮430 btn_cancel = new JButton("取消");431 btn_cancel.setBounds(179, 213, 60, 23);432 btn_cancel.setContentAreaFilled(false);433 btn_cancel.setBorder(BorderFactory.createLineBorder(Color.GRAY));434 add(btn_cancel);435 btn_cancel.addActionListener(new ActionListener() {436 @Override437 public void actionPerformed(ActionEvent e) {438 CalendarPanel.this.setVisible(false);439 }440 });441 }442 443 /**444 * 重新设置日历面板显示为系统当前日期445 */446 public void reset(){447 createCalendarPanel(nowDatetime);448 lb_datetime.setText(nowDatetime);449 }450 451 452 453 /**454 * 改变当前日历控件面板的日期显示455 * @param YEAR_OR_MONTH 是对YEAR还是MONTH操作,这里需要传入Calendar类对应的常量值:Calendar.YEAR,Calendar.MONTH456 * @param flag 对YEAR_OR_MONTH属性是进行加法操作还是减法操作,如果flag为true则是加法操作,否则为减法操作457 */458 public void changTheDate(int YEAR_OR_MONTH,boolean flag){459 String dateStr = lb_datetime.getText().trim();460 Date date = null;461 try {462 date = sdf.parse(dateStr);463 } catch (ParseException e1) {464 e1.printStackTrace();465 return;466 }467 Calendar c = Calendar.getInstance();468 c.setTime(date);469 if(flag){470 //将对应的日期属性进行加法操作471 c.set(YEAR_OR_MONTH,c.get(YEAR_OR_MONTH)+1 );472 }else{473 //将对应的日期属性进行减法操作474 c.set(YEAR_OR_MONTH,c.get(YEAR_OR_MONTH)-1 );475 }476 477 date = c.getTime();478 lb_datetime.setText(sdf.format(date));479 createCalendarPanel(sdf.format(date));480 }481 482 483 484 public static void main(String[] args) {485 Calendar c = new GregorianCalendar(2011,11,1);486 System.out.println( c.get(Calendar.DAY_OF_WEEK));487 }488 489 490 public void initCalendarPanel(){491 if(component instanceof javax.swing.JComponent){492 JComponent j = (JComponent)component;493 int w = j.getWidth();494 int h = j.getHeight();495 int x = j.getX();496 int y = j.getY();497 System.out.println("with:"+w +"height:"+h+"x:"+x+"y:"+y);498 this.setComponent(component);499 this.setBounds((x), y+h, 251, 245);500 this.setVisible(false);501 j.addMouseListener(new MouseAdapter() {502 @Override503 public void mouseClicked(MouseEvent e) {504 if (CalendarPanel.this.isVisible()){505 CalendarPanel.this.setVisible(false);506 }else{507 CalendarPanel.this.setVisible(true);508 CalendarPanel.this.reset();509 }510 }511 });512 }513 }514 515 516 517 }
接口:
1 package com.ryd.stocktrader.client.util;2 3 /**4 * Created by Administrator on 2016/7/28.5 */6 public interface CallBack {7 public void callback();8 }
测试类:
1 import java.awt.Color; 2 import java.awt.Point; 3 4 import javax.swing.JFrame; 5 import javax.swing.JLabel; 6 import javax.swing.JPanel; 7 import javax.swing.JTextField; 8 9 //测试类10 public class DateChooser extends JPanel {11 /**12 * 13 */14 private static final long serialVersionUID = 1L;15 //private static Point startp = null;16 //private Point endp = null;17 18 public static void main(String[] args) {19 20 JFrame f = new JFrame();21 f.setLayout(null);22 JTextField txt1 = new JTextField();23 JTextField txt2 = new JTextField();24 txt1.setBounds(20, 50, 300, 30);25 txt2.setBounds(20, 80, 300, 30);26 27 // 定义日历控件面板类28 CalendarPanel p = new CalendarPanel(txt1, "yyyy/MM/dd");29 p.initCalendarPanel();30 31 JLabel l = new JLabel("日历面板");32 p.add(l);33 f.getContentPane().add(p);34 f.getContentPane().add(txt1);35 f.getContentPane().add(txt2);36 f.setSize(500, 400);37 f.setBackground(Color.WHITE);38 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);39 f.setVisible(true);40 }41 }
方式二:
1 package com.ryd.stocktrader.client.util; 2 3 import java.awt.BasicStroke; 4 5 import java.awt.BorderLayout; 6 7 import java.awt.Color; 8 9 import java.awt.Component; 10 11 import java.awt.Cursor; 12 13 import java.awt.Dimension; 14 15 import java.awt.Font; 16 17 import java.awt.Graphics; 18 19 import java.awt.Graphics2D; 20 21 import java.awt.GridLayout; 22 23 import java.awt.Point; 24 25 import java.awt.Polygon; 26 27 import java.awt.Stroke; 28 29 import java.awt.Toolkit; 30 31 import java.awt.event.FocusEvent; 32 33 import java.awt.event.FocusListener; 34 35 import java.awt.event.MouseAdapter; 36 37 import java.awt.event.MouseEvent; 38 39 import java.awt.event.MouseListener; 40 41 import java.awt.event.MouseMotionListener; 42 43 import java.text.SimpleDateFormat; 44 45 import java.util.ArrayList; 46 47 import java.util.Calendar; 48 49 import java.util.Comparator; 50 51 import java.util.Date; 52 53 import java.util.List; 54 55 56 57 import javax.swing.BorderFactory; 58 59 import javax.swing.JComponent; 60 61 import javax.swing.JFrame; 62 63 import javax.swing.JLabel; 64 65 import javax.swing.JPanel; 66 67 import javax.swing.JTextField; 68 69 import javax.swing.Popup; 70 71 import javax.swing.PopupFactory; 72 73 import javax.swing.SwingUtilities; 74 75 import javax.swing.event.AncestorEvent; 76 77 import javax.swing.event.AncestorListener; 78 79 public class DateChooser extends JPanel { 80 private static final long serialVersionUID = 4529266044762990227L; 81 82 83 84 private Date initDate; 85 86 private Calendar now = Calendar.getInstance(); 87 88 private Calendar select; 89 90 private JPanel monthPanel;//月历 91 92 private JP1 jp1;//四块面板,组成 93 94 private JP2 jp2; 95 96 private JP3 jp3; 97 98 private JP4 jp4; 99 100 private Font font = new Font("宋体", Font.PLAIN, 12); 101 102 private final LabelManager lm = new LabelManager(); 103 104 private SimpleDateFormat sdf; 105 106 private boolean isShow = false; 107 108 private Popup pop; 109 110 111 112 private JComponent showDate; 113 114 115 116 public static DateChooser getInstance() { 117 118 return new DateChooser(); 119 120 } 121 122 123 124 public static DateChooser getInstance(Date date) { 125 126 return new DateChooser(date); 127 128 } 129 130 131 132 public static DateChooser getInstance(String format) { 133 134 return new DateChooser(format); 135 136 } 137 138 139 140 public static DateChooser getInstance(Date date, String format) { 141 142 return new DateChooser(date, format); 143 144 } 145 146 147 148 /** 149 150 * Creates a new instance of DateChooser 151 152 */ 153 154 private DateChooser() { 155 156 this(new Date()); 157 158 } 159 160 161 162 private DateChooser(Date date) { 163 164 this(date, "yyyy年MM月dd日"); 165 166 } 167 168 169 170 private DateChooser(String format) { 171 172 this(new Date(), format); 173 174 } 175 176 177 178 private DateChooser(Date date, String format) { 179 180 initDate = date; 181 182 sdf = new SimpleDateFormat(format); 183 184 select = Calendar.getInstance(); 185 186 select.setTime(initDate); 187 188 initPanel(); 189 190 } 191 192 193 194 /** 195 196 * 是否允许用户选择 197 198 */ 199 200 public void setEnabled(boolean b) { 201 202 super.setEnabled(b); 203 204 showDate.setEnabled(b); 205 206 } 207 208 209 210 /** 211 212 *得到当前选择框的日期 213 214 */ 215 216 public Date getDate() { 217 218 return select.getTime(); 219 220 } 221 222 223 224 public String getStrDate() { 225 226 return sdf.format(select.getTime()); 227 228 } 229 230 231 232 public String getStrDate(String format) { 233 234 sdf = new SimpleDateFormat(format); 235 236 return sdf.format(select.getTime()); 237 238 } 239 240 241 242 //根据初始化的日期,初始化面板 243 244 private void initPanel() { 245 246 monthPanel = new JPanel(new BorderLayout()); 247 248 monthPanel.setBorder(BorderFactory.createLineBorder(Color.BLUE)); 249 250 JPanel up = new JPanel(new BorderLayout()); 251 252 up.add(jp1 = new JP1(), BorderLayout.NORTH); 253 254 up.add(jp2 = new JP2(), BorderLayout.CENTER); 255 256 monthPanel.add(jp3 = new JP3(), BorderLayout.CENTER); 257 258 monthPanel.add(up, BorderLayout.NORTH); 259 260 monthPanel.add(jp4 = new JP4(), BorderLayout.SOUTH); 261 262 this.addAncestorListener(new AncestorListener() { 263 264 public void ancestorAdded(AncestorEvent event) { 265 266 267 268 } 269 270 271 272 public void ancestorRemoved(AncestorEvent event) { 273 274 275 276 } 277 278 279 280 //只要祖先组件一移动,马上就让popup消失 281 282 public void ancestorMoved(AncestorEvent event) { 283 284 hidePanel(); 285 286 } 287 288 }); 289 290 } 291 292 293 294 public void register(final JComponent showDate) { 295 296 this.showDate = showDate; 297 298 299 300 showDate.setRequestFocusEnabled(true); 301 302 showDate.addMouseListener(new MouseAdapter() { 303 304 public void mousePressed(MouseEvent me) { 305 306 showDate.requestFocusInWindow(); 307 308 } 309 310 }); 311 312 this.setBackground(Color.WHITE); 313 314 this.add(showDate, BorderLayout.CENTER); 315 316 this.setPreferredSize(new Dimension(90, 25)); 317 318 this.setBorder(BorderFactory.createLineBorder(Color.GRAY)); 319 320 showDate.addMouseListener(new MouseAdapter() { 321 322 public void mouseEntered(MouseEvent me) { 323 324 if (showDate.isEnabled()) { 325 326 showDate.setCursor(new Cursor(Cursor.HAND_CURSOR)); 327 328 showDate.setForeground(Color.white); 329 330 } 331 332 } 333 334 335 336 public void mouseExited(MouseEvent me) { 337 338 if (showDate.isEnabled()) { 339 340 showDate.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); 341 342 showDate.setForeground(Color.white); 343 344 } 345 346 } 347 348 349 350 public void mousePressed(MouseEvent me) { 351 352 if (showDate.isEnabled()) { 353 354 showDate.setForeground(Color.CYAN); 355 356 if (isShow) { 357 358 hidePanel(); 359 360 } else { 361 362 showPanel(showDate); 363 364 } 365 366 } 367 368 } 369 370 371 372 public void mouseReleased(MouseEvent me) { 373 374 if (showDate.isEnabled()) { 375 376 showDate.setForeground(Color.BLACK); 377 378 } 379 380 } 381 382 }); 383 384 showDate.addFocusListener(new FocusListener() { 385 386 public void focusLost(FocusEvent e) { 387 388 hidePanel(); 389 390 } 391 392 393 394 public void focusGained(FocusEvent e) { 395 396 397 398 } 399 400 }); 401 402 } 403 404 405 406 //根据新的日期刷新 407 408 private void refresh() { 409 410 jp1.updateDate(); 411 412 jp2.updateDate(); 413 414 jp3.updateDate(); 415 416 jp4.updateDate(); 417 418 SwingUtilities.updateComponentTreeUI(this); 419 420 } 421 422 423 424 //提交日期 425 426 private void commit() { 427 428 //TODO add other components here 429 430 if (showDate instanceof JTextField) { 431 432 ((JTextField) showDate).setText(sdf.format(select.getTime())); 433 434 }else if (showDate instanceof JLabel) { 435 436 ((JLabel) showDate).setText(sdf.format(select.getTime())); 437 438 } 439 440 441 442 hidePanel(); 443 444 } 445 446 447 448 //隐藏日期选择面板 449 450 private void hidePanel() { 451 452 if (pop != null) { 453 454 isShow = false; 455 456 pop.hide(); 457 458 pop = null; 459 460 } 461 462 } 463 464 465 466 //显示日期选择面板 467 468 private void showPanel(Component owner) { 469 470 if (pop != null) { 471 472 pop.hide(); 473 474 } 475 476 Point show = new Point(0, showDate.getHeight()); 477 478 SwingUtilities.convertPointToScreen(show, showDate); 479 480 Dimension size = Toolkit.getDefaultToolkit().getScreenSize(); 481 482 int x = show.x; 483 484 int y = show.y; 485 486 if (x < 0) { 487 488 x = 0; 489 490 } 491 492 if (x > size.width - 295) { 493 494 x = size.width - 295; 495 496 } 497 498 if (y < size.height - 170) { 499 500 } else { 501 502 y -= 188; 503 504 } 505 506 pop = PopupFactory.getSharedInstance().getPopup(owner, monthPanel, x, y); 507 508 pop.show(); 509 510 isShow = true; 511 512 } 513 514 515 516 /** 517 518 * 最上面的面板用来显示月份的增减 519 520 */ 521 522 private class JP1 extends JPanel { 523 524 private static final long serialVersionUID = -5638853772805561174L; 525 526 JLabel yearleft, yearright, monthleft, monthright, center, centercontainer; 527 528 529 530 public JP1() { 531 532 super(new BorderLayout()); 533 534 this.setBackground(new Color(160, 185, 215)); 535 536 initJP1(); 537 538 } 539 540 541 542 private void initJP1() { 543 544 yearleft = new JLabel(" <<", JLabel.CENTER); 545 546 yearleft.setToolTipText("上一年"); 547 548 yearright = new JLabel(">> ", JLabel.CENTER); 549 550 yearright.setToolTipText("下一年"); 551 552 yearleft.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0)); 553 554 yearright.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0)); 555 556 557 558 monthleft = new JLabel(" <", JLabel.RIGHT); 559 560 monthleft.setToolTipText("上一月"); 561 562 monthright = new JLabel("> ", JLabel.LEFT); 563 564 monthright.setToolTipText("下一月"); 565 566 monthleft.setBorder(BorderFactory.createEmptyBorder(2, 30, 0, 0)); 567 568 monthright.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 30)); 569 570 571 572 centercontainer = new JLabel("", JLabel.CENTER); 573 574 centercontainer.setLayout(new BorderLayout()); 575 576 center = new JLabel("", JLabel.CENTER); 577 578 579 580 centercontainer.add(monthleft, BorderLayout.WEST); 581 582 centercontainer.add(center, BorderLayout.CENTER); 583 584 centercontainer.add(monthright, BorderLayout.EAST); 585 586 587 588 this.add(yearleft, BorderLayout.WEST); 589 590 this.add(centercontainer, BorderLayout.CENTER); 591 592 this.add(yearright, BorderLayout.EAST); 593 594 this.setPreferredSize(new Dimension(295, 25)); 595 596 597 598 updateDate(); 599 600 601 602 yearleft.addMouseListener(new MouseAdapter() { 603 604 public void mouseEntered(MouseEvent me) { 605 606 yearleft.setCursor(new Cursor(Cursor.HAND_CURSOR)); 607 608 yearleft.setForeground(Color.RED); 609 610 } 611 612 613 614 public void mouseExited(MouseEvent me) { 615 616 yearleft.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); 617 618 yearleft.setForeground(Color.BLACK); 619 620 } 621 622 623 624 public void mousePressed(MouseEvent me) { 625 626 select.add(Calendar.YEAR, -1); 627 628 yearleft.setForeground(Color.WHITE); 629 630 refresh(); 631 632 } 633 634 635 636 public void mouseReleased(MouseEvent me) { 637 638 yearleft.setForeground(Color.BLACK); 639 640 } 641 642 }); 643 644 yearright.addMouseListener(new MouseAdapter() { 645 646 public void mouseEntered(MouseEvent me) { 647 648 yearright.setCursor(new Cursor(Cursor.HAND_CURSOR)); 649 650 yearright.setForeground(Color.RED); 651 652 } 653 654 655 656 public void mouseExited(MouseEvent me) { 657 658 yearright.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); 659 660 yearright.setForeground(Color.BLACK); 661 662 } 663 664 665 666 public void mousePressed(MouseEvent me) { 667 668 select.add(Calendar.YEAR, 1); 669 670 yearright.setForeground(Color.WHITE); 671 672 refresh(); 673 674 } 675 676 677 678 public void mouseReleased(MouseEvent me) { 679 680 yearright.setForeground(Color.BLACK); 681 682 } 683 684 }); 685 686 monthleft.addMouseListener(new MouseAdapter() { 687 688 public void mouseEntered(MouseEvent me) { 689 690 monthleft.setCursor(new Cursor(Cursor.HAND_CURSOR)); 691 692 monthleft.setForeground(Color.RED); 693 694 } 695 696 697 698 public void mouseExited(MouseEvent me) { 699 700 monthleft.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); 701 702 monthleft.setForeground(Color.BLACK); 703 704 } 705 706 707 708 public void mousePressed(MouseEvent me) { 709 710 select.add(Calendar.MONTH, -1); 711 712 monthleft.setForeground(Color.WHITE); 713 714 refresh(); 715 716 } 717 718 719 720 public void mouseReleased(MouseEvent me) { 721 722 monthleft.setForeground(Color.BLACK); 723 724 } 725 726 }); 727 728 monthright.addMouseListener(new MouseAdapter() { 729 730 public void mouseEntered(MouseEvent me) { 731 732 monthright.setCursor(new Cursor(Cursor.HAND_CURSOR)); 733 734 monthright.setForeground(Color.RED); 735 736 } 737 738 739 740 public void mouseExited(MouseEvent me) { 741 742 monthright.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); 743 744 monthright.setForeground(Color.BLACK); 745 746 } 747 748 749 750 public void mousePressed(MouseEvent me) { 751 752 select.add(Calendar.MONTH, 1); 753 754 monthright.setForeground(Color.WHITE); 755 756 refresh(); 757 758 } 759 760 761 762 public void mouseReleased(MouseEvent me) { 763 764 monthright.setForeground(Color.BLACK); 765 766 } 767 768 }); 769 770 } 771 772 773 774 private void updateDate() { 775 776 center.setText(select.get(Calendar.YEAR) + "年" + (select.get(Calendar.MONTH) + 1) + "月"); 777 778 } 779 780 } 781 782 783 784 private class JP2 extends JPanel { 785 786 private static final long serialVersionUID = -8176264838786175724L; 787 788 789 790 public JP2() { 791 792 this.setPreferredSize(new Dimension(295, 20)); 793 794 } 795 796 797 798 protected void paintComponent(Graphics g) { 799 800 g.setFont(font); 801 802 g.drawString("星期日 星期一 星期二 星期三 星期四 星期五 星期六", 5, 10); 803 804 g.drawLine(0, 15, getWidth(), 15); 805 806 } 807 808 809 810 private void updateDate() { 811 812 813 814 } 815 816 } 817 818 819 820 private class JP3 extends JPanel { 821 822 private static final long serialVersionUID = 43157272447522985L; 823 824 825 826 public JP3() { 827 828 super(new GridLayout(6, 7)); 829 830 this.setPreferredSize(new Dimension(295, 100)); 831 832 initJP3(); 833 834 } 835 836 837 838 private void initJP3() { 839 840 updateDate(); 841 842 } 843 844 845 846 public void updateDate() { 847 848 this.removeAll(); 849 850 lm.clear(); 851 852 Date temp = select.getTime(); 853 854 Calendar select = Calendar.getInstance(); 855 856 select.setTime(temp); 857 858 select.set(Calendar.DAY_OF_MONTH, 1); 859 860 int index = select.get(Calendar.DAY_OF_WEEK); 861 862 int sum = (index == 1 ? 8 : index); 863 864 select.add(Calendar.DAY_OF_MONTH, 0 - sum); 865 866 for (int i = 0; i < 42; i++) { 867 868 select.add(Calendar.DAY_OF_MONTH, 1); 869 870 lm.addLabel(new MyLabel(select.get(Calendar.YEAR), select.get(Calendar.MONTH), select.get(Calendar.DAY_OF_MONTH))); 871 872 } 873 874 for (MyLabel my : lm.getLabels()) { 875 876 this.add(my); 877 878 } 879 880 select.setTime(temp); 881 882 } 883 884 } 885 886 887 888 private class MyLabel extends JLabel implements Comparator, MouseListener, MouseMotionListener { 889 890 private static final long serialVersionUID = 3668734399227577214L; 891 892 private int year, month, day; 893 894 private boolean isSelected; 895 896 897 898 public MyLabel(int year, int month, int day) { 899 900 super("" + day, JLabel.CENTER); 901 902 this.year = year; 903 904 this.day = day; 905 906 this.month = month; 907 908 this.addMouseListener(this); 909 910 this.addMouseMotionListener(this); 911 912 this.setFont(font); 913 914 if (month == select.get(Calendar.MONTH)) { 915 916 this.setForeground(Color.BLACK); 917 918 } else { 919 920 this.setForeground(Color.LIGHT_GRAY); 921 922 } 923 924 if (day == select.get(Calendar.DAY_OF_MONTH)) { 925 926 this.setBackground(new Color(160, 185, 215)); 927 928 } else { 929 930 this.setBackground(Color.WHITE); 931 932 } 933 934 } 935 936 937 938 public boolean getIsSelected() { 939 940 return isSelected; 941 942 } 943 944 945 946 public void setSelected(boolean b, boolean isDrag) { 947 948 isSelected = b; 949 950 if (b && !isDrag) { 951 952 int temp = select.get(Calendar.MONTH); 953 954 select.set(year, month, day); 955 956 if (temp == month) { 957 958 SwingUtilities.updateComponentTreeUI(jp3); 959 960 } else { 961 962 refresh(); 963 964 } 965 966 } 967 968 this.repaint(); 969 970 } 971 972 973 974 protected void paintComponent(Graphics g) { 975 976 if (day == select.get(Calendar.DAY_OF_MONTH) && month == select.get(Calendar.MONTH)) { 977 978 //如果当前日期是选择日期,则高亮显示 979 980 g.setColor(new Color(160, 185, 215)); 981 982 g.fillRect(0, 0, getWidth(), getHeight()); 983 984 } 985 986 if (year == now.get(Calendar.YEAR) && month == now.get(Calendar.MONTH) && day == now.get(Calendar.DAY_OF_MONTH)) { 987 988 //如果日期和当前日期一样,则用红框 989 990 Graphics2D gd = (Graphics2D) g; 991 992 gd.setColor(Color.RED); 993 994 Polygon p = new Polygon(); 995 996 p.addPoint(0, 0); 997 998 p.addPoint(getWidth() - 1, 0); 999 1000 p.addPoint(getWidth() - 1, getHeight() - 1);1001 1002 p.addPoint(0, getHeight() - 1);1003 1004 gd.drawPolygon(p);1005 1006 }1007 1008 if (isSelected) { //如果被选中了就画出一个虚线框出来1009 1010 Stroke s = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 1.0f, new float[] { 2.0f, 2.0f }, 1.0f);1011 1012 Graphics2D gd = (Graphics2D) g;1013 1014 gd.setStroke(s);1015 1016 gd.setColor(Color.BLACK);1017 1018 Polygon p = new Polygon();1019 1020 p.addPoint(0, 0);1021 1022 p.addPoint(getWidth() - 1, 0);1023 1024 p.addPoint(getWidth() - 1, getHeight() - 1);1025 1026 p.addPoint(0, getHeight() - 1);1027 1028 gd.drawPolygon(p);1029 1030 }1031 1032 super.paintComponent(g);1033 1034 }1035 1036 1037 1038 public boolean contains(Point p) {1039 1040 return this.getBounds().contains(p);1041 1042 }1043 1044 1045 1046 private void update() {1047 1048 repaint();1049 1050 }1051 1052 1053 1054 public void mouseClicked(MouseEvent e) {1055 1056 }1057 1058 1059 1060 public void mousePressed(MouseEvent e) {1061 1062 isSelected = true;1063 1064 update();1065 1066 }1067 1068 1069 1070 public void mouseReleased(MouseEvent e) {1071 1072 Point p = SwingUtilities.convertPoint(this, e.getPoint(), jp3);1073 1074 lm.setSelect(p, false);1075 1076 commit();1077 1078 }1079 1080 1081 1082 public void mouseEntered(MouseEvent e) {1083 1084 }1085 1086 1087 1088 public void mouseExited(MouseEvent e) {1089 1090 }1091 1092 1093 1094 public void mouseDragged(MouseEvent e) {1095 1096 Point p = SwingUtilities.convertPoint(this, e.getPoint(), jp3);1097 1098 lm.setSelect(p, true);1099 1100 }1101 1102 1103 1104 public void mouseMoved(MouseEvent e) {1105 1106 }1107 1108 1109 1110 public int compare(MyLabel o1, MyLabel o2) {1111 1112 Calendar c1 = Calendar.getInstance();1113 1114 c1.set(o1.year, o2.month, o1.day);1115 1116 Calendar c2 = Calendar.getInstance();1117 1118 c2.set(o2.year, o2.month, o2.day);1119 1120 return c1.compareTo(c2);1121 1122 }1123 1124 }1125 1126 1127 1128 private class LabelManager {1129 1130 private List list;1131 1132 1133 1134 public LabelManager() {1135 1136 list = new ArrayList ();1137 1138 }1139 1140 1141 1142 public List getLabels() {1143 1144 return list;1145 1146 }1147 1148 1149 1150 public void addLabel(MyLabel my) {1151 1152 list.add(my);1153 1154 }1155 1156 1157 1158 public void clear() {1159 1160 list.clear();1161 1162 }1163 1164 1165 1166 @SuppressWarnings("unused")1167 1168 public void setSelect(MyLabel my, boolean b) {1169 1170 for (MyLabel m : list) {1171 1172 if (m.equals(my)) {1173 1174 m.setSelected(true, b);1175 1176 } else {1177 1178 m.setSelected(false, b);1179 1180 }1181 1182 }1183 1184 }1185 1186 1187 1188 public void setSelect(Point p, boolean b) {1189 1190 //如果是拖动,则要优化一下,以提高效率1191 1192 if (b) {1193 1194 //表示是否能返回,不用比较完所有的标签,能返回的标志就是把上一个标签和1195 1196 //将要显示的标签找到了就可以了1197 1198 boolean findPrevious = false, findNext = false;1199 1200 for (MyLabel m : list) {1201 1202 if (m.contains(p)) {1203 1204 findNext = true;1205 1206 if (m.getIsSelected()) {1207 1208 findPrevious = true;1209 1210 } else {1211 1212 m.setSelected(true, b);1213 1214 }1215 1216 } else if (m.getIsSelected()) {1217 1218 findPrevious = true;1219 1220 m.setSelected(false, b);1221 1222 }1223 1224 if (findPrevious && findNext) {1225 1226 return;1227 1228 }1229 1230 }1231 1232 } else {1233 1234 MyLabel temp = null;1235 1236 for (MyLabel m : list) {1237 1238 if (m.contains(p)) {1239 1240 temp = m;1241 1242 } else if (m.getIsSelected()) {1243 1244 m.setSelected(false, b);1245 1246 }1247 1248 }1249 1250 if (temp != null) {1251 1252 temp.setSelected(true, b);1253 1254 }1255 1256 }1257 1258 }1259 1260 1261 1262 }1263 1264 1265 1266 private class JP4 extends JPanel {1267 1268 private static final long serialVersionUID = -6391305687575714469L;1269 1270 1271 1272 public JP4() {1273 1274 super(new BorderLayout());1275 1276 this.setPreferredSize(new Dimension(295, 20));1277 1278 this.setBackground(new Color(160, 185, 215));1279 1280 SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");1281 1282 final JLabel jl = new JLabel("今天: " + sdf.format(new Date()));1283 1284 jl.setToolTipText("点击选择今天日期");1285 1286 this.add(jl, BorderLayout.CENTER);1287 1288 jl.addMouseListener(new MouseAdapter() {1289 1290 public void mouseEntered(MouseEvent me) {1291 1292 jl.setCursor(new Cursor(Cursor.HAND_CURSOR));1293 1294 jl.setForeground(Color.RED);1295 1296 }1297 1298 1299 1300 public void mouseExited(MouseEvent me) {1301 1302 jl.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));1303 1304 jl.setForeground(Color.BLACK);1305 1306 }1307 1308 1309 1310 public void mousePressed(MouseEvent me) {1311 1312 jl.setForeground(Color.WHITE);1313 1314 select.setTime(new Date());1315 1316 refresh();1317 1318 commit();1319 1320 }1321 1322 1323 1324 public void mouseReleased(MouseEvent me) {1325 1326 jl.setForeground(Color.BLACK);1327 1328 }1329 1330 });1331 1332 }1333 1334 1335 1336 private void updateDate() {1337 1338 1339 1340 }1341 1342 }1343 1344 1345 1346 public static void main(String[] args) {1347 1348 DateChooser dateChooser1 = DateChooser.getInstance("yyyy-MM-dd");1349 1350 DateChooser dateChooser2 = DateChooser.getInstance("yyyy-MM-dd");1351 1352 JTextField showDate1 = new JTextField("单击选择日期");1353 1354 JLabel showDate2 = new JLabel("单击选择日期");1355 1356 1357 1358 dateChooser1.register(showDate1);1359 1360 dateChooser2.register(showDate2);1361 1362 1363 1364 JFrame jf = new JFrame("测试日期选择器");1365 1366 jf.add(showDate1, BorderLayout.NORTH);1367 1368 jf.add(showDate2, BorderLayout.SOUTH);1369 1370 jf.pack();1371 1372 jf.setLocationRelativeTo(null);1373 1374 jf.setVisible(true);1375 1376 jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);1377 1378 }1379 }