请帮我调试代码。我正在使用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 :(得分:3)
几点意见:
应在event dispatch thread上构建和操作仅 的Swing GUI对象。
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 :(得分:1)
如果添加/删除组件,重绘是不够的,因为组件需要重新排序。这可以通过在致电validate()
之前致电repaint()
来完成。
答案 2 :(得分:-1)
您好。试试这个Code man。我想知道有多少人使用过这个: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);
}
}
}
}