/* * GridPane.java * * Created on 21 ��� 2006 �., 1:32 * */ package datechooser.view; import datechooser.controller.DateChooseController; import datechooser.controller.FooEventHandler; import datechooser.model.DateChoose; import datechooser.model.FooModel; import datechooser.view.appearance.*; import java.awt.*; import java.awt.event.*; import java.awt.font.FontRenderContext; import java.awt.geom.Rectangle2D; import java.beans.*; import java.io.*; import java.text.DateFormatSymbols; import java.util.*; import javax.swing.*; import javax.swing.border.Border; /** * Days grid panel.<br> * ������ � ������ ����. * @author Androsov Vadim * @since 1.0 */ public class GridPane extends JPanel implements PropertyChangeListener { private static final int TEXT_SHIFT = 8; private DateChoose model; private DateChooseController controller; private AppearancesList appearance; private transient CellAppearance currentAppearance; private String[] weekDays; private Locale locale; private boolean focused; private boolean autoFontSize; private WeekDaysStyle weekStyle; private Rectangle cell; private transient int rows; private transient int cols; private transient int cellWidth; private transient int cellHeight; private transient int widthShift; private transient int heightShift; private transient int widthCounter; private transient int heightCounter; private transient int curWidth; private transient int curHeight; public GridPane() { this(new AppearancesList()); } public GridPane(AppearancesList appearanceList) { setAppearanceList(appearanceList); getAppearance().addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { firePropertyChange("currentAppearance", null, null); repaint(); } }); setFocused(false); setEnabled(true); addFocusListener(new FocusListener() { public void focusGained(FocusEvent e) { setFocused(true); } public void focusLost(FocusEvent e) { setFocused(false); } }); cell = new Rectangle(); setFocusable(true); setModel(new FooModel()); setController(new FooEventHandler()); locale = Locale.getDefault(); weekStyle = WeekDaysStyle.NORMAL; initWeekDays(); } public void setLocale(Locale l) { if (getLocale().equals(l)) return; super.setLocale(l); locale = l; initWeekDays(); repaint(); } public Locale getLocale() { return locale; } private void initWeekDays() { DateFormatSymbols dateSymbols = new DateFormatSymbols(getLocale()); String[] allDays = null; switch (getWeekStyle()) { case FULL: allDays = dateSymbols.getWeekdays(); break; case NORMAL: allDays = dateSymbols.getShortWeekdays(); break; case SHORT: allDays = dateSymbols.getShortWeekdays(); for (int i = 0; i < allDays.length; i++) { if (allDays[i].length() < 2) continue; allDays[i] = allDays[i].substring(0, 1).toLowerCase(); } break; } weekDays = new String[allDays.length - 1]; int firstWD = Calendar.getInstance(getLocale()).getFirstDayOfWeek(); for (int i = 0; i < allDays.length - 1; i++) { weekDays[i] = allDays[firstWD]; if (firstWD < (allDays.length - 1)) { firstWD++; } else { firstWD = 1; } } allDays = null; } protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; getController().reBound(); Rectangle bounds = getBounds(); BackRenderer renderer = getAppearance().isSupportsTransparency() ? getAppearance().getRenderer() : null; if (renderer != null) renderer.render(g2d, bounds); rows = getModel().getRowsCount() + 1; cols = getModel().getColsCount(); cellWidth = (int)bounds.getWidth() / cols; cellHeight = (int)bounds.getHeight() / rows; widthShift = (int)bounds.getWidth() % cols; heightShift = (int)bounds.getHeight() % rows; // g2d.translate(widthShift, heightShift); curWidth = 0; widthCounter = widthShift; heightCounter = heightShift; curHeight = cellHeight + ((heightCounter--) > 0 ? 1 : 0); for (int c = 0; c < cols; c++) { curWidth = cellWidth + ((widthCounter--) > 0 ? 1 : 0); paintCaption(g2d, c, curWidth, curHeight); g2d.translate(curWidth, 0); } g2d.translate(-cellWidth * cols - widthShift, curHeight); widthCounter = widthShift; for (int i = 1; i < rows; i++) { curHeight = cellHeight + ((heightCounter--) > 0 ? 1 : 0); for (int j = 0; j < cols; j++) { curWidth = cellWidth + ((widthCounter--) > 0 ? 1 : 0); paintCell(g2d, i - 1 , j, curWidth, curHeight); if (j == (cols - 1)) { g2d.translate(-cellWidth * (cols - 1) - widthShift, curHeight); widthCounter = widthShift; } else { g2d.translate(curWidth, 0); } } } } private void paintCell(Graphics2D g2d, int row, int column, int width, int height) { boolean isText = true; switch (getModel().getCellState(row, column)) { case NORMAL : currentAppearance = getAppearance().getUsual(); break; case NOW : currentAppearance = getAppearance().getNow(); break; case SELECTED : currentAppearance = getAppearance().getSelected(); break; case UNACCESSIBLE: currentAppearance = getAppearance().getDisabled(); break; case NORMAL_SCROLL: isText = getModel().isShowNeighbourMonth(); currentAppearance = getAppearance().getScroll(); break; } if (currentAppearance == null) { return; } currentAppearance.render(g2d, this, isText ? getModel().getCellCaption(row, column) : "", width, height, isFocused() && getModel().isCursor(row, column)); } private void paintCaption(Graphics2D g2d, int c, int width, int height) { getAppearance().getCaption().render(g2d, this, weekDays[c], width, height); } public DateChooseController getController() { return controller; } public void setController(DateChooseController controller) { this.controller = controller; controller.setView(this); } public DateChoose getModel() { return model; } public void setModel(DateChoose model) { if (getModel() != null) { getModel().removePropertyChangeListener(this); } this.model = model; getModel().addPropertyChangeListener(this); } public boolean isFocused() { return focused; } public void setFocused(boolean focused) { this.focused = focused; repaint(); } public boolean isAutoFontSize() { return autoFontSize; } public void setAutoFontSize(boolean autoFontSize) { this.autoFontSize = autoFontSize; } public ViewAppearance getAppearance() { return appearance.getCurrent(); } public void setEnabled(boolean enabled) { super.setEnabled(enabled); setFocusable(enabled); } public AppearancesList getAppearanceList() { return appearance; } public void setAppearanceList(AppearancesList appearance) { this.appearance = appearance; } public WeekDaysStyle getWeekStyle() { return weekStyle; } public void setWeekStyle(WeekDaysStyle weekStyle) { if (weekStyle == this.weekStyle) return; this.weekStyle = weekStyle; initWeekDays(); } public void propertyChange(PropertyChangeEvent evt) { repaint(); } // private void writeObject(ObjectOutputStream out) throws IOException { // out.defaultWriteObject(); // } // // private void readObject(ObjectInputStream in) // throws IOException, ClassNotFoundException { // in.defaultReadObject(); // } }