问题描述
我正在使用 JPanel 创建一个 JFrame,它有 2 个组合框:月份和年份选择。
然后在它们下面有一个基于 CalendarModel 的 JTable。 CalendarModel 的初始值基于第一个默认选择的月份和年份。
每次在每个组合框中选择不同的值时,如何动态更新表格?
谢谢!
更新:我忘了添加 panel.add(scrollPane,BorderLayout.CENTER);
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
final Boolean[] ispressed = {false};
JFrame frame = new JFrame("Timesheet creator");
frame.setVisible(true);
frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300,305);
frame.setLocation(430,100);
JPanel panel = new JPanel();
panel.setBackground( Color.ORANGE );
panel.setLayout(new BoxLayout(panel,BoxLayout.Y_AXIS)); // added code
frame.add(panel);
panel.add(new JLabel("\t")); // spacing label
JLabel lbl = new JLabel("Select a month & year and click Create");
lbl.setAlignmentX( Component.CENTER_ALIGNMENT);
panel.add(lbl);
panel.add(new JLabel("\t"));
String[] monthsList = { "January","February","march","April","May","June","July","August","September","October","November","December" };
Integer[] yearChoiceList = {2020,2021,2022,2023,2024,2025,2026,2027,2028,2030};
final JComboBox<String> cbMonth = new JComboBox<String>(monthsList);
final JComboBox<Integer> cbYear = new JComboBox<Integer>(yearChoiceList);
cbMonth.setMaximumSize(cbMonth.getPreferredSize());
cbMonth.setAlignmentX(Component.CENTER_ALIGNMENT);
cbMonth.addActionListener( new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Month selected: " + cbMonth.getSelectedItem());
CalendarModel model = new CalendarModel();
model.setMonth(cbYear.getSelectedindex() + 1998,cbMonth.getSelectedindex());
}
} );
panel.add(cbMonth);
cbYear.setMaximumSize(cbYear.getPreferredSize());
cbYear.setAlignmentX(Component.CENTER_ALIGNMENT);
cbYear.addActionListener( new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Year selected: " + cbYear.getSelectedItem());
CalendarModel model = new CalendarModel();
model.setMonth(cbYear.getSelectedindex() + 1998,cbMonth.getSelectedindex());
}
} );
panel.add(cbYear);
JButton btnCreate = new JButton("Create");
btnCreate.setAlignmentX(Component.CENTER_ALIGNMENT); // added code
btnCreate.addActionListener( new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Button pressed");
ispressed[0] = true;
}
} );
panel.setBorder( new EmptyBorder( 0,20,20 ) );
panel.setSize( 150,60 );
//Table creation:
CalendarModel model = new CalendarModel();
JTable table = new JTable(model);
table.setBounds(130,80,50);
model.setMonth(cbYear.getSelectedindex() + 1998,cbMonth.getSelectedindex());
model.fireTableDataChanged();
table.setGridColor(Color.black);
table.setShowGrid(true);
table.setAlignmentX(Component.WIDTH);
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setBorder( new BevelBorder( 1 ) );
scrollPane.setBorder( new EmptyBorder( 4,20 ) );
scrollPane.setBackground( Color.ORANGE );
scrollPane.getViewport().setViewPosition(new Point(50,50));
scrollPane.setColumnHeaderView( table.getTableHeader() );
scrollPane.getColumnHeader().setBackground( Color.ORANGE );
table.getTableHeader().setVisible( false );
panel.add(scrollPane,BorderLayout.CENTER);
panel.add(btnCreate);
frame.setVisible(true);
}
}
CalendarModel 类:
import javax.swing.table.AbstractTableModel;
class CalendarModel extends AbstractTableModel {
String[] days = { "Sun","Mon","Tue","Wed","Thu","Fri","Sat" };
int[] numDays = { 31,28,31,30,31 };
String[][] calendar = new String[7][7];
public CalendarModel() {
for (int i = 0; i < days.length; ++i)
calendar[0][i] = days[i];
for (int i = 1; i < 7; ++i)
for (int j = 0; j < 7; ++j)
calendar[i][j] = " ";
}
public int getRowCount() {
return 7;
}
public int getColumnCount() {
return 7;
}
public Object getValueAt(int row,int column) {
return calendar[row][column];
}
public void setValueAt(Object value,int row,int column) {
calendar[row][column] = (String) value;
}
public void setMonth(int year,int month) {
for (int i = 1; i < 7; ++i)
for (int j = 0; j < 7; ++j)
calendar[i][j] = " ";
java.util.GregorianCalendar cal = new java.util.GregorianCalendar();
cal.set(year,month,1);
int offset = cal.get(java.util.GregorianCalendar.DAY_OF_WEEK) - 1;
offset += 7;
int num = daysInMonth(year,month);
for (int i = 0; i < num; ++i) {
calendar[offset / 7][offset % 7] = Integer.toString(i + 1);
++offset;
}
}
public boolean isLeapYear(int year) {
if (year % 4 == 0)
return true;
return false;
}
public int daysInMonth(int year,int month) {
int days = numDays[month];
if (month == 1 && isLeapYear(year))
++days;
return days;
}
}
解决方法
CalendarModel model = new CalendarModel();
model.setMonth(cbYear.getSelectedIndex() + 1998,cbMonth.getSelectedIndex());
上面的代码什么都不做。您创建了一个新模型并设置了月份,但不对模型进行任何操作。
您有两个选择:
- 用新模型替换表中的模型。
代码:
CalendarModel model = new CalendarModel();
model.setMonth(cbYear.getSelectedIndex() + 1998,cbMonth.getSelectedIndex());
table.setModel( model );
- 更新表中的现有模型以重置月份:
代码:
CalendarModel model = (CalendarModel)table.getModel();
model.setMonth(cbYear.getSelectedIndex() + 1998,cbMonth.getSelectedIndex());
在这两种情况下,这意味着您需要将 JTable 定义为类的实例变量,而不是局部变量。