0

コードのデバッグを手伝ってください。JTableを使用してカレンダーを作成していますが、次または前のボタンを押すたびに、カレンダーが正しく再描画されません。それは「半分にカット」され、次にもう一度押すと消えます。私はこれを処理するためにさまざまな方法を試しましたが、実際には手がかりがありません。

コードは次のとおりです。

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import java.util.*;
import java.lang.*;

public class NewCalendar extends JFrame
{
    private JFrame frame = new JFrame();
    private Object[] colNames = {"Sun","Mon","Tue","Wed","Thurs","Fri","Sat"};
    private Object[][] days = new Object[6][7];

    private JLabel lblMonth, lblYear;
    private JButton btnPrev, btnNext, pinBoard, addEntry;
    private Container pane;
    private JPanel pnlCalendar;
    private JComboBox cmbYear;
    private int realYear, realMonth, realDay, currYear, currMonth;
    GregorianCalendar calx = new GregorianCalendar();
    GregorianCalendar cal;
    JScrollPane scroll;
    JTable table;
    TableModel model;
    int row;
    int column;

    public NewCalendar()
    {
        realDay = calx.get(GregorianCalendar.DAY_OF_MONTH);
        realMonth = calx.get(GregorianCalendar.MONTH);
        realYear = calx.get(GregorianCalendar.YEAR);

        //cal = new GregorianCalendar(2012, 10, 27);
        //cal = new GregorianCalendar(realYear, 9, realDay);
        cal = new GregorianCalendar(realYear, realMonth+1, realDay);

        GregorianCalendar cald = new GregorianCalendar(realYear, realMonth, realDay);

        int nod = cald.getActualMaximum(GregorianCalendar.DAY_OF_MONTH);
        int som = cal.get(GregorianCalendar.DAY_OF_WEEK);


        System.out.println(realYear + " " + realMonth + " " + realDay);
        currYear = realYear;
        currMonth = realMonth;
        for( int i=1; i<=nod; i++ )
        {
            row = new Integer((i+som-2)/7);
            column = (i+som-2)%7;
            days[row][column] = new Integer(i);
        }
        TableModel model = new DefaultTableModel(days, colNames)
        {
            private static final long serialVersionUID = 1L;
            public boolean isCellEditable(int row, int column)
            {
                return days[row][column] != null;
            }
        };

        table = new JTable(model);
        table.setRowHeight(38);
        table.setColumnSelectionAllowed(true);
        table.setRowSelectionAllowed(true);
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        for(int i=0; i<7; i++)
        {
            table.getColumnModel().getColumn(i).setCellEditor(new ClientsTableRenderer(new JCheckBox()));
        }

        table.getTableHeader().setReorderingAllowed(false);

        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        table.setShowHorizontalLines(true);
        table.setShowVerticalLines(true);

        scroll = new JScrollPane(table);
        /*frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout( new BorderLayout() );
        frame.pack();
        frame.add(scroll);
        frame.setLocation(150,150);
        frame.setVisible(true);
        frame.setSize(325,450);
        frame.setResizable(false);*/

        this.setTitle("Calendar");
        this.setSize(325,450);
        pane = this.getContentPane();
        pane.setLayout(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        this.setResizable(false);


        //create controls
        lblMonth = new JLabel("January");
        lblYear = new JLabel("Change year: ");
        cmbYear = new JComboBox();
        btnPrev = new JButton("<<");
        btnNext = new JButton(">>");
        pinBoard = new JButton("Go to Pin Board");
        addEntry = new JButton("Add Entry");
        pnlCalendar = new JPanel(null);

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

        //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(scroll);
        pnlCalendar.add(lblMonth);
        pnlCalendar.add(lblYear);
        pnlCalendar.add(cmbYear);
        pnlCalendar.add(btnPrev);
        pnlCalendar.add(btnNext);
        pnlCalendar.add(pinBoard);
        pnlCalendar.add(addEntry);


        //set bounds
        pnlCalendar.setBounds(0,0,500,500);
        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);
        pinBoard.setBounds(10,340,300,25);
        addEntry.setBounds(10,380, 300, 25);
        scroll.setBounds(10,50,300,250);
        refreshCalendar( currMonth, currYear); //refresh calendar
    }

    public void refreshCalendar( int month, int year )
    {
        String[] months = {"January","February","March","April","May","June","July","August","September","October","November","December"};
        int nod, som; //number of days, start of month
        btnPrev.setEnabled(true);
        btnNext.setEnabled(true);
        days = new Object[6][7];
        if( month == 0 && year <= realYear-100)
            btnPrev.setEnabled(false);
        if( month == 11 && year >= realYear+100 )
            btnNext.setEnabled(false);
        lblMonth.setText(months[month]); //refresh month label
        lblMonth.setBounds(160-lblMonth.getPreferredSize().width/2, 25,180,25); //re-align label with calendar
        cmbYear.setSelectedItem(String.valueOf(year));
        cal = new GregorianCalendar(year, month, 1);
        System.out.println("refreshed: " + year + " " + month + " 1");
        nod = cal.getActualMaximum(GregorianCalendar.DAY_OF_MONTH);
        som = cal.get(GregorianCalendar.DAY_OF_WEEK);
        for( int i=1; i<=nod; i++ )
        {
            row = new Integer((i+som-2)/7);
            column = (i+som-2)%7;
            days[row][column] = new Integer(i);
        }

        for(int i = 0; i < 6; i++)
        {
            for(int j = 0; j < 7; j++)
            {
                if(days[i][j] == null) System.out.print(" ");
                else System.out.print(days[i][j]+"");
                System.out.print("\t");
            }
            System.out.println();
        }

        TableModel model1 = new DefaultTableModel(days, colNames)
        {
            private static final long serialVersionUID = 1L;
            public boolean isCellEditable(int row, int column)
            {
                return days[row][column] != null;
            }
        };


        JTable table1 = new JTable(model1);
        table1.setRowHeight(38);
        table1.setColumnSelectionAllowed(true);
        table1.setRowSelectionAllowed(true);
        table1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        for(int i=0; i<7; i++)
        {
            table1.getColumnModel().getColumn(i).setCellEditor(new ClientsTableRenderer(new JCheckBox()));
        }

        table1.getTableHeader().setReorderingAllowed(false);

        table1.setPreferredScrollableViewportSize(table.getPreferredSize());
        table1.setShowHorizontalLines(true);
        table1.setShowVerticalLines(true);

        JScrollPane scroll1 = new JScrollPane(table1);
        // scroll = scroll1;
        pnlCalendar.removeAll();
        pnlCalendar.add(scroll1);
        pnlCalendar.add(lblMonth);
        pnlCalendar.add(lblYear);
        pnlCalendar.add(cmbYear);
        pnlCalendar.add(btnPrev);
        pnlCalendar.add(btnNext);
        pnlCalendar.add(pinBoard);
        pnlCalendar.add(addEntry);
        pnlCalendar.revalidate();
        // pnlCalendar.repaint();
        // pane.repaint();
    }

    public static void main( String[] args ) throws Exception
    {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        /*EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                new NewCalendar();
            }
        });*/

        new NewCalendar();
    }

class ClientsTableRenderer extends DefaultCellEditor
{
    private JButton button;
    private String label;
    private boolean clicked;
    private int row, col;
    private JTable table;

    public ClientsTableRenderer(JCheckBox checkBox)
    {
        super(checkBox);
        button = new JButton();
        button.setOpaque(true);
        button.addActionListener(new ActionListener()
        {
            public void actionPerformed( ActionEvent e )
            {
                fireEditingStopped();
            }
        });
    }

    public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected, int row, int column)
    {
        this.table = table;
        this.row = row;
        this.col = column;
        button.setForeground(Color.black);
        button.setBackground(UIManager.getColor("Button background"));
        label = (value == null) ? "" : value.toString();
        button.setText(label);
        clicked = true;
        return button;
    }

    public Object getCellEditorValue()
    {
        if(clicked)
        {
            //this is what happens when a cell is clicked
            JOptionPane.showMessageDialog( button, "Column with Value: "+table.getValueAt(row,col)+" - Clicked!\n Row: "+row+" Column: "+col);
        }
        clicked = false;
        return new String(label);
    }

    public boolean stopCellEditing()
    {
        clicked = false;
        return super.stopCellEditing();
    }

    protected void fireEditingStopped()
    {
        super.fireEditingStopped();
    }
}

class btnPrev_Action implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        if( currMonth == 0 )
        {
            currMonth = 11;
            currYear -= 1;
        }
        else
        {
            currMonth -= 1;
        }

        refreshCalendar(currMonth, currYear);
    }
}

class btnNext_Action implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        if( currMonth == 11 )
        {
            currMonth = 0;
            currYear += 1;
        }
        else
        {
            currMonth += 1;
        }

        refreshCalendar(currMonth, currYear);
    }
}

class cmbYear_Action implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        if( cmbYear.getSelectedItem() != null )
        {
            String b = cmbYear.getSelectedItem().toString();
            currYear = Integer.parseInt(b);
            //ssrefreshCalendar(currMonth, currYear);
        }
        else
        {
            currMonth -= 1;
        }

        refreshCalendar(currMonth, currYear);
    }
}

}
4

3 に答える 3

3

いくつかの観察:

  • Swing GUIオブジェクトは、イベントディスパッチスレッドでのみ構築および操作する必要があります。

    public static void main(String[] args) throws Exception {
        EventQueue.invokeLater(new Runnable() {
    
            @Override
            public void run() {
                new NewCalendar();
            }
        });
    }
    
  • 使用しないでくださいsetBounds(); レイアウトマネージャーを使用します; 私のプラットフォームでは、コンポーネントが切り捨てられているように見えます。

  • ;のテーブルを置き換えないでください。refreshCalendar()単に更新しTableModelます; JTableモデルが関連するイベントを発生させると、リスニングビューが自動的に更新されます。
于 2012-09-27T16:50:23.313 に答える
1

コンポーネントを追加/削除する場合、コンポーネントを並べ替える必要があるため、再描画では不十分です。validate()これは、 を呼び出す前に を呼び出すことで実行できますrepaint()

于 2012-09-27T16:17:01.710 に答える
-1

こんにちは。このコードマンを試してみてください。何人の人がこれを使ったのかしら :D

        package dafs;

        /*Contents of CalendarProgran.class */


        //Import packages
        import javax.swing.*;
        import javax.swing.event.*;
        import javax.swing.table.*;
        import java.awt.*;
        import java.awt.event.*;
        import java.util.*;

        public class CalendarProgram{
            static JLabel lblMonth, lblYear;
            static JButton btnPrev, btnNext;
            static JTable tblCalendar;
            static JComboBox 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 ("Gestionnaire de clients"); //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();
                btnPrev = new JButton ("<<");
                btnNext = new JButton (">>");
                mtblCalendar = new DefaultTableModel(){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{
                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);
                    }
                }
            }
        }
于 2014-06-08T20:00:03.383 に答える