一个输出如下图日历程序: 
    日 一 二 三 四 五 六
    ** 1  2  3  4  5  6
    7  8  9  10 11 12 13   
    14 15 16 17 18 19 20
    21 22 23 24 25 26 27
    28 29 30 31有办法写的程序时使得它换行后能对齐上面的标题“日一二三四五六”的吗。因为我写的下面数字部分无法和上面对齐,所以想求助下,书上的练习希望大牛求助解决谢谢~

解决方案 »

  1.   

    package test;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;import javax.swing.JFrame;
    import javax.swing.JPanel;public class Main extends JPanel {
      SimpleDateFormat month = new SimpleDateFormat("MMMM");
      SimpleDateFormat year = new SimpleDateFormat("yyyy");
      SimpleDateFormat day = new SimpleDateFormat("d");
      Date date = new Date();  public void setDate(Date date) {
        this.date = date;
      }
      public void paintComponent(Graphics g) {
        ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.black);
        g.drawString(month.format(date), 34, 36);
        g.setColor(Color.white);
        g.drawString(year.format(date), 235, 36);    Calendar today = Calendar.getInstance();
        today.setTime(date);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DATE, 1);
        cal.add(Calendar.DATE, -cal.get(Calendar.DAY_OF_WEEK) + 1);
        for (int week = 0; week < 6; week++) {
          for (int d = 0; d < 7; d++) {
            Color col = Color.black;
              g.drawString(day.format(cal.getTime()), d * 30 + 46 + 4,
                  week * 29 + 81 + 20);
            cal.add(Calendar.DATE, +1);
          }
        }
      }  public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setPreferredSize(new Dimension(300, 280));    Main ch = new Main();
        ch.setDate(new Date());
        frame.getContentPane().add(ch);
        frame.setUndecorated(true);    frame.pack();
        frame.setVisible(true);
      }
    }
      

  2.   

    /* 
     * JCommon : a free general purpose class library for the Java(tm) platform
     * 
     *
     * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
     * 
     * Project Info:  http://www.jfree.org/jcommon/index.html
     *
     * 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 Street, Fifth Floor, Boston, MA  02110-1301, 
     * USA.  
     *
     * [Java is a trade or registered trade of Sun Microsystems, Inc. 
     * in the United States and other countries.]
     * 
     * ---------------------
     * DateChooserPanel.java
     * ---------------------
     * (C) Copyright 2000-2004, by Object Refinery Limited.
     *
     * Original Author:  David Gilbert (for Object Refinery Limited);
     * Contributor(s):   -;
     *
     * $Id: DateChooserPanel.java,v 1.11 2007/11/02 17:50:36 taqua Exp $
     *
     * Changes (from 26-Oct-2001)
     * --------------------------
     * 26-Oct-2001 : Changed package to com.jrefinery.ui.* (DG);
     * 08-Dec-2001 : Dropped the getMonths() method (DG);
     * 13-Oct-2002 : Fixed errors reported by Checkstyle (DG);
     * 02-Nov-2005 : Fixed a bug where the current day-of-the-month is past
     *               the end of the newly selected month when the month or year
     *               combo boxes are changed - see bug id 1344319 (DG);
     *
     */
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.GridLayout;
    import java.awt.Insets;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.text.DateFormatSymbols;
    import java.util.Calendar;
    import java.util.Date;
    import javax.swing.BorderFactory;
    import javax.swing.JButton;
    import javax.swing.JComboBox;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.SwingConstants;
    import javax.swing.UIManager;/**
     * A panel that allows the user to select a date.
     *
     * @author David Gilbert
     */
    public class DateChooserPanel extends JPanel implements ActionListener {    /**
         * The date selected in the panel.
         */
        private Calendar chosenDate;    /**
         * The color for the selected date.
         */
        private Color chosenDateButtonColor;    /**
         * The color for dates in the current month.
         */
        private Color chosenMonthButtonColor;    /**
         * The color for dates that are visible, but not in the current month.
         */
        private Color chosenOtherButtonColor;    /**
         * The first day-of-the-week.
         */
        private int firstDayOfWeek;    /**
         * The range used for selecting years.
         */
        private int yearSelectionRange = 20;    /**
         * The font used to display the date.
         */
        private Font dateFont = new Font("SansSerif", Font.PLAIN, 10);    /**
         * A combo for selecting the month.
         */
        private JComboBox monthSelector;    /**
         * A combo for selecting the year.
         */
        private JComboBox yearSelector;    /**
         * A button for selecting today's date.
         */
        private JButton todayButton;    /**
         * An array of buttons used to display the days-of-the-month.
         */
        private JButton[] buttons;    /**
         * A flag that indicates whether or not we are currently refreshing the 
         * buttons.
         */
        private boolean refreshing = false;    /**
         * The ordered set of all seven days of a week,
         * beginning with the 'firstDayOfWeek'.
         */
        private int[] WEEK_DAYS;    /**
         * Constructs a new date chooser panel, using today's date as the initial 
         * selection.
         */
        public DateChooserPanel() {
            this(Calendar.getInstance(), false);
        }    /**
         * Constructs a new date chooser panel.
         *
         * @param calendar     the calendar controlling the date.
         * @param controlPanel a flag that indicates whether or not the 'today' 
         *                     button should appear on the panel.
         */
        public DateChooserPanel(final Calendar calendar, 
                                final boolean controlPanel) {        super(new BorderLayout());        this.chosenDateButtonColor = UIManager.getColor("textHighlight");
            this.chosenMonthButtonColor = UIManager.getColor("control");
            this.chosenOtherButtonColor = UIManager.getColor("controlShadow");        // the default date is today...
            this.chosenDate = calendar;
            this.firstDayOfWeek = calendar.getFirstDayOfWeek();
            this.WEEK_DAYS = new int[7];
            for (int i = 0; i < 7; i++) {
                this.WEEK_DAYS[i] = ((this.firstDayOfWeek + i - 1) % 7) + 1;
            }        add(constructSelectionPanel(), BorderLayout.NORTH);
            add(getCalendarPanel(), BorderLayout.CENTER);
            if (controlPanel) {
                add(constructControlPanel(), BorderLayout.SOUTH);
            }
            setDate(calendar.getTime());
        }    /**
         * Sets the date chosen in the panel.
         *
         * @param theDate the new date.
         */
        public void setDate(final Date theDate) {        this.chosenDate.setTime(theDate);
            this.monthSelector.setSelectedIndex(this.chosenDate.get(
                    Calendar.MONTH));
            refreshYearSelector();
            refreshButtons();    }    /**
         * Returns the date selected in the panel.
         *
         * @return the selected date.
         */
        public Date getDate() {
            return this.chosenDate.getTime();
        }    /**
         * Handles action-events from the date panel.
         *
         * @param e information about the event that occurred.
         */
        public void actionPerformed(final ActionEvent e) {        if (e.getActionCommand().equals("monthSelectionChanged")) {
                final JComboBox c = (JComboBox) e.getSource();
                
                // In most cases, changing the month will not change the selected
                // day.  But if the selected day is 29, 30 or 31 and the newly
                // selected month doesn't have that many days, we revert to the 
                // last day of the newly selected month...
                int dayOfMonth = this.chosenDate.get(Calendar.DAY_OF_MONTH);
                this.chosenDate.set(Calendar.DAY_OF_MONTH, 1);
                this.chosenDate.set(Calendar.MONTH, c.getSelectedIndex());
                int maxDayOfMonth = this.chosenDate.getActualMaximum(
                        Calendar.DAY_OF_MONTH);
                this.chosenDate.set(Calendar.DAY_OF_MONTH, Math.min(dayOfMonth, 
                        maxDayOfMonth));
                refreshButtons();
            }
            else if (e.getActionCommand().equals("yearSelectionChanged")) {
                if (!this.refreshing) {
                    final JComboBox c = (JComboBox) e.getSource();
                    final Integer y = (Integer) c.getSelectedItem();
                    
                    // in most cases, changing the year will not change the 
                    // selected day.  But if the selected day is Feb 29, and the
                    // newly selected year is not a leap year, we revert to 
                    // Feb 28...
                    int dayOfMonth = this.chosenDate.get(Calendar.DAY_OF_MONTH);
                    this.chosenDate.set(Calendar.DAY_OF_MONTH, 1);
                    this.chosenDate.set(Calendar.YEAR, y.intValue());
                    int maxDayOfMonth = this.chosenDate.getActualMaximum(
                        Calendar.DAY_OF_MONTH);
                    this.chosenDate.set(Calendar.DAY_OF_MONTH, Math.min(dayOfMonth, 
                        maxDayOfMonth));
                    refreshYearSelector();
                    refreshButtons();
                }
            }
            else if (e.getActionCommand().equals("todayButtonClicked")) {
                setDate(new Date());
            }
            else if (e.getActionCommand().equals("dateButtonClicked")) {
                final JButton b = (JButton) e.getSource();
                final int i = Integer.parseInt(b.getName());
                final Calendar cal = getFirstVisibleDate();
                cal.add(Calendar.DATE, i);
                setDate(cal.getTime());
            }
        }    /**
         * Returns a panel of buttons, each button representing a day in the month.
         * This is a sub-component of the DatePanel.
         *
         * @return the panel.
         */
        private JPanel getCalendarPanel() {        final JPanel p = new JPanel(new GridLayout(7, 7));
            final DateFormatSymbols dateFormatSymbols = new DateFormatSymbols();
            final String[] weekDays = dateFormatSymbols.getShortWeekdays();        for (int i = 0; i < this.WEEK_DAYS.length; i++) {
                p.add(new JLabel(weekDays[this.WEEK_DAYS[i]], 
                        SwingConstants.CENTER));
            }        this.buttons = new JButton[42];
            for (int i = 0; i < 42; i++) {
                final JButton b = new JButton("");
                b.setMargin(new Insets(1, 1, 1, 1));
                b.setName(Integer.toString(i));
                b.setFont(this.dateFont);
                b.setFocusPainted(false);
                b.setActionCommand("dateButtonClicked");
                b.addActionListener(this);
                this.buttons[i] = b;
                p.add(b);
            }
            return p;    }
      

  3.   

       /**
         * Returns the button color according to the specified date.
         *
         * @param theDate the date.
         * @return the color.
         */
        private Color getButtonColor(final Calendar theDate) {
            if (equalDates(theDate, this.chosenDate)) {
                return this.chosenDateButtonColor;
            }
            else if (theDate.get(Calendar.MONTH) == this.chosenDate.get(
                    Calendar.MONTH)) {
                return this.chosenMonthButtonColor;
            }
            else {
                return this.chosenOtherButtonColor;
            }
        }    /**
         * Returns true if the two dates are equal (time of day is ignored).
         *
         * @param c1 the first date.
         * @param c2 the second date.
         * @return boolean.
         */
        private boolean equalDates(final Calendar c1, final Calendar c2) {
            if ((c1.get(Calendar.DATE) == c2.get(Calendar.DATE))
                && (c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH))
                && (c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR))) {
                return true;
            }
            else {
                return false;
            }
        }    /**
         * Returns the first date that is visible in the grid.  This should always 
         * be in the month preceding the month of the selected date.
         *
         * @return the date.
         */
        private Calendar getFirstVisibleDate() {
            final Calendar c = Calendar.getInstance();
            c.set(this.chosenDate.get(Calendar.YEAR), this.chosenDate.get(
                    Calendar.MONTH), 1);
            c.add(Calendar.DATE, -1);
            while (c.get(Calendar.DAY_OF_WEEK) != getFirstDayOfWeek()) {
                c.add(Calendar.DATE, -1);
            }
            return c;
        }    /**
         * Returns the first day of the week (controls the labels in the date 
         * panel).
         *
         * @return the first day of the week.
         */
        private int getFirstDayOfWeek() {
            return this.firstDayOfWeek;
        }    /**
         * Update the button labels and colors to reflect date selection.
         */
        private void refreshButtons() {
            final Calendar c = getFirstVisibleDate();
            for (int i = 0; i < 42; i++) {
                final JButton b = this.buttons[i];
                b.setText(Integer.toString(c.get(Calendar.DATE)));
                b.setBackground(getButtonColor(c));
                c.add(Calendar.DATE, 1);
            }
        }    /**
         * Changes the contents of the year selection JComboBox to reflect the 
         * chosen date and the year range.
         */
        private void refreshYearSelector() {
            if (!this.refreshing) {
                this.refreshing = true;
                this.yearSelector.removeAllItems();
                final Integer[] years = getYears(this.chosenDate.get(
                        Calendar.YEAR));
                for (int i = 0; i < years.length; i++) {
                    this.yearSelector.addItem(years[i]);
                }
                this.yearSelector.setSelectedItem(new Integer(this.chosenDate.get(
                        Calendar.YEAR)));
                this.refreshing = false;
            }
        }    /**
         * Returns a vector of years preceding and following the specified year.  
         * The number of years preceding and following is determined by the 
         * yearSelectionRange attribute.
         *
         * @param chosenYear the selected year.
         * @return a vector of years.
         */
        private Integer[] getYears(final int chosenYear) {
            final int size = this.yearSelectionRange * 2 + 1;
            final int start = chosenYear - this.yearSelectionRange;        final Integer[] years = new Integer[size];
            for (int i = 0; i < size; i++) {
                years[i] = new Integer(i + start);
            }
            return years;
        }    /**
         * Constructs a panel containing two JComboBoxes (for the month and year) 
         * and a button (to reset the date to TODAY).
         *
         * @return the panel.
         */
        private JPanel constructSelectionPanel() {
            final JPanel p = new JPanel();        final int minMonth = this.chosenDate.getMinimum(Calendar.MONTH);
            final int maxMonth = this.chosenDate.getMaximum(Calendar.MONTH);
            final String[] months = new String[maxMonth - minMonth + 1];
            for(int i=0;i<months.length;i++){
              months[i] = ""+i;
            } 
                    this.monthSelector = new JComboBox(months);
            this.monthSelector.addActionListener(this);
            this.monthSelector.setActionCommand("monthSelectionChanged");
            p.add(this.monthSelector);        this.yearSelector = new JComboBox(getYears(0));
            this.yearSelector.addActionListener(this);
            this.yearSelector.setActionCommand("yearSelectionChanged");
            p.add(this.yearSelector);        return p;
        }    /**
         * Returns a panel that appears at the bottom of the calendar panel - 
         * contains a button for selecting today's date.
         *
         * @return the panel.
         */
        private JPanel constructControlPanel() {        final JPanel p = new JPanel();
            p.setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 5));
            this.todayButton = new JButton("Today");
            this.todayButton.addActionListener(this);
            this.todayButton.setActionCommand("todayButtonClicked");
            p.add(this.todayButton);
            return p;    }    /**
         * Returns the color for the currently selected date.
         *
         * @return a color.
         */
        public Color getChosenDateButtonColor() {
            return this.chosenDateButtonColor;
        }    /**
         * Redefines the color for the currently selected date.
         *
         * @param chosenDateButtonColor the new color
         */
        public void setChosenDateButtonColor(final Color chosenDateButtonColor) {
            if (chosenDateButtonColor == null) {
                throw new NullPointerException("UIColor must not be null.");
            }
            final Color oldValue = this.chosenDateButtonColor;
            this.chosenDateButtonColor = chosenDateButtonColor;
            refreshButtons();
            firePropertyChange("chosenDateButtonColor", oldValue, 
                    chosenDateButtonColor);
        }    /**
         * Returns the color for the buttons representing the current month.
         *
         * @return the color for the current month.
         */
        public Color getChosenMonthButtonColor() {
            return this.chosenMonthButtonColor;
        }    /**
         * Defines the color for the buttons representing the current month.
         *
         * @param chosenMonthButtonColor the color for the current month.
         */
        public void setChosenMonthButtonColor(final Color chosenMonthButtonColor) {
            if (chosenMonthButtonColor == null) {
                throw new NullPointerException("UIColor must not be null.");
            }
            final Color oldValue = this.chosenMonthButtonColor;
            this.chosenMonthButtonColor = chosenMonthButtonColor;
            refreshButtons();
            firePropertyChange("chosenMonthButtonColor", oldValue, 
                    chosenMonthButtonColor);
        }    /**
         * Returns the color for the buttons representing the other months.
         *
         * @return a color.
         */
        public Color getChosenOtherButtonColor() {
            return this.chosenOtherButtonColor;
        }    /**
         * Redefines the color for the buttons representing the other months.
         *
         * @param chosenOtherButtonColor a color.
         */
        public void setChosenOtherButtonColor(final Color chosenOtherButtonColor) {
            if (chosenOtherButtonColor == null) {
                throw new NullPointerException("UIColor must not be null.");
            }
            final Color oldValue = this.chosenOtherButtonColor;
            this.chosenOtherButtonColor = chosenOtherButtonColor;
            refreshButtons();
            firePropertyChange("chosenOtherButtonColor", oldValue, 
                    chosenOtherButtonColor);
        }    /**
         * Returns the range of years available for selection (defaults to 20).
         * 
         * @return The range.
         */
        public int getYearSelectionRange() {
            return this.yearSelectionRange;
        }    /**
         * Sets the range of years available for selection.
         * 
         * @param yearSelectionRange  the range.
         */
        public void setYearSelectionRange(final int yearSelectionRange) {
            final int oldYearSelectionRange = this.yearSelectionRange;
            this.yearSelectionRange = yearSelectionRange;
            refreshYearSelector();
            firePropertyChange("yearSelectionRange", oldYearSelectionRange, 
                    yearSelectionRange);
        }
    }