GUI 日历 DefaultTableModel 添加 MouseListeners

GUI Calendar DefaultTableModel Addig MouseListeners

所以我遵循了有关如何创建 GUI 日历的教程,但现在我想更进一步。我希望能够单击日历中的各个日期以提示用户添加事件。但我不知道如何使用 DefaultTableModel 来实现这一点。有人可以帮我吗?

这是我目前的代码:

主要:

enum MONTHS
{
    January, February, March, April, May, June, July, August, September, October, November, December;
}
enum DAYS
{
    Su, Mo, Tu, We, Th, Fr, Sa;
}

public class MyCalendarTester implements java.io.Serializable {

    static JTable tblCalendar;
    //static JComboBox cmbYear;
    static JFrame frmMain;
    static Container panel;
    static DefaultTableModel mtblCalendar; //Table model
    static JScrollPane stblCalendar; //The scrollpane
    static JPanel pnlCalendar;
    static int realYear, realMonth, realDay, currentYear, currentMonth;

    static MONTHS[] arrayOfMonths = MONTHS.values();
    static DAYS[] arrayOfDays = DAYS.values();
    static MyCalendar myCal = new MyCalendar();
    static Event myEvent = new Event(null, null, null);

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        GregorianCalendar cal = new GregorianCalendar(); // capture today

        //initialize calendar values
        currentMonth = cal.get(Calendar.MONTH);
        currentYear = cal.get(Calendar.YEAR);
        realYear = cal.get(Calendar.YEAR);
        realMonth = cal.get(Calendar.MONTH);
        realDay = cal.get(Calendar.DATE);


        //Look and feel that matches users Operating System
        try {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());}
        catch (ClassNotFoundException e) {}
        catch (InstantiationException e) {}
        catch (IllegalAccessException e) {}
        catch (UnsupportedLookAndFeelException e) {}

        //Prepare frame
        frmMain = new JFrame ("My Calendar"); //Create frame
        frmMain.setSize(400, 400); //Set size to 400x400 pixels
        panel = frmMain.getContentPane(); //Get content panel
        panel.setLayout(null); //Apply null layout
        frmMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Close when X is clicked

        //Create controls
        mtblCalendar = new DefaultTableModel(){public boolean isCellEditable(int rowIndex, int mColIndex){return false;}}; // prevents the dates from being edited
        tblCalendar = new JTable(mtblCalendar);
        stblCalendar = new JScrollPane(tblCalendar);
        pnlCalendar = new JPanel(null);

        //Set border
        pnlCalendar.setBorder(BorderFactory.createTitledBorder(Integer.toString(cal.get(Calendar.YEAR))));

        //Add controls to pane
                panel.add(pnlCalendar);

                pnlCalendar.add(stblCalendar);

                //Set bounds
                pnlCalendar.setBounds(0, 0, 320, 335);
                stblCalendar.setBounds(10, 50, 300, 250);
                frmMain.setResizable(false); // do not allow resizing
                frmMain.setVisible(true);//Make frame visible


        printCalendar(cal);
        MyCalendar.monthView(cal.get(Calendar.MONTH), cal.get(Calendar.YEAR));


        System.out.println("\nI think we're done here!");
    }

    /**
     * displays the calendar for this month and highlights todays date
     * @param cal the instance of todays calendar
     */
    public static void  printCalendar(Calendar cal){

        GregorianCalendar dayCounter = new GregorianCalendar(); // capture today
        dayCounter.set(Calendar.DAY_OF_MONTH, 1);

        for (int i = 0; i < 7; i++){
            mtblCalendar.addColumn(arrayOfDays[i]); // add headers for days of the week
        }

        tblCalendar.getParent().setBackground(tblCalendar.getBackground()); //Set white 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);
}

日历Class代码

public class MyCalendar{

    GregorianCalendar calendar;
    private static HashMap<GregorianCalendar, Event> myCalHash;
    GregorianCalendar dayCounter = new GregorianCalendar(); // capture today
    static MONTHS[] arrayOfMonths = MONTHS.values();
    static DAYS[] arrayOfDays = DAYS.values();
    static JButton btnPrev, btnNext;
    static JLabel lblMonth = new JLabel ("January");;

    MyCalendar(){
        calendar = new GregorianCalendar();
        myCalHash = new HashMap<GregorianCalendar, Event>();
    }

    public HashMap<GregorianCalendar, Event> getMyCalHash(){
        return myCalHash;
    }

    public void setMyCalHash(HashMap<GregorianCalendar, Event> myCalHash) {
        this.myCalHash = myCalHash;
    }

        public static void monthView(int month, int year){
            //print month calendar

            int nod, som; //Number Of Days, Start Of Month

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

            btnPrev = new JButton ("<<");
            btnNext = new JButton (">>");

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

            btnPrev.setBounds(10, 25, 50, 25);
            btnNext.setBounds(260, 25, 50, 25);

            //Allow/disallow buttons
            btnPrev.setEnabled(true);
            btnNext.setEnabled(true);
            System.out.println(arrayOfMonths[month].toString());
            lblMonth.setText(arrayOfMonths[month].toString()); //Refresh the month label (at the top)
            lblMonth.setBounds(160-lblMonth.getPreferredSize().width/2, 25, 180, 25); //Re-align label with calendar
            MyCalendarTester.pnlCalendar.add(lblMonth);
            MyCalendarTester.pnlCalendar.add(btnPrev);
            MyCalendarTester.pnlCalendar.add(btnNext);

            lblMonth.setBounds(160-lblMonth.getPreferredSize().width/2, 25, 100, 25); //places the calendar in the center

            //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;
                MyCalendarTester.mtblCalendar.setValueAt(i, row, column);

            }

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

        }

        static class tblCalendarRenderer extends DefaultTableCellRenderer{
            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()) == MyCalendarTester.realDay && 
                            MyCalendarTester.currentMonth == MyCalendarTester.realMonth && MyCalendarTester.currentYear == MyCalendarTester.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 (MyCalendarTester.currentMonth == 0){ //Back one year
                    MyCalendarTester.currentMonth = 11;
                    MyCalendarTester.currentYear -= 1;
                }
                else{ //Back one month
                    MyCalendarTester.currentMonth -= 1;
                }
                monthView(MyCalendarTester.currentMonth, MyCalendarTester.currentYear);
            }
        }
        static class btnNext_Action implements ActionListener{
            public void actionPerformed (ActionEvent e){
                if (MyCalendarTester.currentMonth == 11){ //Forward one year
                    MyCalendarTester.currentMonth = 0;
                    MyCalendarTester.currentYear += 1;
                }
                else{ //Foward one month
                    MyCalendarTester.currentMonth += 1;
                }
                monthView(MyCalendarTester.currentMonth, MyCalendarTester.currentYear);
            }
        }

MouseListener 添加到 JTable

调用 mouseClicked 时,您可以使用 JTable#getSelectedRowJTable#getSelectedColumn 来确定被单击的单元格。

这些值在视图的上下文中,您应该始终(作为一种好的做法)使用 JTable#convertRowIndexToModel and JTable#convertColumnIndexToModel

将它们转换为模型上下文

然后您可以使用JTable#getValueAt从模型中获取单元格值

查看 How to use tables and How to write MouseListeners 了解更多详情