的Java Swing JXDatePicker(Java Swing JXDatePicker)

2019-08-31 13:58发布

我使用SwingX JXDatePicker,我无法弄清楚如何提供下一/上一年按钮(因为默认情况下它仅提供下/上一月份按钮)。

此外,似乎SwingX不维护了:我应该使用较新的组件作为日期选择器?

任何帮助/提示将不胜感激。 谢谢,托马斯

更新:

为了澄清这个问题,我添加了一个JXDatePicker截图并以红色下一/上一月份按钮高亮显示。 问题是这样的:如何添加,将带来日历下一个/上一年按钮? 请注意,新的按钮必须是标准部件,因为他们需要通过特定的外观和感觉管理(Insusbtantial在这种情况下)来渲染。

非常感谢

Answer 1:

我会建议使用Microba的DatePicker。 这是高度可定制的和你想要做什么。

http://microba.sourceforge.net/

编辑:

好的我明白了。 嗯,我做了一些研究,似乎你正在寻找的功能实际上是不存在的JXDatePicker。

不同的替代方案,我发现是:在JDatePicker http://sourceforge.net/projects/jdatepicker/ 。

主要网站: https://jdatepicker.org/

这仍然支持,似乎有你想要的功能。



Answer 2:

我知道这是一个老问题,但我终于找到了答案在这里,约SwingsLab演示克列奥帕特拉的评论。

所述SwingsLab演示提供了如何设置在每个组件的基础自定义日历头的示例,但是这是我实际使用的代码(这是全局的;每个应用程序):

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

这似乎是实验代码(不完全不失),所以在自己的风险。 希望能帮助到你。



Answer 3:

这是我几年前放在一起。 你可以修改它以满足您的需求。

你需要这个映像运行主要的测试: 。 只要把它放在同一目录与名称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);
    }
}


Answer 4:

改进:

该dateTimePicker的是太远的按钮,

在行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;

}

和行动中你得到的组件的位置

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);
        }
    });

所以:

  • 创建另一个类:例如FramePrinc
  • 创建公共静态点位置
  • 加你dateTimePiker在面板内部
  • 把我的按钮动作里面说行

祝好运

Grine_Amine改进:)



Answer 5:

缺乏JXDatePicker内置一个/下一个年度的按钮是主要的原因,我最终没有使用包我的软件。 否则,它是更好的日期选择器就在那里之一。

作为替代方案,我建议LGoodDatePicker。 它有回去和向前上一年按钮,再加上选择任何所需一年的菜单。 公平披露:我对这个项目的主要开发商。 请让我知道,如果它成为你的需求。

LGoodDatePicker主页: https://github.com/LGoodDatePicker/LGoodDatePicker

有一个在释放部分中的工作演示(可执行的JAR文件),以及核心功能的gitub页上的列表。

截图如下。



文章来源: Java Swing JXDatePicker