410013796724260
• Webmoney
R335386147728
Z369087728698
|
в помощь разработчикам Swing-приложений
Пример компонента JDatePickerВ статье рассмотрен пример (example-datepicker) использования компонента JDatePicker модуля base-gui, позволяющего выбирать дату из выпадающего календаря. В основе компонента лежит код, созданный Juan Heyns. Доработанный компонент локализован для русского, английского и немецкого языков, позволяет определить первый день недели [Воскресенье, Понедельник]. На следующем скриншоте представлен интерфейс примера.
В примере рассмотрены следующие возможности API компонента JDatePicker модуля base-gui :
Описание примераПример включает класс ExampleDatePicker, который будет представлен в статье следующим образом :
1. Описание полей классаОписание полей класса ExampleDatePicker включает метки lblFilter, lblFrom и lblTo, компоненты даты dtFrom и dtTo, константы (модификаторы final не приведены в листинге) определения надписей кнопок управления FIRST_DAY, FIRST_DAYS, LOCALIZATION, CHOOSE. Объекты локализации locale (текущий) и locales (возможные), идентификаторы первого дня недели FIRST_DAY_IDX и текущей локализации LOCALE_idx. Константа PATTERN_DATE определяет формат представления даты в интерфейсе примера. Константа SPAN_normal определяет порядок представления надписей на кнопках.
JLabel lblFilter = null;
JLabel lblFrom = null;
JLabel lblTo = null;
JDatePickerImpl dtFrom = null;
JDatePickerImpl dtTo = null;
String[] FIRST_DAY = {"Неделя с <%s>",
"Week from <%s>",
"Woche ab <%s>"};
String[][] FIRST_DAYS = {{"Вс", "По"},
{"Su", "Mo"},
{"Mo", "So"}};
String[] LOCALIZATION = {"Локализация" ,
"Localization" ,
"Lokalisierung"};
String[] CHOOSE = {"Выбор" ,
"Choose" ,
"Auswahl" };
Locale locale = null;
Locale[] locales = {new Locale("ru"),
new Locale("en"),
new Locale("de")};
int FIRST_DAY_IDX = 0;
int LOCALE_idx = 0;
String PATTERN_DATE = "dd.MM.yyyy";
String SPAN_normal =
"<html><span style=\"font-weight:normal\">";
2. Формирование интерфейсаМетод createGUI формирует интерфейс примера. Особый интерес в коде данного метода представляют строки создания двух компонентов JDatePicker :
Примечание : обратите внимание, что для компонентов используются разные модели дат (UtilDateModel, UtilCalendarModel).
private void createGUI()
{
JPanel pnlFilter = new JPanel();
pnlFilter.setLayout(new BorderLayout());
pnlFilter.setPreferredSize(new Dimension(268, 80));
Border border = BorderFactory.createCompoundBorder(
BorderFactory.createEtchedBorder(),
BorderFactory.createEmptyBorder(15, 10, 15, 4));
pnlFilter.setBorder(border);
lblFilter = new JLabel();
lblFilter.setText(SPAN_normal + "Период времени");
// Определение параметров компонентов дат
UtilDateModel modelFrom ;
UtilCalendarModel modelTo ;
JDatePanelImpl datePanelFrom;
JDatePanelImpl datePanelTo ;
DateLabelFormatter dlf ;
modelFrom = new UtilDateModel ();
modelTo = new UtilCalendarModel();
datePanelFrom = new JDatePanelImpl(modelFrom, locale);
datePanelTo = new JDatePanelImpl(modelTo , locale);
dlf = new DateLabelFormatter(PATTERN_DATE);
//-----------------------------------------------------
Dimension dim = new Dimension(100, 20);
Dimension dimLabel = new Dimension( 30, 20);
//-----------------------------------------------------
lblFrom = new JLabel();
lblFrom.setText(SPAN_normal + "c");
lblFrom.setPreferredSize(dimLabel);
dtFrom = new JDatePickerImpl(datePanelFrom, dlf);
dtFrom.setPreferredSize(new Dimension(145, 20));
dtFrom.getJFormattedTextField().setBackground(Color.WHITE);
SpringLayout layoutFilter = new SpringLayout();
JPanel pnlFrom = new JPanel(layoutFilter);
pnlFrom.add(lblFrom);
pnlFrom.add(dtFrom);
pnlFrom.setPreferredSize(dim);
pnlFrom.setSize (dim);
layoutFilter.putConstraint(SpringLayout.WEST, dtFrom, 30,
SpringLayout.EAST, lblFrom);
//-----------------------------------------------------
lblTo = new JLabel();
lblTo.setText(SPAN_normal + "по");
lblTo.setPreferredSize(dimLabel);
dtTo = new JDatePickerImpl(datePanelTo, dlf);
dtTo.setPreferredSize(new Dimension(145, 20));
dtTo.getJFormattedTextField().setBackground(Color.WHITE);
JPanel pnlTo = new JPanel(layoutFilter);
pnlTo.add(lblTo);
pnlTo.add(dtTo);
pnlTo.setPreferredSize(dim);
pnlTo.setSize (dim);
layoutFilter.putConstraint(SpringLayout.WEST, dtTo, 30,
SpringLayout.EAST, lblTo);
//-----------------------------------------------------
pnlFilter.add(pnlFrom, BorderLayout.NORTH);
pnlFilter.add(pnlTo , BorderLayout.SOUTH);
//-----------------------------------------------------
String caption = SPAN_normal +
String.format(FIRST_DAY[LOCALE_idx],
FIRST_DAYS[LOCALE_idx][FIRST_DAY_IDX]);
JButton btnFirstDay = new JButton(caption);
String caption = SPAN_normal + LOCALIZATION[LOCALE_idx];
JButton btnLocale = new JButton(caption);
String caption = SPAN_normal + CHOOSE[LOCALE_idx];
JButton btnFilter = new JButton(caption);
final int WIDTH_BUTTON = 130;
dim = new Dimension (WIDTH_BUTTON, 28);
btnFirstDay.setPreferredSize(dim);
btnLocale .setPreferredSize(dim);
btnFilter .setPreferredSize(dim);
// Панель кнопок управления
JPanel pnlButtons = new JPanel();
pnlButtons.add(btnFirstDay);
pnlButtons.add(btnLocale );
pnlButtons.add(btnFilter );
btnFirstDay.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
changeFirstWeekDay();
String caption = SPAN_normal +
String.format(FIRST_DAY[LOCALE_idx],
FIRST_DAYS[LOCALE_idx][FIRST_DAY_IDX]);
btnFirstDay.setText(caption);
}
});
btnLocale.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
changeLocale();
btnLocale .setText(SPAN_normal +
LOCALIZATION[LOCALE_idx]);
btnFilter .setText(SPAN_normal +
CHOOSE[LOCALE_idx]);
btnFirstDay.setText(SPAN_normal +
String.format(FIRST_DAY[LOCALE_idx],
FIRST_DAYS[LOCALE_idx][FIRST_DAY_IDX]));
}
});
btnFilter.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ChoosedDates();
}
});
getContentPane().add(lblFilter , BorderLayout.NORTH );
getContentPane().add(pnlFilter , BorderLayout.CENTER);
getContentPane().add(pnlButtons, BorderLayout.SOUTH);
}
Обработчики нажатий кнопок управления вызывают методы изменения первого дня недели и текущего языка локализации, вывода сообщения с выбранными датами. 3. Определение первого дня неделиИсходный код компонента JDatePicker, созданный Juan Heyns, допускает только один вариант первого дня недели «Su» (Sunday). Модифицированный компонент JDatePicker модуля base-gui позволяет выбрать первым днём недели как «Понедельник» (Monday), так и «Воскресенье» (Sunday). Для изменения текущего первого дня недели перезагрузки компонента не требуется, достаточно вызвать метод компонента setFirstDayMonday (boolean); истинное значение параметра (true) определяет первый день недели «Понедельник» (Monday). Ниже представлен листинг метода changeFirstWeekDay, который динамически в режиме run-time изменяет первый день недели в окне календаря.
private void changeFirstWeekDay()
{
if (++FIRST_DAY_IDX == 2)
FIRST_DAY_IDX = 0;
dtFrom.setFirstDayMonday (!dtFrom.isFirstDayMonday());
dtTo.setFirstDayMonday (!dtTo .isFirstDayMonday());
}
На следующем скриншоте представлен открытый календарь компонента с первым днем недели «По» (Понедельник).
На скриншоте описания локализации (см. скриншот ниже) представлено окно календаря с первым днём недели «Su» (Sunday/Воскресенье). 4. ЛокализацияЛокализация в примере касается только наименований кнопок и выпадающего окна календаря. Модифицированный компонент JDatePicker модуля base-gui позволяет использовать один из 3-х языков локализации : [русский (по умолчанию), английский, немецкий]. Для переключения языка локализации не требуется перезагрузка компонента, достаточно вызвать метод компонента changeLocale с объектом локализации, например changeLocale(new Locale("ru")). Ниже представлен листинг метода changeLocale, который динамически в режиме run-time изменяет язык локализации окна раскрывающегося календаря.
private void changeLocale()
{
if (++LOCALE_idx >= locales.length)
LOCALE_idx = 0;
dtFrom.changeLocale(locales[LOCALE_idx]);
dtTo .changeLocale(locales[LOCALE_idx]);
}
На скриншоте описания первого дня недели (см.скриншот выше) представлена русскоязычная версия открытого календаря. На следующем скриншоте представлен раскрытый календарь в английской интерпретации : окно выбора месяца, надписи и дни недели представлены на английском языке.
5. Чтение значенийМетод ChoosedDates формирует сообщение с выбранными датами и отображает его в диалоговом окне JOptionPane главного JFrame. Для получения значения даты следует использовать метод getValue модели данных (getModel()) компонента. Если значение даты не определено/выбрано, то метод вернет 'null'. Примечание : поскольку компоненты дат (dtFrom, dtTo) используют разные модели(UtilDateModel и UtilCalendarModel), то имеются и существенные отличия получения выбранного значения даты.
private void ChoosedDates()
{
// Выбранные строки
String msg = "Вы выбрали период с '%s' по '%s'";
String title = "Выбор";
String from = "null";
String to = "null";
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
if (dtFrom.getModel().getValue() != null)
from = sdf.format(dtFrom.getModel().getValue());
if ((dtTo.getModel() instanceof UtilDateModel) &&
(dtTo.getModel().getValue() != null))
to = sdf.format(dtTo.getModel().getValue());
else if ((dtTo.getModel() instanceof UtilCalendarModel) &&
(dtTo.getModel().getValue() != null)) {
Calendar calendar;
calendar = (Calendar) dtTo.getModel().getValue();
to = sdf.format(calendar.getTime());
}
msg = String.format(msg, from, to);
JOptionPane.showMessageDialog (ExampleDatePicker.this,
msg, title, JOptionPane.INFORMATION_MESSAGE);
}
На следующем скриншоте представлено окно с сообщением.
6. Главный класс ExampleDatePickerЛистинг класса ExampleDatePicker (см. код ниже), не включает поля и методы, описанные выше. Полный исходный код примера можно скачать в конце страницы. В конструкторе класса определяется текущий язык локализации и вызывается метод создания интерфейса.
public class ExampleDatePicker extends JFrame
{
public ExampleDatePicker()
{
super("Form example");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(440, 180);
locale = locales[LOCALE_idx];
createGUI();
vsetVisible(true);
}
public static void main(String[] args) {
new ExampleDatePicker();
}
}
Привязка выпадающего календаря к правому/левому краю компонентаНа представленных выше скриншотах видно, что размер компонента по горизонтали меньше ширины открытого календаря. При этом, окно календаря привязано к левой стороне компонента. Исходный JDatePicker, созданный Juan Heyns, не допускал привязку окна календаря к правой стороне компонента при его близком размещении к правой стороне экрана; в этом случае часть календаря не отображалась на экране. Единственным спасением в этом случае было определять ширину компонента не меньше ширины окна календаря. Доработанный JDatePicker модуля base-gui автоматически привязывает всплывающее окно календаря к правому краю компонента при его близком расположении к правой стороне монитора. Чтобы увидеть это достаточно переместить мышью окно примера в правую часть монитора и открыть окно календаря, как это представлено на следующем скриншоте.
Старт примераАрхив примера включает командный файл run-example-datepicker.bat для старта example-datepicker.jar в Windows из командной строки. Запускаемый example-datepicker.jar (runable) может быть стартован не только из командной строки, но и обычным способом (двойным нажатием клавишей мыши), поскольку модуль lib/base-gui-1.0.0.jar включен в classpath манифеста META-INF/MANIFEST.MF. Скачать примерАрхивный файл base-gui-example.zip включает данный пример (example-datepicker) и другие примеры использования модуля base-gui. |
