Java Swing JPanel 位于其他面板后面而不是替换它
Java Swing JPanel goes behind other panel instead of replacing it
我正在做一个需要日历的项目;是的,我正在从头开始制作日历 :)。
我已经设置好日历部分,现在我正在处理上个月和下个月的按钮。现在,我正在实施上个月,当我点击按钮时,上个月确实会出现,但它会出现在当前月份之后,而不是像你想象的那样替换它。起初我没有看到任何事情发生,所以我查看了我的代码并再次 运行 它。这一次,让 window 变大;就在那时我看到上个月落后于当前月份。
这是我的完整代码..我做错了什么?
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import javax.swing.*;
public class CalendarTest extends JFrame {
private JPanel calPanel;
CalendarTest() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
InitCal(LocalDate.now().getMonth(), LocalDate.now().getYear());
this.pack();
this.setVisible(true);
this.setLocationRelativeTo(null);
}
private void InitCal(Month month, int year) {
LocalDate date = LocalDate.of(year, ConvertMonthToInt(month), 1);
DayOfWeek dayOfWeek;
int dayOfMonth;
GridBagConstraints c = new GridBagConstraints();
calPanel = new JPanel(new GridBagLayout());
c.gridx = 0;
c.gridy = 0;
c.fill = GridBagConstraints.BOTH;
JButton previous = new JButton("<");
previous.setBorderPainted(false);
previous.setFocusPainted(false);
previous.setBackground(Color.WHITE);
previous.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
LocalDate prevDate = date.minusMonths(1);
InitCal(prevDate.getMonth(), prevDate.getYear());
}
});
calPanel.add(previous, c);
c.gridx++;
c.gridwidth = 3;
calPanel.add(new JButton(month.toString()), c);
c.gridwidth = 2;
c.gridx += 3;
calPanel.add(new JButton(Integer.toString(year)), c);
c.gridwidth = 1;
c.gridx += 2;
calPanel.add(new JButton(">"), c);
c.gridx = 0;
c.gridy++;
JLabel sunday = new JLabel("Sun");
sunday.setHorizontalAlignment(JLabel.CENTER);
calPanel.add(sunday, c);
c.gridx++;
JLabel monday = new JLabel("Mon");
monday.setHorizontalAlignment(JLabel.CENTER);
calPanel.add(monday, c);
c.gridx++;
JLabel tuesday = new JLabel("Tue");
tuesday.setHorizontalAlignment(JLabel.CENTER);
calPanel.add(tuesday, c);
c.gridx++;
JLabel wednesday = new JLabel("Wed");
wednesday.setHorizontalAlignment(JLabel.CENTER);
calPanel.add(wednesday, c);
c.gridx++;
JLabel thursday = new JLabel("Thu");
thursday.setHorizontalAlignment(JLabel.CENTER);
calPanel.add(thursday, c);
c.gridx++;
JLabel friday = new JLabel("Fri");
friday.setHorizontalAlignment(JLabel.CENTER);
calPanel.add(friday, c);
c.gridx++;
JLabel saturday = new JLabel("Sat");
saturday.setHorizontalAlignment(JLabel.CENTER);
calPanel.add(saturday, c);
c.gridx = 0;
c.gridy++;
int fillBeginning = ConvertDayOfWeekToInt(date.getDayOfWeek());
int count = fillBeginning;
if (fillBeginning > 0) {
LocalDate prev = date.minusMonths(1);
int prevDays = GetDaysInMonth(ConvertMonthToInt(prev.getMonth()), prev.getYear());
prevDays -= (fillBeginning - 1);
while (fillBeginning > 0) {
JButton b = new JButton(Integer.toString(prevDays));
b.setBorderPainted(false);
b.setFocusPainted(false);
b.setBackground(new Color(100,150,200));
calPanel.add(b, c);
c.gridx++;
fillBeginning--;
prevDays++;
}
}
int day = 1;
int daysInMonth = GetDaysInMonth(ConvertMonthToInt(month), year);
while(day <= daysInMonth) {
if (count >= 7) {
c.gridy++;
c.gridx = 0;
count = 0;
}
JButton b = new JButton(Integer.toString(day));
b.setBorderPainted(false);
b.setFocusPainted(false);
b.setBackground(Color.WHITE);
calPanel.add(b, c);
count++;
day++;
c.gridx++;
}
int nextDays = 1;
while (7 - count > 0) {
JButton b = new JButton(Integer.toString(nextDays));
b.setBorderPainted(false);
b.setFocusPainted(false);
b.setBackground(new Color(100,150,200));
calPanel.add(b, c);
c.gridx++;
count++;
nextDays++;
}
this.add(calPanel);
}
private int ConvertMonthToInt(Month m) {
switch(m.toString()) {
case "JANUARY" : return 1;
case "FEBRUARY" : return 2;
case "MARCH" : return 3;
case "APRIL" : return 4;
case "MAY" : return 5;
case "JUNE" : return 6;
case "JULY" : return 7;
case "AUGUST" : return 8;
case "SEPTEMBER" : return 9;
case "OCTOBER" : return 10;
case "NOVEMBER" : return 11;
case "DECEMBER" : return 12;
default: return 0;
}
}
private int ConvertDayOfWeekToInt(DayOfWeek dow) {
switch(dow.toString()) {
case "SUNDAY" : return 0;
case "MONDAY" : return 1;
case "TUESDAY" : return 2;
case "WEDNESDAY" : return 3;
case "THURSDAY" : return 4;
case "FRIDAY" : return 5;
case "SATURDAY" : return 6;
default : return 0;
}
}
private int GetDaysInMonth(int m, int y) {
switch(m) {
case 4 : case 6 : case 9 : case 11 : return 30;
case 1 : case 3 : case 5 : case 7 : case 8 : case 10 : case 12 : return 31;
case 2 :
if (IsLeapYear(y)) {
return 29;
} else {
return 28;
}
default : return 0;
}
}
private boolean IsLeapYear(int y) {
if (y % 4 == 0) {
return true;
} else if (y % 100 == 0) {
return false;
}
return false;
}
public static void main(String[] args) {
new CalendarTest();
}
}
看到 2018 年 12 月如何显示在 2019 年 1 月下方?我希望 January 消失并被 December 取代。这张照片是我调整大小后点击上一个按钮后的。
我也试过将 JPanel calPanel = new JPanel(new GridBagLayout());
放在 InitCal()
方法中。那只是和以前一样的问题。有什么建议吗?
您需要从框架中删除上一个面板,如下所示:
private void InitCal(Month month, int year) {
if(calPanel!= null){
this.remove(calPanel);
this.revalidate();
}
...
最后,您需要在添加新的月份面板后重新验证框架,如下所示:
...
this.add(calPanel);
this.revalidate(); // You need to revalidate to component to see the changes.
}
我正在做一个需要日历的项目;是的,我正在从头开始制作日历 :)。
我已经设置好日历部分,现在我正在处理上个月和下个月的按钮。现在,我正在实施上个月,当我点击按钮时,上个月确实会出现,但它会出现在当前月份之后,而不是像你想象的那样替换它。起初我没有看到任何事情发生,所以我查看了我的代码并再次 运行 它。这一次,让 window 变大;就在那时我看到上个月落后于当前月份。
这是我的完整代码..我做错了什么?
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import javax.swing.*;
public class CalendarTest extends JFrame {
private JPanel calPanel;
CalendarTest() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
InitCal(LocalDate.now().getMonth(), LocalDate.now().getYear());
this.pack();
this.setVisible(true);
this.setLocationRelativeTo(null);
}
private void InitCal(Month month, int year) {
LocalDate date = LocalDate.of(year, ConvertMonthToInt(month), 1);
DayOfWeek dayOfWeek;
int dayOfMonth;
GridBagConstraints c = new GridBagConstraints();
calPanel = new JPanel(new GridBagLayout());
c.gridx = 0;
c.gridy = 0;
c.fill = GridBagConstraints.BOTH;
JButton previous = new JButton("<");
previous.setBorderPainted(false);
previous.setFocusPainted(false);
previous.setBackground(Color.WHITE);
previous.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
LocalDate prevDate = date.minusMonths(1);
InitCal(prevDate.getMonth(), prevDate.getYear());
}
});
calPanel.add(previous, c);
c.gridx++;
c.gridwidth = 3;
calPanel.add(new JButton(month.toString()), c);
c.gridwidth = 2;
c.gridx += 3;
calPanel.add(new JButton(Integer.toString(year)), c);
c.gridwidth = 1;
c.gridx += 2;
calPanel.add(new JButton(">"), c);
c.gridx = 0;
c.gridy++;
JLabel sunday = new JLabel("Sun");
sunday.setHorizontalAlignment(JLabel.CENTER);
calPanel.add(sunday, c);
c.gridx++;
JLabel monday = new JLabel("Mon");
monday.setHorizontalAlignment(JLabel.CENTER);
calPanel.add(monday, c);
c.gridx++;
JLabel tuesday = new JLabel("Tue");
tuesday.setHorizontalAlignment(JLabel.CENTER);
calPanel.add(tuesday, c);
c.gridx++;
JLabel wednesday = new JLabel("Wed");
wednesday.setHorizontalAlignment(JLabel.CENTER);
calPanel.add(wednesday, c);
c.gridx++;
JLabel thursday = new JLabel("Thu");
thursday.setHorizontalAlignment(JLabel.CENTER);
calPanel.add(thursday, c);
c.gridx++;
JLabel friday = new JLabel("Fri");
friday.setHorizontalAlignment(JLabel.CENTER);
calPanel.add(friday, c);
c.gridx++;
JLabel saturday = new JLabel("Sat");
saturday.setHorizontalAlignment(JLabel.CENTER);
calPanel.add(saturday, c);
c.gridx = 0;
c.gridy++;
int fillBeginning = ConvertDayOfWeekToInt(date.getDayOfWeek());
int count = fillBeginning;
if (fillBeginning > 0) {
LocalDate prev = date.minusMonths(1);
int prevDays = GetDaysInMonth(ConvertMonthToInt(prev.getMonth()), prev.getYear());
prevDays -= (fillBeginning - 1);
while (fillBeginning > 0) {
JButton b = new JButton(Integer.toString(prevDays));
b.setBorderPainted(false);
b.setFocusPainted(false);
b.setBackground(new Color(100,150,200));
calPanel.add(b, c);
c.gridx++;
fillBeginning--;
prevDays++;
}
}
int day = 1;
int daysInMonth = GetDaysInMonth(ConvertMonthToInt(month), year);
while(day <= daysInMonth) {
if (count >= 7) {
c.gridy++;
c.gridx = 0;
count = 0;
}
JButton b = new JButton(Integer.toString(day));
b.setBorderPainted(false);
b.setFocusPainted(false);
b.setBackground(Color.WHITE);
calPanel.add(b, c);
count++;
day++;
c.gridx++;
}
int nextDays = 1;
while (7 - count > 0) {
JButton b = new JButton(Integer.toString(nextDays));
b.setBorderPainted(false);
b.setFocusPainted(false);
b.setBackground(new Color(100,150,200));
calPanel.add(b, c);
c.gridx++;
count++;
nextDays++;
}
this.add(calPanel);
}
private int ConvertMonthToInt(Month m) {
switch(m.toString()) {
case "JANUARY" : return 1;
case "FEBRUARY" : return 2;
case "MARCH" : return 3;
case "APRIL" : return 4;
case "MAY" : return 5;
case "JUNE" : return 6;
case "JULY" : return 7;
case "AUGUST" : return 8;
case "SEPTEMBER" : return 9;
case "OCTOBER" : return 10;
case "NOVEMBER" : return 11;
case "DECEMBER" : return 12;
default: return 0;
}
}
private int ConvertDayOfWeekToInt(DayOfWeek dow) {
switch(dow.toString()) {
case "SUNDAY" : return 0;
case "MONDAY" : return 1;
case "TUESDAY" : return 2;
case "WEDNESDAY" : return 3;
case "THURSDAY" : return 4;
case "FRIDAY" : return 5;
case "SATURDAY" : return 6;
default : return 0;
}
}
private int GetDaysInMonth(int m, int y) {
switch(m) {
case 4 : case 6 : case 9 : case 11 : return 30;
case 1 : case 3 : case 5 : case 7 : case 8 : case 10 : case 12 : return 31;
case 2 :
if (IsLeapYear(y)) {
return 29;
} else {
return 28;
}
default : return 0;
}
}
private boolean IsLeapYear(int y) {
if (y % 4 == 0) {
return true;
} else if (y % 100 == 0) {
return false;
}
return false;
}
public static void main(String[] args) {
new CalendarTest();
}
}
看到 2018 年 12 月如何显示在 2019 年 1 月下方?我希望 January 消失并被 December 取代。这张照片是我调整大小后点击上一个按钮后的。
我也试过将 JPanel calPanel = new JPanel(new GridBagLayout());
放在 InitCal()
方法中。那只是和以前一样的问题。有什么建议吗?
您需要从框架中删除上一个面板,如下所示:
private void InitCal(Month month, int year) {
if(calPanel!= null){
this.remove(calPanel);
this.revalidate();
}
...
最后,您需要在添加新的月份面板后重新验证框架,如下所示:
...
this.add(calPanel);
this.revalidate(); // You need to revalidate to component to see the changes.
}