Java Swing JXDatePicker

前端 未结 5 542
执笔经年
执笔经年 2020-12-11 06:15

I\'m using SwingX JXDatePicker and I can\'t figure out how to provide next/previous year buttons (as by default it only provides next/previous month buttons).

Also,

5条回答
  •  醉酒成梦
    2020-12-11 07:14

    This is something I put together a few years ago. You can modify it to meet your needs.

    enter image description here

    You'll need this image to run the main test: calendar icon. Just put it in the same directory as the source with the name 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 popupListeners = 
            new ArrayList();
    
        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);
        }
    }
    

提交回复
热议问题