下面是日历应用程序的可运行代码。这个应用程序不是我写的,它使用了null布局。出于我的目的,我需要更多的灵活性,所以我尝试使用布局管理器。然而,当我尝试时,除了面板边框之外,什么都没有显示出来。此外,原始的绝对定位代码也被注释掉了。
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class CalendarPanel extends JPanel{
private static final long serialVersionUID = 1L;
static JLabel lblMonth, lblYear;
static JButton btnPrev, btnNext;
static JTable tblCalendar;
static JComboBox cmbYear;
static DefaultTableModel mtblCalendar;
static JScrollPane stblCalendar;
static int realYear, realMonth, realDay, currentYear, currentMonth;
private static GridBagLayout gridBag = new GridBagLayout();
private GridBagConstraints constraints = new GridBagConstraints();
public CalendarPanel(){
super(gridBag);
createControls();
setBorder();
registerActionListeners();
addControls();
setBounds();
setDate();
addHeaders();
setBackground();
setTableProperties();
populateTable();
refreshCalendar(realMonth, realYear);
}
private void createControls(){
lblMonth = new JLabel ("January");
lblYear = new JLabel ("Change year:");
cmbYear = new JComboBox();
btnPrev = new JButton ("<");
btnNext = new JButton (">");
mtblCalendar = new DefaultTableModel(){
private static final long serialVersionUID = 1L;
public boolean isCellEditable(int rowIndex, int mColIndex){return false;}};
tblCalendar = new JTable(mtblCalendar);
stblCalendar = new JScrollPane(tblCalendar);
}
private void setBorder(){
this.setBorder(BorderFactory.createTitledBorder("Calendar"));
}
private void registerActionListeners(){
btnPrev.addActionListener(new btnPrev_Action());
btnNext.addActionListener(new btnNext_Action());
cmbYear.addActionListener(new cmbYear_Action());
}
private void addControls(){
GridBagLayout topGridBag = new GridBagLayout();
JPanel topPanel = new JPanel(topGridBag);
topGridBag.setConstraints(btnPrev, constraints);
topGridBag.setConstraints(lblMonth, constraints);
topGridBag.setConstraints(lblMonth, constraints);
/*this.add(lblMonth);
this.add(lblYear);
this.add(cmbYear);
this.add(btnPrev);
this.add(btnNext);
this.add(stblCalendar);
*/
}
private void setBounds(){
/*this.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);*/
}
private void setDate(){
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;
}
private void addHeaders(){
String[] headers = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
for (int i=0; i<7; i++){
mtblCalendar.addColumn(headers[i]);
}
}
private void setBackground(){
tblCalendar.getParent().setBackground(tblCalendar.getBackground());
}
private void setTableProperties(){
//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);
}
private void populateTable(){
for (int i=realYear-100; i<=realYear+100; i++){
cmbYear.addItem(String.valueOf(i));
}
}
private 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());
}
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel calendarPanel = new CalendarPanel();
frame.add(calendarPanel);
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
//frame.setResizable(false);
frame.setVisible(true);
}
static class tblCalendarRenderer extends DefaultTableCellRenderer{
private static final long serialVersionUID = 1L;
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){ //Forward one year
currentMonth = 0;
currentYear += 1;
}
else{ //Forward 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);
}
}
}
}
简单的答案是:您忘记将组件添加到容器中。我假设您认为setConstraint()方法都添加了具有指定约束的组件。实际上,您必须首先添加组件,然后设置它们的约束。