2012-09-27 2 views
0

코드 디버깅을 도와주세요. JTable을 사용하여 캘린더를 만들고 있지만 다음 또는 이전 버튼을 누를 때마다 캘린더가 제대로 다시 그려지지 않습니다. 그것은 "반으로 잘라"다음 다른 언론이 사라집니다. 이 문제를 해결하기 위해 여러 가지 방법을 시도했지만 실제로 실마리가 없습니다. 구성 요소가 다시 정렬 할 필요가 있기 때문에,왜이 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); 
    } 
} 

} 
+0

'숙제'태그는 현재 사용되지 않으므로 오른쪽의 게시판을 참조하십시오. –

+0

[sscce] 제공을위한 +1 (http://sscce.org/); 또한 [tag : jcalendar]를 고려하십시오. – trashgod

답변

3

몇 가지 관찰 :

  • 스윙 GUI 개체는 구성 만event dispatch thread을 조작해야합니다.

    public static void main(String[] args) throws Exception { 
        EventQueue.invokeLater(new Runnable() { 
    
         @Override 
         public void run() { 
          new NewCalendar(); 
         } 
        }); 
    } 
    
  • setBounds(); layout manager; 귀하의 구성 요소는 내 플랫폼에 truncated으로 표시됩니다.

  • refreshCalendar()의 테이블로 바꿉니다. 단순히 TableModel을 업데이트하십시오. 모델이 관련 이벤트를 발생 시키면 수신 대기 JTable보기가 자동으로 새로 고침됩니다.
1

추가하면/다시 그리기가 충분하지 않습니다 구성 요소를 제거 : 여기

는 코드입니다. 이는 repaint()에 전화하기 전에 validate()으로 전화하여 수행 할 수 있습니다.

+1

사실,하지만'JTable'에 대한 최선의 접근법은 아닙니다. 모델을 업데이트하고 듣기 뷰가 반응하도록하는 것이 더 좋습니다. [here] (http://stackoverflow.com/a/12626327/230513). – trashgod

-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); 
        } 
       } 
      } 
     } 
+1

이 질문에 대한 답변은 1 년이 넘었습니다. 귀하의 답변이 효과가있을 것이라고보기는 어렵습니다. –

관련 문제