2013-04-19 3 views
5

Я использую SwingX JXDatePicker, и я не могу понять, как обеспечить кнопки следующего/предыдущего года (так как по умолчанию он предоставляет только кнопки следующего/предыдущего месяца).Java Swing JXDatePicker

Кроме того, похоже, что SwingX больше не поддерживается: следует ли использовать более поздний компонент в качестве выбора даты?

Любая помощь/подсказка были бы весьма признательны. Спасибо, Томас

UPDATE:

Для выяснения вопроса, я добавил скриншот JXDatePicker и выделены красным цветом следующей/предыдущей кнопки месяц. Вопросы таким образом: как добавить кнопки, которые приведут календарь к следующему/предыдущему году? Обратите внимание, что новые кнопки должны быть стандартными компонентами, так как они должны быть визуализированы конкретным Look & Feel manager (в этом случае несовместимо).

Большое спасибо

enter image description here

+0

Заканчивать [это] (http://stackoverflow.com/questions/1339354/what-are-good-java-date-chooser-swing-gui-widgets) вопрос для списка вверх - современные варианты. Я бы рекомендовал попробовать некоторые из них. – Kezz101

+0

it _is_ поддерживается - текущая версия 1.6.5-1, но не понимает, что вам нужно: что именно вы хотите? И почему почему настройка, описанная в демонстрационных версиях swingx (веб-ссылка на странице проекта), не помогает) – kleopatra

+0

@MrD почему распространение несущественных ссылок? Этот вопрос касается совершенно несвязанной проблемы ... – kleopatra

ответ

2

Я бы рекомендовал использовать Microba DatePicker. Он очень настраиваемый и делает именно то, что вы хотите.

http://microba.sourceforge.net/

enter image description here enter image description here

Edit:

Ok я вижу. Хорошо, я сделал некоторые исследования, и кажется, что функция, которую вы ищете, на самом деле отсутствует в JXDatePicker.

Другая альтернатива, которую я нашел, это: JDatePicker по адресу http://sourceforge.net/projects/jdatepicker/.

Главный сайт: https://jdatepicker.org/

Это все еще поддерживается и, кажется, функция, которую вы хотите.

+0

К сожалению, этот компонент не поддерживается больше (без релиза за последние 5 лет): это слишком рискованно для нас, так как будущая версия Java/Swing может сломать его, и он не будет исправлен ... – Tom

+0

@ Omid скажите мне, как я добавляю это в компонент Swing и перетаскиваю в jframe, я добавил использование JPallete Manager, но этот компонент не перетаскивается в jframe. –

+0

Я пою Net Beans 7.1, совместим ли это с NeBeans 7.1 и Swing frame work. –

1

Это то, что я собрал несколько лет назад. Вы можете изменить его в соответствии с вашими потребностями.

enter image description here

Вам нужно это изображение, чтобы запустить основной тест: calendar icon. Просто поместите его в тот же каталог, что и источник с именем 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

Я знаю, что это старый вопрос, но я, наконец, нашел ответ здесь, от Клеопатры комментарий о SwingsLab демо.

SwingsLab демо представляет собой пример того, как установить пользовательский календарь заголовок на основе каждого компонента, но это код, я использовал (это глобальное, для каждого приложения):

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

Это, кажется, экспериментальный код (пока еще не полностью открытый), поэтому используйте на свой страх и риск. Надеюсь, поможет.

SwingsLab Demo

+0

милый, кто-то _really_ посмотрел на демо :-) – kleopatra

+0

@Radiace Wei Q Ong Спасибо за сообщение, но используя ваш код doesnot показывает год, как вы показываете на картинке. У меня такое же требование. –

+0

@ Syed Muhammad Mubashir это работает для меня, хотя. Возможно, попробуйте код в демоверсии SwingsLab? Картинка из демонстрации. –

0

улучшение:

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 Improvement :)

0

Отсутствие встроенных кнопок предыдущего/следующего года в JXDatePicker является основной причиной, по которой я не использовал этот пакет для своего программного обеспечения. В противном случае это один из лучших сборщиков дат.

В качестве альтернативы я бы рекомендовал LGoodDatePicker. Он имеет кнопки для возврата назад и вперед по году, а также меню для выбора любого желаемого года. Справедливое раскрытие: я являюсь основным разработчиком этого проекта. Пожалуйста, дайте мне знать, если он будет отвечать вашим потребностям.

LGoodDatePicker страница: https://github.com/LGoodDatePicker/LGoodDatePicker

Существует рабочая демо (исполняемый файл JAR) в разделе выпуска, а также перечень основных функций на странице gitub.

Скриншоты ниже.

enter image description here

Смежные вопросы