我有一个问题,现在已经困扰了我很久......
我有一个带有gridlayout(6,7)的JPanel,我的问题是正确更新数据。 我正在制作一个简单的日历软件,当然我还在使用日历。问题是 当我更改Calendar对象MONTH字段并将新月份数据添加到此JPanel gridlayout时 但数据没有正确显示。
我是否计算我的数据字段incorreclty或如何更新MONTH字段。我试过了 组(INT,INT,INT),添加(CalendarObject.MONTH,+ / - 1),辊(CalendarObject.MONTH,真/假)
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cal.set(cal.YEAR,cal.MONTH-1,1);
cal.add(Calendar.DATE, -cal.get(Calendar.DAY_OF_WEEK));
Component[] comps = JavaCalendar.panel.getComponents();
for (Component comp : comps) {
JPanel p = (JPanel) comp;
JLabel c = (JLabel) p.getComponent(0);
c.setText(day.format(cal.getTime()));
cal.add(Calendar.DATE, +1);
}
}
});
是因为for循环大约42次并且它更新每个字段并且每次都调用add()......? 数据更新有点不正确...示例5月1日是Wensday,6月1日是星期六,但是当调用此actionPerfomed()时,它显示6月1日是星期日。
SSCE代码
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Calendar;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.*;
import java.text.SimpleDateFormat;
import java.util.Locale;
public class JavaCalendar extends JFrame {
private Calendar cal;
public static JPanel paneeli;
public static SimpleDateFormat month = new SimpleDateFormat("M");
private SimpleDateFormat year = new SimpleDateFormat("y");
private SimpleDateFormat day = new SimpleDateFormat("d");
private SimpleDateFormat Day = new SimpleDateFormat("E");
public JavaCalendar() {
super("JavaCalendar");
cal = Calendar.getInstance(Locale.getDefault());
cal.setFirstDayOfWeek(Calendar.MONDAY);
setSize(500,400);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new GridLayout(2,1));
paneeli = paneeli(cal);
add(paneeli);
add(buttons(cal));
setLocationRelativeTo(null);
setVisible(true);
}
public JPanel paneeli(Calendar cal) {
cal.set(Calendar.DATE, 1);
cal.add(Calendar.DATE, -cal.get(Calendar.DAY_OF_WEEK)+2);
JPanel paneeli = new JPanel();
paneeli.setLayout(new GridLayout(6,7));
for(int i = 0;i<6;++i) {
for(int j = 0;j<7;++j) {
JPanel label = new JPanel();
label.setBackground(Color.RED);
if (i == 0) {
if (j == 0) {
// Top left corner, draw all sides
label.setBorder(BorderFactory.createLineBorder(Color.BLACK));
} else {
// Top edge, draw all sides except left edge
label.setBorder(BorderFactory.createMatteBorder(1,
0,
1,
1,
Color.BLACK));
}
} else {
if (j == 0) {
// Left-hand edge, draw all sides except top
label.setBorder(BorderFactory.createMatteBorder(0,
1,
1,
1,
Color.BLACK));
} else {
// Neither top edge nor left edge, skip both top and left lines
label.setBorder(BorderFactory.createMatteBorder(0,
0,
1,
1,
Color.BLACK));
}
}
label.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
JPanel panel = (JPanel) e.getSource();
if (Color.RED.equals(panel.getBackground())) {
panel.setBackground(Color.PINK);
panel.revalidate();
panel.repaint();
}else{
panel.setBackground(Color.RED);
panel.revalidate();
panel.repaint();
}
}
});
JLabel labeli = new JLabel();
labeli.setText(day.format(cal.getTime()));
label.add(labeli);
cal.add(Calendar.DATE, +1);
paneeli.add(label);
}
}
return paneeli;
}
public JPanel buttons(Calendar cal) {
final Calendar calender = (Calendar) cal.clone();
JPanel buttonPanel = new JPanel();
JButton button = new JButton();
JButton buttoni = new JButton();
button.setText("Prev");
buttonPanel.add(button);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
calender.set(calender.YEAR,calender.MONTH-1,1);
calender.add(Calendar.DATE, -calender.get(Calendar.DAY_OF_WEEK));
Component[] comps = JavaCalendar.paneeli.getComponents();
for (Component comp : comps) {
JPanel p = (JPanel) comp;
JLabel c = (JLabel) p.getComponent(0);
c.setText(day.format(calender.getTime()));
calender.add(Calendar.DATE, +1);
}
}
});
buttoni.setText("Next");
buttonPanel.add(buttoni);
buttoni.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
calender.set(calender.YEAR,calender.MONTH+1,1);
calender.add(Calendar.DATE, -calender.get(Calendar.DAY_OF_WEEK));
Component[] comps = JavaCalendar.paneeli.getComponents();
for (Component comp : comps) {
JPanel p = (JPanel) comp;
JLabel c = (JLabel) p.getComponent(0);
c.setText(day.format(calender.getTime()));
calender.add(Calendar.DATE, +1);
}
}
});
cal = (Calendar) calender.clone();
return buttonPanel;
}
public static void main(String[] args) {
new JavaCalendar();
}
}
答案 0 :(得分:2)
没有实施
区域设置,
特殊日子/ Hollydays
multi_selection
range_selection
仅关于如何在变化(蛾,年)上刷新网格
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.LayoutManager;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
/**
* Custom dialog box to enter dates. The <code>CalendarDateChooser</code>
* class presents a calendar and allows the user to visually select a
* day, month and year so that it is impossible to enter an invalid
* date.
**/
public class CalendarDateChooser extends JDialog implements ItemListener, MouseListener, FocusListener, KeyListener, ActionListener {
private static final long serialVersionUID = 1L;
private static final String[] MONTHS = new String[]{"January", "February", "March",
"April", "May", "June", "July", "August", "September", "October", "November", "December"}; // Names of the months.
private static final String[] DAYS = new String[]{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};// Names of the days of the week.
private static final Color WEEK_DAYS_FOREGROUND = Color.black;// Text color of the days of the weeks, used as column headers in the calendar.
private static final Color DAYS_FOREGROUND = Color.blue;// Text color of the days' numbers in the calendar.
private static final Color SELECTED_DAY_FOREGROUND = Color.white;// Background color of the selected day in the calendar.
private static final Color SELECTED_DAY_BACKGROUND = Color.blue;// Text color of the selected day in the calendar.
private static final Border EMPTY_BORDER = BorderFactory.createEmptyBorder(1, 1, 1, 1);// Empty border, used when the calendar does not have the focus.
private static final Border FOCUSED_BORDER = BorderFactory.createLineBorder(Color.yellow, 1);// Border used to highlight the selected day when the calendar has the focus.
private static final int FIRST_YEAR = 2010;// First year that can be selected.
private static final int LAST_YEAR = 2100;// Last year that can be selected.
private GregorianCalendar calendar;// Auxiliary variable to compute dates.
/** Calendar, as a matrix of labels. The first row represents the first week of the month, the second row, the second week, and
so on. Each column represents a day of the week, the first is Sunday, and the last is Saturday. The label's text is the number
of the corresponding day. */
private JLabel[][] days;
/** Day selection control. It is just a panel that can receive the focus. The actual user interaction is driven by the
<code>CalendarDateChooser</code> class. */
private FocusablePanel daysGrid;
private JComboBox month;// Month selection control. */
private JComboBox year;// Year selection control. */
private JButton ok; // "Ok" button. */
private JButton cancel;// "Cancel" button. */
/** Day of the week (0=Sunday) corresponding to the first day of
the selected month. Used to calculate the position, in the
calendar ({@link #days}), corresponding to a given day. */
private int offset;
private int lastDay; // Last day of the selected month.
private JLabel day;// Selected day.
/** <code>true</code> if the "Ok" button was clicked to close the dialog box, <code>false</code> otherwise. */
private boolean okClicked;
/**
* Constructs a new <code>CalendarDateChooser</code> with the given title.
* @param owner owner dialog
* @param title dialog title
**/
public CalendarDateChooser(JDialog owner, String title) {
super(owner, title, true);
construct();
}
/**
* Constructs a new <code>CalendarDateChooser</code>.
* @param owner owner dialog
**/
public CalendarDateChooser(JDialog owner) {
super(owner, true);
construct();
}
/**
* Constructs a new <code>CalendarDateChooser</code> with the given title.
* @param owner owner frame
* @param title dialog title
**/
public CalendarDateChooser(JFrame owner, String title) {
super(owner, title, true);
construct();
}
/**
* Constructs a new <code>CalendarDateChooser</code>.
* @param owner owner frame
**/
public CalendarDateChooser(JFrame owner) {
super(owner, true);
construct();
}
/**
* Custom panel that can receive the focus. Used to implement the calendar control.
**/
private static class FocusablePanel extends JPanel {
private static final long serialVersionUID = 1L;
/**
* Constructs a new <code>FocusablePanel</code> with the given
* layout manager.
*
* @param layout layout manager
**/
FocusablePanel(LayoutManager layout) {
super(layout);
}
/**
* Always returns <code>true</code>, since <code>FocusablePanel</code> can receive the focus. @return <code>true</code>
**/
@Override
public boolean isFocusable() {
return true;
}
}
/**
* Initializes this <code>CalendarDateChooser</code> object. Creates the controls, registers listeners and initializes the dialog box.
**/
private void construct() {
Border line, raisedbevel, loweredbevel, title, empty;
line = BorderFactory.createLineBorder(Color.black);
raisedbevel = BorderFactory.createRaisedBevelBorder();
loweredbevel = BorderFactory.createLoweredBevelBorder();
title = BorderFactory.createTitledBorder("");
empty = BorderFactory.createEmptyBorder(4, 4, 4, 4);
Border compound;
Border compound1;
compound = BorderFactory.createCompoundBorder(empty, new RoundedBorderLine());
Color crl = (Color.blue);
compound1 = BorderFactory.createCompoundBorder(empty, new RoundedBorderLineBlue(crl));
calendar = new GregorianCalendar();
month = new JComboBox(MONTHS);//adds the monthes into the combobox
month.addItemListener(this);
year = new JComboBox();//adds the years into the combobox
for (int i = FIRST_YEAR; i <= LAST_YEAR; i++) {
year.addItem(Integer.toString(i));
}
year.addItemListener(this);
days = new JLabel[7][7];
for (int i = 0; i < 7; i++) {//set up the days in week display using DAYS constant
days[0][i] = new JLabel(DAYS[i], JLabel.RIGHT);
days[0][i].setForeground(WEEK_DAYS_FOREGROUND);
}
for (int i = 1; i < 7; i++) {//set up the days
for (int j = 0; j < 7; j++) {
days[i][j] = new JLabel(" ", JLabel.RIGHT);
days[i][j].setForeground(DAYS_FOREGROUND);
days[i][j].setBackground(SELECTED_DAY_BACKGROUND);
days[i][j].setBorder(EMPTY_BORDER);
days[i][j].addMouseListener(this);
}
}
ok = new JButton("Ok");
ok.addActionListener(this);
ok.setFocusPainted(false);
cancel = new JButton("Cancel");
cancel.addActionListener(this);
cancel.setFocusPainted(false);
JPanel monthYear = new JPanel();
monthYear.add(month);
monthYear.add(year);
daysGrid = new FocusablePanel(new GridLayout(7, 7, 5, 0));
daysGrid.addFocusListener(this);
daysGrid.addKeyListener(this);
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 7; j++) {
daysGrid.add(days[i][j]);
}
}
daysGrid.setBackground(Color.white);
daysGrid.setBorder(BorderFactory.createLoweredBevelBorder());
JPanel daysPanel = new JPanel();
daysPanel.add(daysGrid);
JPanel buttons = new JPanel();
buttons.add(ok);
//buttons.add(cancel);
JPanel topPanel = new JPanel();
topPanel.setLayout(new BorderLayout());
/*Container dialog = getContentPane();
dialog.add("North", monthYear);
dialog.add("Center", daysPanel);
dialog.add("South", buttons);*/
topPanel.add(monthYear, BorderLayout.NORTH);
topPanel.add(daysPanel, BorderLayout.CENTER);
topPanel.add(buttons, BorderLayout.SOUTH);
topPanel.setBorder(compound1);
add("Center", topPanel);
setAlwaysOnTop(true);
setUndecorated(true);
pack();
setResizable(false);
}
/**
* Gets the selected day, as an <code>int</code>. Parses the text of the selected label in the calendar to get the day.
* @return the selected day or -1 if there is no day selected
**/
private int getSelectedDay() {
if (day == null) {
return -1;
}
try {
return Integer.parseInt(day.getText());
} catch (NumberFormatException e) {
}
return -1;
}
/**
* Sets the selected day. The day is specified as the label control, in the calendar, corresponding to the day to select.
* @param newDay day to select
**/
private void setSelected(JLabel newDay) {
if (day != null) {
day.setForeground(DAYS_FOREGROUND);
day.setOpaque(false);
day.setBorder(EMPTY_BORDER);
}
day = newDay;
day.setForeground(SELECTED_DAY_FOREGROUND);
day.setOpaque(true);
if (daysGrid.hasFocus()) {
day.setBorder(FOCUSED_BORDER);
}
}
/** Sets the selected day. The day is specified as the number of the day, in the month, to selected. The function compute the
* corresponding control to select. @param newDay day to select **/
private void setSelected(int newDay) {
setSelected(days[(newDay + offset - 1) / 7 + 1][(newDay + offset - 1) % 7]);
}
/**
* Updates the calendar. This function updates the calendar panel
* to reflect the month and year selected. It keeps the same day
* of the month that was selected, except if it is beyond the last
* day of the month. In this case, the last day of the month is
* selected.
**/
private void update() {
int iday = getSelectedDay();
for (int i = 0; i < 7; i++) {
days[1][i].setText(" ");
days[5][i].setText(" ");
days[6][i].setText(" ");
}
calendar.set(Calendar.DATE, 1);
calendar.set(Calendar.MONTH, month.getSelectedIndex() + Calendar.JANUARY);
calendar.set(Calendar.YEAR, year.getSelectedIndex() + FIRST_YEAR);
offset = calendar.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY;
lastDay = calendar.getActualMaximum(Calendar.DATE);
for (int i = 0; i < lastDay; i++) {
days[(i + offset) / 7 + 1][(i + offset) % 7].setText(String.valueOf(i + 1));
}
if (iday != -1) {
if (iday > lastDay) {
iday = lastDay;
}
setSelected(iday);
}
}
/**
* Called when the "Ok" button is pressed. Just sets a flag and hides the dialog box.
* @param e
*/
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == ok) {
okClicked = true;
}
setVisible(false);
}
/**
* Called when the calendar gains the focus. Just re-sets the
* selected day so that it is redrawn with the border that
* indicate focus.
*
* @param e
*/
@Override
public void focusGained(FocusEvent e) {
setSelected(day);
}
/**
* Called when the calendar loses the focus. Just re-sets the
* selected day so that it is redrawn without the border that
* indicate focus.
*
* @param e
*/
@Override
public void focusLost(FocusEvent e) {
setSelected(day);
}
/**
* Called when a new month or year is selected. Updates the calendar
* to reflect the selection.
*
* @param e
*/
@Override
public void itemStateChanged(ItemEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
update();
}
});
}
/**
* Called when a key is pressed and the calendar has the
* focus. Handles the arrow keys so that the user can select a day
* using the keyboard.
*
* @param e
*/
@Override
public void keyPressed(KeyEvent e) {
int iday = getSelectedDay();
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
if (iday > 1) {
setSelected(iday - 1);
}
break;
case KeyEvent.VK_RIGHT:
if (iday < lastDay) {
setSelected(iday + 1);
}
break;
case KeyEvent.VK_UP:
if (iday > 7) {
setSelected(iday - 7);
}
break;
case KeyEvent.VK_DOWN:
if (iday <= lastDay - 7) {
setSelected(iday + 7);
}
break;
}
}
/**
* Called when the mouse is clicked on a day in the
* calendar. Selects the clicked day.
*
* @param e
*/
@Override
public void mouseClicked(MouseEvent e) {
JLabel day1 = (JLabel) e.getSource();
if (!day1.getText().equals(" ")) {
setSelected(day1);
}
daysGrid.requestFocus();
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
/**
* Selects a date. Displays the dialog box, with a given date as
* the selected date, and allows the user select a new date.
* @param date initial date
* @return the new date selected or <code>null</code> if the user
* press "Cancel" or closes the dialog box
**/
public Date select(Date date) {
calendar.setTime(date);
int _day = calendar.get(Calendar.DATE);
int _month = calendar.get(Calendar.MONTH);
int _year = calendar.get(Calendar.YEAR);
year.setSelectedIndex(_year - FIRST_YEAR);
month.setSelectedIndex(_month - Calendar.JANUARY);
setSelected(_day);
okClicked = false;
setVisible(true);
if (!okClicked) {
return null;
}
calendar.set(Calendar.DATE, getSelectedDay());
calendar.set(Calendar.MONTH, month.getSelectedIndex() + Calendar.JANUARY);
calendar.set(Calendar.YEAR, year.getSelectedIndex() + FIRST_YEAR);
return calendar.getTime();
}
public void setDate(Date date) {
calendar.setTime(date);
int _day = calendar.get(Calendar.DATE);
int _month = calendar.get(Calendar.MONTH);
int _year = calendar.get(Calendar.YEAR);
year.setSelectedIndex(_year - FIRST_YEAR);
month.setSelectedIndex(_month - Calendar.JANUARY);
setSelected(_day);
}
public Date getDate() {
calendar.set(Calendar.DATE, getSelectedDay());
calendar.set(Calendar.MONTH, month.getSelectedIndex() + Calendar.JANUARY);
calendar.set(Calendar.YEAR, year.getSelectedIndex() + FIRST_YEAR);
return calendar.getTime();
}
/**
* Selects new date. Just calls {@link #select(Date)} with the
* system date as the parameter.
*
* @return the same as the function {@link #select(Date)}
**/
public Date select() {
return select(new Date());
}
}