2013-04-19 19 views
5

Używam SwingX JXDatePicker i nie mogę się dowiedzieć, jak zapewnić przyciski następnego/poprzedniego roku (ponieważ domyślnie udostępnia tylko przyciski następnego/poprzedniego miesiąca).Java Swing JXDatePicker

Wygląda na to, że SwingX nie jest już konserwowany: czy powinienem używać nowszego komponentu jako selektora dat?

Każda pomoc/podpowiedź byłaby bardzo doceniana. Dzięki Thomas

UPDATE:

wyjaśnić kwestię, dodałem zrzut ekranu JXDatePicker i podświetlony na czerwono następnego/poprzedniego miesiąca przycisków. Pytania brzmią: jak dodać przyciski, które wprowadzą kalendarz do następnego/poprzedniego roku? Należy pamiętać, że nowe przyciski muszą być standardowymi komponentami, ponieważ muszą być renderowane przez określonego menedżera uczuć Look & (Insusbtantial w tym przypadku).

Dziękujemy

enter image description here

+0

Sprawdź się [to] (http://stackoverflow.com/questions/1339354/what-are-good-java-date-chooser-swing-gui-widgets) pytanie o listę w górę do aktualnych alternatyw. Polecam wypróbować niektóre z nich. – Kezz101

+0

to jest zachowane - obecna wersja 1.6.5-1, ale nie rozumiem, o co ci chodzi: czego dokładnie chcesz? I dlaczego nie ma możliwości dostosowania, jak opisano w prezentacjach swingx (webstartowalny link na stronie projektu)? – kleopatra

+0

@MrD dlaczego rozpowszechnianie nieistotnych linków? Ten dotyczy zupełnie niezwiązanego problemu ... – kleopatra

Odpowiedz

2

polecam korzystania Microba datepicker. Jest wysoce konfigurowalny i robi dokładnie to, co chcesz.

http://microba.sourceforge.net/

enter image description here enter image description here

Edit:

Ok widzę. Zrobiłem trochę badań i wygląda na to, że funkcja, której szukasz, w rzeczywistości nie jest obecna w JXDatePicker.

Inną alternatywą, którą znalazłem, jest: JDatePicker pod numerem http://sourceforge.net/projects/jdatepicker/.

Główna strona www: https://jdatepicker.org/

ta jest nadal wspierany i wydaje się mieć żądaną funkcję.

+0

Niestety, ten komponent nie jest już dłużej utrzymywany (bez wydania przez ostatnie 5 lat): jest dla nas zbyt ryzykowny, ponieważ przyszła wersja Java/Swing może go złamać i nie zostanie naprawiony ... – Tom

+0

@Omid can you powiedz mi, jak to dodać w komponencie Swing i przeciągnij w jframe, dodałem za pomocą JPallete Manager, ale ten komponent nie przeciąga do jframe. –

+0

Piszę Net Beans 7.1, czy jest to kompatybilne z NeBeans 7.1 i ramką Swing. –

1

To jest coś, co ułożyłem kilka lat temu. Możesz go zmodyfikować zgodnie ze swoimi potrzebami.

enter image description here

Musisz to zdjęcie, aby uruchomić główny Test: calendar icon. Po prostu umieść go w tym samym katalogu co źródło o nazwie 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

wiem, jest to stara sprawa, ale w końcu znalazłem odpowiedź tutaj, z komentarzem Kleopatra chodzi o demo SwingsLab.

SwingsLab demo stanowi przykład, jak ustawić niestandardowy nagłówek kalendarza na zasadzie per-komponent, ale jest to kod I rzeczywiście używany (jest to globalny; per-application):

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

Wydaje się, że jest to kod eksperymentalny (jeszcze nie w pełni publiczny), więc używaj go na własne ryzyko. Mam nadzieję, że to pomoże.

SwingsLab Demo

+0

miło, ktoś _nie_ spojrzał na demo :-) – kleopatra

+0

@Radiace Wei Q Ong Dzięki za wpis, ale używanie twojego kodu nie pokazuje roku, jak pokazujesz na obrazku. Mam ten sam wymóg. –

+0

@Syed Muhammad Mubashir działa jednak dla mnie. Może wypróbujesz kod w wersji demonstracyjnej SwingsLab? Zdjęcie pochodzi z wersji demo. –

0

poprawa:

DateTimePicker jest zbyt daleko od przycisku tak

na linii 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; 

} 

i wewnątrz działania można dostać od lokalizacji składnik

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

Więc:

  • utworzyć inną klasę, na przykład: FramePrinc
  • utworzyć publiczny punkt statyczny Lokalizacja
  • dodać Ci dateTimePiker wewnątrz panelu
  • umieścić linię powiedziałem wewnątrz przycisku akcji

powodzenia

Ulepszenie Grine_Amine :)

0

Brak wbudowanych przycisków poprzedniego/następnego roku w JXDatePicker jest głównym powodem, dla którego nie skorzystałem z tego pakietu dla mojego oprogramowania. W przeciwnym razie jest to jeden z lepszych narzędzi do zbierania danych.

Jako alternatywę, polecam LGoodDatePicker. Posiada przyciski do cofania się i przewijania w roku, a także menu do wyboru w dowolnym roku. Uczciwe ujawnienie: jestem głównym programistą tego projektu. Daj mi znać, jeśli spełnia Twoje potrzeby.

LGoodDatePicker strona domowa: https://github.com/LGoodDatePicker/LGoodDatePicker

Jest demo działa (wykonywalny plik jar) w sekcji uwalniania, a lista funkcji bazowych na stronie gitub.

Zrzuty ekranu znajdują się poniżej.

enter image description here