/* * $Id$ * * Copyright 2007 Sun Microsystems, Inc., 4150 Network Circle, * Santa Clara, California 95054, U.S.A. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ package org.jdesktop.swingx.plaf.basic; import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.text.DateFormat; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Locale; import java.util.logging.Logger; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Box; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import org.jdesktop.swingx.InteractiveTestCase; import org.jdesktop.swingx.JXDatePicker; import org.jdesktop.swingx.JXFrame; import org.jdesktop.swingx.JXMonthView; import org.jdesktop.swingx.SwingXUtilities; import org.jdesktop.swingx.action.AbstractActionExt; import org.jdesktop.swingx.calendar.DateSelectionModel.SelectionMode; import org.jdesktop.swingx.plaf.basic.BasicMonthViewUI.RenderingHandler; import org.jdesktop.swingx.renderer.FormatStringValue; import org.jdesktop.swingx.renderer.StringValue; /** * TODO add type doc * * @author Jeanette Winzenburg */ public class BasicMonthViewVisualCheck extends InteractiveTestCase { @SuppressWarnings("unused") private static final Logger LOG = Logger .getLogger(BasicMonthViewVisualCheck.class.getName()); public static void main(String[] args) { BasicMonthViewVisualCheck test = new BasicMonthViewVisualCheck(); try { // test.runInteractiveTests(); test.runInteractiveTests(".*Rendering.*"); // test.runInteractiveTests(".*Debug.*"); } catch (Exception e) { e.printStackTrace(); } } public static class MyMonthViewUI extends BasicMonthViewUI { @SuppressWarnings({"UnusedDeclaration"}) public static ComponentUI createUI(JComponent c) { return new MyMonthViewUI(); } @Override protected CalendarRenderingHandler createRenderingHandler() { return new MyCalendarRenderingHandler(); } } /** * Issue #1062-swingx: core formats don't use arabic digits. Opened rendering */ public static class MyCalendarRenderingHandler extends RenderingHandler { @Override protected StringValue createDayStringValue(Locale locale) { if (locale == null) { locale = Locale.getDefault(); } SimpleDateFormat dateFormat = new SimpleDateFormat("d", locale); LOG.info("got here? " + locale.getCountry() + "-" + locale.getLanguage()); adjustFormatSymbols(locale, (DecimalFormat) dateFormat.getNumberFormat()); FormatStringValue sv = new FormatStringValue(dateFormat) { @Override public String getString(Object value) { if (value instanceof Calendar) { ((DateFormat) getFormat()).setTimeZone(((Calendar) value).getTimeZone()); value = ((Calendar) value).getTime(); } return super.getString(value); } }; return sv; } /** * @param locale * @param df */ private void adjustFormatSymbols(Locale locale, DecimalFormat df) { if ("ar".equals(locale.getLanguage())) { DecimalFormatSymbols dfs = df.getDecimalFormatSymbols(); // set the beginning of the range to Arabic digits dfs.setZeroDigit('\u0660'); df.setDecimalFormatSymbols(dfs); } } @Override protected StringValue createWeekOfYearStringValue(Locale locale) { if (locale == null) { locale = Locale.getDefault(); } DecimalFormat format = (DecimalFormat) NumberFormat.getInstance(locale); adjustFormatSymbols(locale, format); StringValue wsv = new FormatStringValue(format) { @Override public String getString(Object value) { if (value instanceof Calendar) { value = ((Calendar) value).get(Calendar.WEEK_OF_YEAR); } return super.getString(value); } }; return wsv; } } /** * Issue #750-swingx: use rendering to side-step antialiase probs. * * Debugging ... */ public void interactiveRenderingOn() { new JXMonthView(); // KEEP this is global state - uncomment for debug painting completely // // use spinning navigation header if zoomable // UIManager.put(CalendarHeaderHandler.uiControllerID, "org.jdesktop.swingx.plaf.basic.SpinningCalendarHeaderHandler"); // // configure header: arrows around month text // UIManager.put(SpinningCalendarHeaderHandler.ARROWS_SURROUND_MONTH, Boolean.TRUE); // // configuter header: allow focus in spinner text (== editable) // UIManager.put(SpinningCalendarHeaderHandler.FOCUSABLE_SPINNER_TEXT, Boolean.TRUE); // // custom ui delegate for arabic digits in formats // UIManager.put(JXMonthView.uiClassID, "org.jdesktop.swingx.plaf.basic.BasicMonthViewUIVisualCheck$MyMonthViewUI"); // // force picker to use a zoomable monthView by default // UIManager.put("JXDatePicker.forceZoomable", Boolean.TRUE); // KEEP this is global state - uncomment for debug painting completely UIManager.put("JXMonthView.trailingDayForeground", Color.YELLOW); UIManager.put("JXMonthView.leadingDayForeground", Color.ORANGE); UIManager.put("JXMonthView.weekOfTheYearForeground", Color.GREEN); UIManager.put("JXMonthView.unselectableDayForeground", Color.MAGENTA); String frameTitle = "Debug painting: rendering on"; showDebugMonthView(frameTitle); } /** * @param frameTitle * @param disableRendering */ private void showDebugMonthView(String frameTitle) { final JXMonthView monthView = new JXMonthView(); LOG.info("todayBack: " + monthView.getTodayBackground()); // monthView.setZoomable(true); monthView.setDayForeground(Calendar.SUNDAY, Color.BLUE); monthView.setDaysOfTheWeekForeground(Color.RED); monthView.setFlaggedDayForeground(Color.CYAN); monthView.setSelectionBackground(Color.GRAY); monthView.setSelectionForeground(Color.GREEN); monthView.setTodayBackground(Color.PINK); monthView.setTraversable(true); monthView.setShowingWeekNumber(true); monthView.setShowingLeadingDays(true); monthView.setShowingTrailingDays(true); monthView.setSelectionMode(SelectionMode.SINGLE_INTERVAL_SELECTION); monthView.setPreferredColumnCount(2); monthView.setPreferredRowCount(2); final JXFrame frame = wrapInFrame(monthView, frameTitle); addComponentOrientationToggle(frame); Action toggleTraversable = new AbstractAction("toggle zoomable") { public void actionPerformed(ActionEvent e) { monthView.setZoomable(!monthView.isZoomable()); } }; addAction(frame, toggleTraversable); addEnabledToggle(frame, monthView); final JXDatePicker picker = new JXDatePicker(); picker.getMonthView().setShowingWeekNumber(monthView.isShowingWeekNumber()); picker.getMonthView().setZoomable(true); Action toggleShowingWeekNumbers = new AbstractAction("toggle weekNumbers") { public void actionPerformed(ActionEvent e) { monthView.setShowingWeekNumber(!monthView.isShowingWeekNumber()); picker.getMonthView().setShowingWeekNumber(monthView.isShowingWeekNumber()); } }; addAction(frame, toggleShowingWeekNumbers); picker.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals(JXDatePicker.CANCEL_KEY)) return; if (picker.getDate() == null) return; monthView.setFlaggedDates(picker.getDate()); } }); final JXDatePicker unselectable = new JXDatePicker(); unselectable.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals(JXDatePicker.CANCEL_KEY)) return; if (unselectable.getDate() == null) return; monthView.setUnselectableDates(unselectable.getDate()); } }); final JComboBox zoneSelector = new JComboBox(Locale.getAvailableLocales()); // Synchronize the monthView's and selector's zones. zoneSelector.setSelectedItem(monthView.getLocale()); // Set the monthView's time zone based on the selected time zone. zoneSelector.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { Locale zone = (Locale) zoneSelector.getSelectedItem(); SwingXUtilities.setComponentTreeLocale(frame, zone); // monthView.setLocale(zone); // monthView.revalidate(); } }); JComponent pickers = Box.createHorizontalBox(); pickers.add(new JLabel("Flagged: ")); pickers.add(picker); pickers.add(new JLabel("Unselectable: ")); pickers.add(unselectable); pickers.add(new JLabel("Locale: ")); pickers.add(zoneSelector); frame.add(pickers, BorderLayout.SOUTH); show(frame); } /** * Issue #736-swingx: monthView cannot cope with minimalDaysInFirstWeek. * * Debugging ... */ public void interactiveDayAt() { final JXMonthView monthView = new JXMonthView(); monthView.setTraversable(true); monthView.setShowingWeekNumber(true); monthView.setShowingLeadingDays(true); monthView.setShowingTrailingDays(true); monthView.setSelectionMode(SelectionMode.SINGLE_INTERVAL_SELECTION); monthView.setPreferredColumnCount(2); monthView.setPreferredRowCount(2); final BasicMonthViewUI ui = ((BasicMonthViewUI) monthView.getUI()); monthView.addMouseListener(new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { // LOG.info("calendar grid" + ui.calendarGrid); // LOG.info("dayAt " + e.getPoint() + ": " // + "\n" + monthView.getDayAtLocation(e.getX(), e.getY())); // Calendar monthAtLocation = ui.getMonthAtLocation(e.getX(), e.getY()); // LOG.info("month start " + // (monthAtLocation != null ? monthAtLocation.getTime() : null)); // Point p = ui.getMonthGridPositionAtLocation(e.getX(), e.getY()); // LOG.info("month bounds from logical " + // p + " \n " + // ui.getMonthBounds(p.y, p.x)); // LOG.info("month bounds at location" + // ui.getMonthBoundsAtLocation(e.getX(), e.getY())); LOG.info("day grid position " + ui.getDayGridPositionAtLocation(e.getX(), e.getY()) + "\nday bounds " + ui.getDayBoundsAtLocation(e.getX(), e.getY())); } }); Action action = new AbstractActionExt("toggle minimal") { public void actionPerformed(ActionEvent e) { int minimal = monthView.getSelectionModel().getMinimalDaysInFirstWeek(); monthView.getSelectionModel().setMinimalDaysInFirstWeek(minimal > 1 ? 1 : 4); } }; final JXFrame frame = wrapInFrame(monthView, "test mapping: printed on mouse release"); addAction(frame, action); addComponentOrientationToggle(frame); frame.pack(); frame.setVisible(true); } /** * Issue #736-swingx: monthView cannot cope with minimalDaysInFirstWeek. * * Here: look at impact of forcing the minimalDays to a value different * from the calendar. Days must be displayed in starting from the * first row under the days-of-week. * * Not yet completely fixed: for very late firstDayOfWeek, the Jan is incompletely * painted for mininalDays > 1. Rare enough to ignore for now? */ public void interactiveMinimalDaysInFirstWeek() { final JXMonthView monthView = new JXMonthView(); monthView.setTraversable(true); monthView.setShowingWeekNumber(true); monthView.setShowingLeadingDays(true); monthView.setShowingTrailingDays(true); monthView.setSelectionMode(SelectionMode.SINGLE_INTERVAL_SELECTION); Action action = new AbstractActionExt("toggle minimal") { public void actionPerformed(ActionEvent e) { int minimal = monthView.getSelectionModel().getMinimalDaysInFirstWeek(); monthView.getSelectionModel().setMinimalDaysInFirstWeek(minimal > 1 ? 1 : 4); } }; final JXFrame frame = wrapInFrame(monthView, "click unselectable fires ActionEvent"); addAction(frame, action); addComponentOrientationToggle(frame); final JComboBox dayOfWeekComboBox = new JComboBox(new String[]{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}); dayOfWeekComboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int selected = dayOfWeekComboBox.getSelectedIndex(); monthView.setFirstDayOfWeek(selected + Calendar.SUNDAY); } }); dayOfWeekComboBox.setSelectedIndex(monthView.getFirstDayOfWeek() - Calendar.SUNDAY); addStatusComponent(frame, dayOfWeekComboBox); frame.pack(); frame.setVisible(true); } }