如何从内部重新绘制面板
How to repaint a Panel from inside
所以我有一个使用边框布局的日历 GUI。有一个 header(北),带有月份和年份的组合框。当我 select 月份组合框中的一个项目说,六月,然后它会更新日历并重新绘制中心(中心有 42 个 JButtons)。中心是一个充满按钮的 JPanel。这些按钮很难显示当天的事件(尽可能多地列出信息)。
我的问题是重新绘制面板和拉伸框架。当我拉伸框架时,由于某种原因,中心面板会自行重复。当我调用 revalidate 时,它会继续重复。
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
public class cPan extends JPanel implements ChangeListener
{
String date;
public HashMap<String, ArrayList<Event>> haM;
DataModel data;
JButton dayB;
MyCalendar cal;
public cPan(MyCalendar c, HashMap<String, ArrayList<Event>> hm, DataModel d)
{
haM = hm;
data = d;
cal = c;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
System.out.println(month);
int day = cal.get(Calendar.DAY_OF_MONTH);
int daysInMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
Calendar calForDay = Calendar.getInstance();
calForDay.set(Calendar.DATE, day);
calForDay.set(Calendar.MONTH, month);
calForDay.set(Calendar.YEAR, year);
calForDay.set(Calendar.DAY_OF_MONTH, 1);
Date firstDayOfMonth = calForDay.getTime();
int counter = 0;
SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
String fDOM = sdf.format(firstDayOfMonth);
//print empty buttons
if(fDOM.equalsIgnoreCase("SUNDAY")) {counter = 1;}
if(fDOM.equalsIgnoreCase("MONDAY")) {counter = 2;}
if(fDOM.equalsIgnoreCase("TUESDAY")) {counter = 3;}
if(fDOM.equalsIgnoreCase("WEDNESDAY")) {counter = 4;}
if(fDOM.equalsIgnoreCase("THURSDAY")) {counter = 5;}
if(fDOM.equalsIgnoreCase("FRIDAY")) {counter = 6;}
if(fDOM.equalsIgnoreCase("SATURDAY")) {counter = 7;}
setLayout(new GridLayout(7,7));
DAYS[] arrOfDays = DAYS.values();
for(DAYS s : arrOfDays)
{
dayB = new JButton(s.name());
dayB.setBackground(new Color(255, 204, 153 , 255));
add(dayB);
}
for (int j = 1; j < counter; j++)
{
dayB.setBackground(new Color(255, 229, 204, 255));
dayB = new JButton("");
add(dayB);
}
//print day buttons
for(int i = 1; i <= daysInMonth; i++)
{
String dayNum = String.valueOf(i);
String monthNum = String.valueOf(month + 1);
String yearNum = String.valueOf(year);
String dayNum2 = dayNum;
if(dayNum.length() == 1)
{
dayNum2 = "0" + dayNum;
}
if(String.valueOf(month).length() == 1)
{
monthNum = "0" + monthNum;
}
date = yearNum + monthNum + dayNum2;
dayB = new JButton(dayNum);
if(i == day)
{
dayB.setBackground(new Color(153, 255, 153, 255));
}
else if(haM.containsKey(date))
{
dayB.setBackground(new Color(255, 255, 153, 255));
}
else
{
dayB.setBackground(new Color(255, 229, 204, 255));
}
dayB.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
DayFrame dayF = new DayFrame(date, haM);
}
});
add(dayB);
counter++;
}
//print empty buttons
for(int i = counter; i <= 42; i++)
{
dayB = new JButton("");
dayB.setBackground(new Color(255, 229, 204, 255));
add(dayB);
}
}
public void stateChanged(ChangeEvent e) {
System.out.println("Something is going on in statechange");
cal.set(Calendar.MONTH, 10); // only did this to test it out
cPan.this.revalidate();
cPan.this.repaint();
}
}
您的 paintComponent
方法正在做许多它不应该做的事情,例如创建和放置组件。它应该只画画。
我建议您将组件放入 class 构造函数内的 GUI 中,然后再次使用 paintComponent 仅用于绘画而不用于其他目的。如果您想要显示日历,请考虑将每一天显示为在使用 GridLayout 的 JPanel 中保存的 JPanel。 DayPanel 可以在其自己的 class 中以重构信息。
此外,您应该重命名您的 class,因为按照惯例 class 名称应该以大写字母开头,所以像 CalendarPanel 这样的东西会更好。
所以我有一个使用边框布局的日历 GUI。有一个 header(北),带有月份和年份的组合框。当我 select 月份组合框中的一个项目说,六月,然后它会更新日历并重新绘制中心(中心有 42 个 JButtons)。中心是一个充满按钮的 JPanel。这些按钮很难显示当天的事件(尽可能多地列出信息)。
我的问题是重新绘制面板和拉伸框架。当我拉伸框架时,由于某种原因,中心面板会自行重复。当我调用 revalidate 时,它会继续重复。
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
public class cPan extends JPanel implements ChangeListener
{
String date;
public HashMap<String, ArrayList<Event>> haM;
DataModel data;
JButton dayB;
MyCalendar cal;
public cPan(MyCalendar c, HashMap<String, ArrayList<Event>> hm, DataModel d)
{
haM = hm;
data = d;
cal = c;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
System.out.println(month);
int day = cal.get(Calendar.DAY_OF_MONTH);
int daysInMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
Calendar calForDay = Calendar.getInstance();
calForDay.set(Calendar.DATE, day);
calForDay.set(Calendar.MONTH, month);
calForDay.set(Calendar.YEAR, year);
calForDay.set(Calendar.DAY_OF_MONTH, 1);
Date firstDayOfMonth = calForDay.getTime();
int counter = 0;
SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
String fDOM = sdf.format(firstDayOfMonth);
//print empty buttons
if(fDOM.equalsIgnoreCase("SUNDAY")) {counter = 1;}
if(fDOM.equalsIgnoreCase("MONDAY")) {counter = 2;}
if(fDOM.equalsIgnoreCase("TUESDAY")) {counter = 3;}
if(fDOM.equalsIgnoreCase("WEDNESDAY")) {counter = 4;}
if(fDOM.equalsIgnoreCase("THURSDAY")) {counter = 5;}
if(fDOM.equalsIgnoreCase("FRIDAY")) {counter = 6;}
if(fDOM.equalsIgnoreCase("SATURDAY")) {counter = 7;}
setLayout(new GridLayout(7,7));
DAYS[] arrOfDays = DAYS.values();
for(DAYS s : arrOfDays)
{
dayB = new JButton(s.name());
dayB.setBackground(new Color(255, 204, 153 , 255));
add(dayB);
}
for (int j = 1; j < counter; j++)
{
dayB.setBackground(new Color(255, 229, 204, 255));
dayB = new JButton("");
add(dayB);
}
//print day buttons
for(int i = 1; i <= daysInMonth; i++)
{
String dayNum = String.valueOf(i);
String monthNum = String.valueOf(month + 1);
String yearNum = String.valueOf(year);
String dayNum2 = dayNum;
if(dayNum.length() == 1)
{
dayNum2 = "0" + dayNum;
}
if(String.valueOf(month).length() == 1)
{
monthNum = "0" + monthNum;
}
date = yearNum + monthNum + dayNum2;
dayB = new JButton(dayNum);
if(i == day)
{
dayB.setBackground(new Color(153, 255, 153, 255));
}
else if(haM.containsKey(date))
{
dayB.setBackground(new Color(255, 255, 153, 255));
}
else
{
dayB.setBackground(new Color(255, 229, 204, 255));
}
dayB.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
DayFrame dayF = new DayFrame(date, haM);
}
});
add(dayB);
counter++;
}
//print empty buttons
for(int i = counter; i <= 42; i++)
{
dayB = new JButton("");
dayB.setBackground(new Color(255, 229, 204, 255));
add(dayB);
}
}
public void stateChanged(ChangeEvent e) {
System.out.println("Something is going on in statechange");
cal.set(Calendar.MONTH, 10); // only did this to test it out
cPan.this.revalidate();
cPan.this.repaint();
}
}
您的 paintComponent
方法正在做许多它不应该做的事情,例如创建和放置组件。它应该只画画。
我建议您将组件放入 class 构造函数内的 GUI 中,然后再次使用 paintComponent 仅用于绘画而不用于其他目的。如果您想要显示日历,请考虑将每一天显示为在使用 GridLayout 的 JPanel 中保存的 JPanel。 DayPanel 可以在其自己的 class 中以重构信息。
此外,您应该重命名您的 class,因为按照惯例 class 名称应该以大写字母开头,所以像 CalendarPanel 这样的东西会更好。