1

我对 Java 还是很陌生,并且作为一个整体编码,所以请原谅我的新手问题。

我正在尝试制作一个日历,除了正常的 6 x 7 布局等。我希望它在月视图中水平显示。

这就是我到目前为止所拥有的。我尝试更改列和行以及框架宽度,但我无法让窗格以水平方式正确显示。

任何帮助表示赞赏。

package Calendar_Test;

/*Contents of CalendarProgran.class */
//Import packages
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;

public class Test_Code {

    static JLabel lblMonth, lblYear;
    static JButton btnPrev, btnNext;
    static JTable tblCalendar;
    static JComboBox<String> cmbYear;
    static JFrame frmMain;
    static Container pane;
    static DefaultTableModel mtblCalendar; //Table model  
    static JScrollPane stblCalendar; //The scrollpane  
    static JPanel pnlCalendar;
    static int realYear, realMonth, realDay, currentYear, currentMonth;

    public static void main(String args[]) {
        //Look and feel  
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException e) {
        } catch (InstantiationException e) {
        } catch (IllegalAccessException e) {
        } catch (UnsupportedLookAndFeelException e) {
        }

        //Prepare frame  
        frmMain = new JFrame("Key Dates Timeline"); //Create frame  
        frmMain.setSize(330, 375); //Set size to 400x400 pixels  
        pane = frmMain.getContentPane(); //Get content pane  
        pane.setLayout(null); //Apply null layout  
        frmMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Close when X is clicked  

        //Create controls  
        lblMonth = new JLabel("January");
        lblYear = new JLabel("Change year:");
        cmbYear = new JComboBox<String>();
        btnPrev = new JButton("<<");
        btnNext = new JButton(">>");
        mtblCalendar = new DefaultTableModel() {

            /**
            *
            */
            private static final long serialVersionUID = 1L;

            public boolean isCellEditable(int rowIndex, int mColIndex) {
                return false;
            }
        };
        tblCalendar = new JTable(mtblCalendar);
        stblCalendar = new JScrollPane(tblCalendar);
        pnlCalendar = new JPanel(null);

        //Set border  
        pnlCalendar.setBorder(BorderFactory.createTitledBorder("Calendar"));

        //Register action listeners  
        btnPrev.addActionListener(new btnPrev_Action());
        btnNext.addActionListener(new btnNext_Action());
        cmbYear.addActionListener(new cmbYear_Action());

        //Add controls to pane  
        pane.add(pnlCalendar);
        pnlCalendar.add(lblMonth);
        pnlCalendar.add(lblYear);
        pnlCalendar.add(cmbYear);
        pnlCalendar.add(btnPrev);
        pnlCalendar.add(btnNext);
        pnlCalendar.add(stblCalendar);

        //Set bounds  
        pnlCalendar.setBounds(0, 0, 320, 335);
        lblMonth.setBounds(160 - lblMonth.getPreferredSize().width / 2, 25, 100, 25);
        lblYear.setBounds(10, 305, 80, 20);
        cmbYear.setBounds(230, 305, 80, 20);
        btnPrev.setBounds(10, 25, 50, 25);
        btnNext.setBounds(260, 25, 50, 25);
        stblCalendar.setBounds(10, 50, 300, 250);

        //Make frame visible  
        frmMain.setResizable(false);
        frmMain.setVisible(true);

        //Get real month/year  
        GregorianCalendar cal = new GregorianCalendar(); //Create calendar  
        realDay = cal.get(GregorianCalendar.DAY_OF_MONTH); //Get day  
        realMonth = cal.get(GregorianCalendar.MONTH); //Get month  
        realYear = cal.get(GregorianCalendar.YEAR); //Get year  
        currentMonth = realMonth; //Match month and year  
        currentYear = realYear;

        //Add headers  
        String[] headers = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; //All headers  
        for (int i = 0; i < 7; i++) {
            mtblCalendar.addColumn(headers[i]);
        }

        tblCalendar.getParent().setBackground(tblCalendar.getBackground()); //Set background  

        //No resize/reorder  
        tblCalendar.getTableHeader().setResizingAllowed(false);
        tblCalendar.getTableHeader().setReorderingAllowed(false);

        //Single cell selection  
        tblCalendar.setColumnSelectionAllowed(true);
        tblCalendar.setRowSelectionAllowed(true);
        tblCalendar.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        //Set row/column count  
        tblCalendar.setRowHeight(38);
        mtblCalendar.setColumnCount(7);
        mtblCalendar.setRowCount(6);

        //Populate table  
        for (int i = realYear - 100; i <= realYear + 100; i++) {
            cmbYear.addItem(String.valueOf(i));
        }

        //Refresh calendar  
        refreshCalendar(realMonth, realYear); //Refresh calendar  
    }

    public static void refreshCalendar(int month, int year) {
        //Variables  
        String[] months = {
            "January", "February", "March", "April", "May", "June", "July",
            "August", "September", "October", "November", "December"};
        int nod, som; //Number Of Days, Start Of Month  

        //Allow/disallow buttons  
        btnPrev.setEnabled(true);
        btnNext.setEnabled(true);
        if (month == 0 && year <= realYear - 10) {
            btnPrev.setEnabled(false);
        } //Too early  
        if (month == 11 && year >= realYear + 100) {
            btnNext.setEnabled(false);
        } //Too late  
        lblMonth.setText(months[month]); //Refresh the month label (at the top)  
        lblMonth.setBounds(160 - lblMonth.getPreferredSize().width / 2, 25, 180, 25); //Re-align label with calendar  
        cmbYear.setSelectedItem(String.valueOf(year)); //Select the correct year in the combo box  

        //Clear table  
        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 7; j++) {
                mtblCalendar.setValueAt(null, i, j);
            }
        }

        //Get first day of month and number of days  
        GregorianCalendar cal = new GregorianCalendar(year, month, 1);
        nod = cal.getActualMaximum(GregorianCalendar.DAY_OF_MONTH);
        som = cal.get(GregorianCalendar.DAY_OF_WEEK);

        //Draw calendar  
        for (int i = 1; i <= nod; i++) {
            int row = new Integer((i + som - 2) / 7);
            int column = (i + som - 2) % 7;
            mtblCalendar.setValueAt(i, row, column);
        }

        //Apply renderers  
        tblCalendar.setDefaultRenderer(tblCalendar.getColumnClass(0), new tblCalendarRenderer());
    }

    static class tblCalendarRenderer extends DefaultTableCellRenderer {

        /**
        *
        */
        private static final long serialVersionUID = 1L;

        public Component getTableCellRendererComponent(JTable table, Object
            value, boolean selected, boolean focused, int row, int column) {
            super.getTableCellRendererComponent(
                table, value, selected, focused, row, column);
            if (column == 0 || column == 6) { //Week-end  
                setBackground(new Color(255, 220, 220));
            } else { //Week  
                setBackground(new Color(255, 255, 255));
            }
            if (value != null) {
                if (Integer.parseInt(value.toString()) == realDay
                    && currentMonth == realMonth && currentYear == realYear) { //Today  
                    setBackground(new Color(220, 220, 255));
                }
            }
            setBorder(null);
            setForeground(Color.black);
            return this;
        }
    }

    static class btnPrev_Action implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            if (currentMonth == 0) { //Back one year  
                currentMonth = 11;
                currentYear -= 1;
            } else { //Back one month  
                currentMonth -= 1;
            }
            refreshCalendar(currentMonth, currentYear);
        }
    }

    static class btnNext_Action implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            if (currentMonth == 11) { //Foward one year  
                currentMonth = 0;
                currentYear += 1;
            } else { //Foward one month  
                currentMonth += 1;
            }
            refreshCalendar(currentMonth, currentYear);
        }
    }

    static class cmbYear_Action implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            if (cmbYear.getSelectedItem() != null) {
                String b = cmbYear.getSelectedItem().toString();
                currentYear = Integer.parseInt(b);
                refreshCalendar(currentMonth, currentYear);
            }
        }
    }
}
4

2 回答 2

1

如果您使用 4x3 GridLayout(每季度一行),每个单元格包含一个嵌套的 6x7 GridLayout(保存天/月标题的值,我认为它会工作得更好。您甚至可以嵌套这些都在其他一些容器内来保存你的按钮等等。

正如 MadProgrammer 指出的那样,如果您使用 null 布局并更改字体、框架大小等,那么事情将会变得很不稳定,很快。

于 2013-01-23T03:21:29.123 回答
1

您的要求非常基本。鉴于您已经在使用 a JTable,您只需要为TableModel视图提供一个新的......

现在,这非常简单,但这个概念应该让你开始......

public class CalendarTableModel extends AbstractTableModel {

    private Calendar cal;

    public CalendarTableModel() {
        this(new Date());
    }

    public CalendarTableModel(Date date) {
        setMonthByDate(date);
    }

    public void setMonthByDate(Date date) {

        cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, 1);

        fireTableStructureChanged();

    }

    @Override
    public String getColumnName(int column) {

        String name = null;

        if (cal != null) {

            Calendar tmp = Calendar.getInstance();
            tmp.setTime(cal.getTime());
            tmp.set(Calendar.DAY_OF_MONTH, column + 1);

            int date = tmp.get(Calendar.DAY_OF_MONTH);
            int dow = tmp.get(Calendar.DAY_OF_WEEK);

            switch (dow) {

                case Calendar.MONDAY:
                    name = "Mon";
                    break;
                case Calendar.TUESDAY:
                    name = "Tue";
                    break;
                case Calendar.WEDNESDAY:
                    name = "Wed";
                    break;
                case Calendar.THURSDAY:
                    name = "Thr";
                    break;
                case Calendar.FRIDAY:
                    name = "Fri";
                    break;
                case Calendar.SATURDAY:
                    name = "Sat";
                    break;
                case Calendar.SUNDAY:
                    name = "Sun";
                    break;

            }

            name += " " + date;

        }

        return name;

    }

    @Override
    public int getRowCount() {
        return 10;
    }

    @Override
    public int getColumnCount() {

        return cal == null ? 0 : cal.getMaximum(Calendar.DAY_OF_MONTH);

    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {

        return null;

    }

}
于 2013-01-23T04:09:44.327 回答