2013-04-19 53 views
5

Tôi đang sử dụng SwingX JXDatePicker và tôi không thể tìm ra cách cung cấp các nút tiếp theo/năm trước (theo mặc định nó chỉ cung cấp các nút tháng tiếp theo/trước đó).Java Swing JXDatePicker

Ngoài ra, có vẻ như SwingX không được duy trì nữa: tôi có nên sử dụng thành phần gần đây hơn làm bộ chọn ngày không?

Bất kỳ trợ giúp/gợi ý nào sẽ được đánh giá cao. Cảm ơn, Thomas

UPDATE:

Để làm rõ câu hỏi, tôi đã thêm một ảnh chụp màn hình JXDatePicker và đánh dấu đỏ các nút tháng trước/sau. Các câu hỏi là như vậy: làm thế nào để thêm các nút sẽ mang lại lịch cho năm tiếp theo/năm trước? Xin lưu ý rằng các nút mới cần phải là các thành phần tiêu chuẩn vì chúng cần được hiển thị bằng một Cái nhìn cụ thể & Trình quản lý cảm thấy (Insusbtantial trong trường hợp này).

Rất cám ơn

enter image description here

+0

Check-out [này] hỏi (http://stackoverflow.com/questions/1339354/what-are-good-java-date-chooser-swing-gui-widgets) cho một danh sách lên tùy chọn thay thế. Tôi khuyên bạn nên thử một số trong số đó. – Kezz101

+0

nó _is_ duy trì - phiên bản hiện tại 1.6.5-1, nhưng không hiểu những gì bạn đang sau: chính xác những gì bạn muốn? Và tại sao tại sao tùy chỉnh như được mô tả trong bản trình diễn xoay vòng (liên kết webstartable tại trang dự án) không có ích) – kleopatra

+0

@MrD tại sao lại lan truyền các liên kết không liên quan? Đó là một vấn đề hoàn toàn không liên quan ... – kleopatra

Trả lời

2

tôi sẽ khuyên bạn sử dụng Microba DatePicker. Đó là tùy biến cao và thực hiện chính xác những gì bạn muốn.

http://microba.sourceforge.net/

enter image description here enter image description here

Edit:

Ok tôi thấy. Vâng, tôi đã làm một số nghiên cứu và có vẻ như chức năng bạn đang tìm kiếm thực sự không có trong JXDatePicker.

Một giải pháp thay thế khác mà tôi tìm thấy là: JDatePicker tại http://sourceforge.net/projects/jdatepicker/.

website chính: https://jdatepicker.org/

này vẫn được hỗ trợ và dường như có chức năng mà bạn muốn.

+0

Thật không may thành phần này không được duy trì nữa (không có bản phát hành trong 5 năm qua): nó quá mạo hiểm đối với chúng tôi vì phiên bản Java/Swing trong tương lai có thể phá vỡ nó và nó sẽ không được sửa ... – Tom

+0

@Omid can you cho tôi biết làm thế nào tôi thêm này trong Swing thành phần và kéo trong jframe, tôi đã thêm bằng cách sử dụng JPallete Manager nhưng thành phần này doesnot kéo vào jframe. –

+0

Tôi đang hát Net Beans 7.1, thực hiện điều này tương thích với công việc 7,1 của NeBeans và Swing. –

1

Đây là thứ tôi đã đặt cùng một vài năm trước. Bạn có thể sửa đổi nó để đáp ứng nhu cầu của bạn.

enter image description here

Bạn sẽ cần hình ảnh này để chạy thử nghiệm chính: calendar icon. Chỉ cần đặt nó trong cùng thư mục với nguồn có tên datepicker.gif.

import java.awt.Color; 
import java.awt.Container; 
import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.Font; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import java.awt.Point; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.net.URL; 
import java.text.SimpleDateFormat; 
import java.util.ArrayList; 
import java.util.Calendar; 
import java.util.Date; 
import java.util.List; 

import javax.swing.BorderFactory; 
import javax.swing.BoxLayout; 
import javax.swing.ImageIcon; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.Popup; 
import javax.swing.PopupFactory; 

public class DatePicker extends JPanel { 

    private static final long serialVersionUID = 1L; 

    protected boolean controlsOnTop; 
    protected boolean removeOnDaySelection; 

    protected Calendar currentDisplayDate; 

    protected JButton prevMonth; 
    protected JButton nextMonth; 
    protected JButton prevYear; 
    protected JButton nextYear; 

    protected JTextField textField; 

    protected List<ActionListener> popupListeners = 
     new ArrayList<ActionListener>(); 

    protected Popup popup; 

    protected SimpleDateFormat dayName = new SimpleDateFormat("d"); 
    protected SimpleDateFormat monthName = new SimpleDateFormat("MMMM"); 

    protected String iconFile = "datepicker.gif"; 
    protected String[] weekdayNames = 
     {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; 

    public DatePicker() { 
     super(); 
     currentDisplayDate = Calendar.getInstance(); 
     controlsOnTop  = true; 
     removeOnDaySelection = true; 
     createPanel(); 
    } 

    public DatePicker(Calendar date) { 
     super(); 
     setDate(date); 
     controlsOnTop  = true; 
     removeOnDaySelection = true; 
     createPanel(); 
    } 

    public DatePicker(int month, int day, int year) { 
     super(); 
     setDate(month, day, year); 
     controlsOnTop  = true; 
     removeOnDaySelection = true; 
     createPanel(); 
    } 

    public void setDate(String date) { 
     currentDisplayDate = Calendar.getInstance(); 
     editDate(date); 
    } 

    public void setDate(Calendar date) { 
     currentDisplayDate = date; 
     createPanel(); 
     validate(); 
     repaint(); 
    } 

    public void setDate(int month, int day, int year) { 
     currentDisplayDate = Calendar.getInstance(); 
     currentDisplayDate.set(expandYear(year), month - 1, day); 
     createPanel(); 
     validate(); 
     repaint(); 
    } 

    protected int expandYear(int year) { 
     if (year < 100) {     // 2 digit year 
      int currentYear = Calendar.getInstance().get(Calendar.YEAR); 
      int current2DigitYear = currentYear % 100; 
      int currentCentury = currentYear/100 * 100; 
      // set 2 digit year range +20/-80 from current year 
      int high2DigitYear = (current2DigitYear + 20) % 100; 
      if (year <= high2DigitYear) { 
       year += currentCentury; 
      } 
      else { 
       year += (currentCentury - 100); 
      } 
     } 
     return year; 
    } 

    public void setControlsOnTop(boolean flag) { 
     controlsOnTop = flag; 
     createPanel(); 
     validate(); 
     repaint(); 
    } 

    public void setRemoveOnDaySelection(boolean flag) { 
     removeOnDaySelection = flag; 
    } 

    public Popup getPopup(Container c) { 
     if (popup == null) { 
      Point p = c.getLocation(); 
      PopupFactory factory = PopupFactory.getSharedInstance(); 
      popup = factory.getPopup(c, this, p.x, p.y); 
     } 
     return popup; 
    } 

    public void popupShow(Container c) { 
     getPopup(c); 
     popup.show(); 
    } 

    public void popupHide() { 
     popup.hide(); 
    } 

    public Calendar getCalendarDate() { 
     return currentDisplayDate; 
    } 

    public Date getDate() { 
     return currentDisplayDate.getTime(); 
    } 

    public String getFormattedDate() { 
     return Integer.toString(getMonth()) + "/" + 
      Integer.toString(getDay()) + "/" + 
      Integer.toString(getYear()); 
    } 

    public int getMonth() { 
     return currentDisplayDate.get(Calendar.MONTH) + 1; 
    } 

    public int getDay() { 
     return currentDisplayDate.get(Calendar.DAY_OF_MONTH); 
    } 

    public int getYear() { 
     return currentDisplayDate.get(Calendar.YEAR); 
    } 

    public ImageIcon getImage() { 
     return createImageIcon(iconFile, "Calendar date picker"); 
    } 

    /* 
    * Returns an ImageIcon, or null if the path was invalid. 
    */ 
    protected ImageIcon createImageIcon(String path, String description) { 
     URL imgURL = getClass().getResource(path); 
     String fileName = imgURL.getFile().replace("bin/", "src/"); 
     fileName = fileName.replace("%20", " ").substring(1); 
     ImageIcon icon = new ImageIcon(fileName, description); 
     return icon; 
    } 

    protected void createPanel() { 
     removeAll(); 
     setBorder(BorderFactory.createLineBorder(Color.black, 3)); 
     setFocusable(true); 
     setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 
     if (controlsOnTop) { 
      add(createControls()); 
      add(createCalendar()); 
     } else { 
      add(createCalendar()); 
      add(createControls()); 
     } 
     Dimension d = getPreferredSize(); 
     setPreferredSize(new Dimension(d.width, d.height + 8)); 
    } 

    protected JPanel createControls() {   
     JPanel c = new JPanel(); 
     c.setBorder(BorderFactory.createRaisedBevelBorder()); 
     c.setFocusable(true); 
     c.setLayout(new FlowLayout(FlowLayout.CENTER)); 

     prevYear = new JButton("<<"); 
     c.add(prevYear); 
     prevYear.setMargin(new Insets(0,0,0,0)); 
     prevYear.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 
       addYear(-1);   
      } 
     }); 

     prevMonth = new JButton("<"); 
     c.add(prevMonth); 
     prevMonth.setMargin(new Insets(0,0,0,0)); 
     prevMonth.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 
       addMonth(-1);  
      } 
     }); 


     textField = new JTextField(getFormattedDate(), 10); 
     c.add(textField); 
     textField.setEditable(true); 
     textField.setEnabled(true); 
     textField.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       editDate(textField.getText()); 
      } 
     }); 

     nextMonth = new JButton(">"); 
     c.add(nextMonth); 
     nextMonth.setMargin(new Insets(0,0,0,0)); 
     nextMonth.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 
       addMonth(+1); 
      } 
     }); 

     nextYear = new JButton(">>"); 
     c.add(nextYear); 
     nextYear.setMargin(new Insets(0,0,0,0)); 
     nextYear.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 
       addYear(+1);  
      } 
     }); 

     return c; 
    } 

    protected JPanel createCalendar() { 
     JPanel x = new JPanel(); 
     GridBagLayout gridbag = new GridBagLayout(); 
     GridBagConstraints c = new GridBagConstraints(); 

     x.setFocusable(true); 
     x.setLayout(gridbag); 

     String month = monthName.format(currentDisplayDate.getTime()); 
     String year = Integer.toString(getYear()); 

     c.gridx  = 0; 
     c.gridy  = 0; 
     c.gridwidth = 7; 
     c.gridheight = 1; 
     JLabel title = new JLabel(month + " " + year); 
     x.add(title, c); 
     Font font  = title.getFont(); 
//  Font titleFont = new Font(font.getName(), font.getStyle(), 
//    font.getSize() + 2); 
     Font weekFont = new Font(font.getName(), font.getStyle(), 
       font.getSize() - 2); 
     title.setFont(font); 

     c.gridy  = 1; 
     c.gridwidth = 1; 
     c.gridheight = 1; 
     for (c.gridx = 0; c.gridx < 7; c.gridx++) { 
      JLabel label = new JLabel(weekdayNames[c.gridx]); 
      x.add(label, c); 
      label.setFont(weekFont); 
     } 

     Calendar draw = (Calendar) currentDisplayDate.clone(); 
     draw.set(Calendar.DATE, 1); 
     draw.add(Calendar.DATE, -draw.get(Calendar.DAY_OF_WEEK) + 1); 
     int monthInt = currentDisplayDate.get(Calendar.MONTH); 
//  monthInt = 0; 
//  System.out.println("Current month: " + monthInt); 

     c.gridwidth = 1; 
     c.gridheight = 1; 
     int width = getFontMetrics(weekFont).stringWidth(" Wed "); 
     int width1 = getFontMetrics(weekFont).stringWidth("Wed"); 
     int height = getFontMetrics(weekFont).getHeight() + 
       (width - width1); 

     for (c.gridy = 2; c.gridy < 8; c.gridy++) { 
      for (c.gridx = 0; c.gridx < 7; c.gridx++) { 
       JButton dayButton; 
//    System.out.print("Draw month: " + draw.get(Calendar.MONTH)); 
       if (draw.get(Calendar.MONTH) == monthInt) { 
        String dayString = dayName.format(draw.getTime()); 
        if (draw.get(Calendar.DAY_OF_MONTH) < 10) 
         dayString = " " + dayString; 
        dayButton = new JButton(dayString); 
       } else { 
        dayButton = new JButton(); 
        dayButton.setEnabled(false); 
       } 
//    System.out.println(", day: " + dayName.format(draw.getTime())); 
       x.add(dayButton, c); 
       Color color = dayButton.getBackground(); 
       if ((draw.get(Calendar.DAY_OF_MONTH) == getDay()) && 
         (draw.get(Calendar.MONTH) == monthInt)) { 
        dayButton.setBackground(Color.yellow); 
//     dayButton.setFocusPainted(true); 
//     dayButton.setSelected(true); 
       } else 
        dayButton.setBackground(color); 
       dayButton.setFont(weekFont); 
       dayButton.setFocusable(true); 
       dayButton.setPreferredSize(new Dimension(width, height)); 
       dayButton.setMargin(new Insets(0,0,0,0)); 
       dayButton.addActionListener(new ActionListener() { 
        public void actionPerformed(ActionEvent e) { 
         changeDay(e.getActionCommand()); 
        } 

       }); 
       draw.add(Calendar.DATE, +1); 
      } 
//   if (draw.get(Calendar.MONTH) != monthInt) break; 
     } 
     return x; 
    } 

    public void addMonth(int month) { 
     currentDisplayDate.add(Calendar.MONTH, month); 
     createPanel(); 
     validate(); 
     repaint(); 
    } 

    public void addYear(int year) { 
     currentDisplayDate.add(Calendar.YEAR, year); 
     createPanel(); 
     validate(); 
     repaint(); 
    } 

    public void editDate(String date) { 
     parseDate(date); 
     createPanel(); 
     validate(); 
     repaint(); 
    } 

    protected void parseDate(String date) { 
     String[] parts = date.split("/"); 
     if (parts.length == 3) { 
      currentDisplayDate.set(Calendar.MONTH, 
        Integer.valueOf(parts[0]) - 1); 
      currentDisplayDate.set(Calendar.DAY_OF_MONTH, 
        Integer.valueOf(parts[1])); 
      currentDisplayDate.set(Calendar.YEAR, 
        expandYear(Integer.valueOf(parts[2]))); 
     } else if (parts.length == 2) { 
      currentDisplayDate = Calendar.getInstance(); 
      currentDisplayDate.set(Calendar.MONTH, 
        Integer.valueOf(parts[0]) - 1); 
      currentDisplayDate.set(Calendar.DAY_OF_MONTH, 
        Integer.valueOf(parts[1])); 
     } else { 
      // invalid date 
      currentDisplayDate = Calendar.getInstance(); 
     } 
    } 

    public void changeDay(String day) { 
     currentDisplayDate.set(Calendar.DAY_OF_MONTH, 
       Integer.valueOf(day.trim())); 
     if (removeOnDaySelection) { 
      firePopupEvent(new ActionEvent(this, 1, "hide")); 
      popup = null; 
     } else { 
      createPanel(); 
      validate(); 
      repaint(); 
     } 
    } 

    public void addPopupListener(ActionListener l) { 
     popupListeners.add(l); 
    } 

    public void removePopupListener(ActionListener l) { 
     popupListeners.remove(l); 
    } 

    public void firePopupEvent(ActionEvent e) { 
     for (int i = popupListeners.size() - 1; i >= 0; i--) { 
      ActionListener l = popupListeners.get(i); 
      l.actionPerformed(e); 
     } 
    } 

    public static void main(String[] args) { 
     final JFrame frame = new JFrame("Date Picker"); 
     Container pane = frame.getContentPane(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setPreferredSize(new Dimension(450, 250)); 
     pane.setLayout(new FlowLayout(FlowLayout.LEFT)); 
     pane.add(new JLabel("Birthdate: ")); 
     final JTextField testDate = new JTextField(10); 
     pane.add(testDate); 
     final DatePicker dp = new DatePicker(); 
     ImageIcon ii = dp.getImage(); 
//  System.out.println(ii.getIconWidth()); 
//  System.out.println(ii.getIconHeight()); 
     final JButton datePicker = new JButton(ii); 
     pane.add(datePicker); 
     datePicker.setPreferredSize(new Dimension(30, 24)); 
     datePicker.setMargin(new Insets(0,0,0,0)); 
     datePicker.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       dp.setDate(testDate.getText()); 
       dp.popupShow(datePicker); 
      } 
     }); 
     dp.addPopupListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       testDate.setText(dp.getFormattedDate()); 
       dp.popupHide(); 
      } 
     }); 
     frame.pack(); 
     frame.setFocusable(true); 
     frame.setResizable(true); 
     frame.setVisible(true); 
    } 
} 
5

Tôi biết đây là câu hỏi cũ, nhưng cuối cùng tôi đã tìm thấy câu trả lời ở đây, từ nhận xét của kleopatra về bản trình diễn SwingsLab.

Bản demo SwingsLab cung cấp một ví dụ về cách đặt tiêu đề lịch tùy chỉnh trên một cơ sở cho mỗi thành phần, nhưng đây là đoạn code tôi thực sự sử dụng (đây là toàn cầu; mỗi ứng dụng):

UIManager.put(CalendarHeaderHandler.uiControllerID, SpinningCalendarHeaderHandler.class.getName()); 
datePicker = new JXDatePicker(); 
datePicker.getMonthView().setZoomable(true); //this is needed for custom header 

Đây có vẻ là mã thử nghiệm (chưa hoàn toàn công khai), vì vậy hãy sử dụng rủi ro của riêng mình. Hy vọng nó giúp.

SwingsLab Demo

+0

đẹp, ai đó _really_ đã xem bản demo :-) – kleopatra

+0

@Radiace Wei Q Ong Cảm ơn bạn đã đăng bài nhưng sử dụng mã không hiển thị năm bạn hiển thị trong hình ảnh. Tôi có cùng yêu cầu. –

+0

@Syed Muhammad Mubashir nó làm việc cho tôi mặc dù. Có thể thử mã trong bản demo SwingsLab? Hình ảnh là từ bản demo. –

0

cải thiện:

các DateTimePicker là quá xa từ nút nên

tại dòng 139:

public Popup getPopup(Container c) { 

    if (popup == null) { 

     Point p = c.getLocation(); 

     PopupFactory factory = PopupFactory.getSharedInstance(); 


// FramePrinc.Location.x ==> public static Point Location ; in class FramePrinc 

    popup = factory.getPopup(c, this, FramePrinc.Location.x,FramePrinc.Location.y); 

    } 

    return popup; 

} 

và bên trong hành động mà bạn có được vị trí của thành phần

datePicker.addActionListener(new ActionListener() { 

     public void actionPerformed(ActionEvent e) { 

      //Add this Line and you will get a good result 

      Location = datePickerButton.getLocationOnScreen(); 

      dp.setDate(testDate.getText()); 

      dp.popupShow(datePicker); 
     } 
    }); 

Vì vậy:

  • tạo một lớp: ví dụ FramePrinc
  • tạo public static Point Location
  • thêm bạn dateTimePiker bên trong một bảng điều khiển
  • đặt dòng đó tôi đã nói bên trong nút hành động

chúc may mắn

Grine_Amine Improvement :)

0

Việc thiếu các nút tích hợp sẵn trong năm trước/năm tiếp theo trong JXDatePicker là lý do chính khiến tôi không sử dụng gói đó cho phần mềm của mình. Nếu không, đó là một trong những công cụ chọn ngày tốt nhất hiện có.

Cách khác, tôi khuyên bạn nên LGoodDatePicker. Nó có các nút để quay trở lại và chuyển tiếp trong năm, cộng với một trình đơn để chọn bất kỳ năm mong muốn nào. Công bố thông tin: Tôi là nhà phát triển chính về dự án này. Xin vui lòng cho tôi biết nếu nó phục vụ nhu cầu của bạn.

LGoodDatePicker trang chủ: https://github.com/LGoodDatePicker/LGoodDatePicker

Có một bản demo làm việc (một file jar thực thi) trong phần phát hành, và một danh sách các tính năng chính trên trang gitub.

Ảnh chụp màn hình bên dưới.

enter image description here