如何从以前的创建中删除 JLabel?

How do i delete the JLabel from previous creation?

我正在创建一个日历,我使用 forloop 来循环日期并根据每一天添加 JLabel。但是,每当我更改日历的月份时,假设一月有 31 天,例如,如果我将月份更改为二月,二月将有 31 + 28 天,我真的很困惑如何解决这个问题

代码如下: MonthPanel.java

public class MonthPanel extends JPanel {

    private String[] headers = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    private int realDay, realMonth, realYear, currentMonth, currentYear;
    private Toolbar toolbar;
    private String inputTotal = "";


    public MonthPanel() throws IOException {

        setLayout(new GridLayout(6,7));

        for (String header : headers) {
             add(new JLabel(header));
        }

        changeCalendar();
    }

    public void changeCalendar(int month) throws IOException {

    String[] months = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
    int noDays, monthStart;

    Border border = BorderFactory.createLineBorder(Color.BLACK, 1);

    GregorianCalendar cal = new GregorianCalendar(2015, month, 1);
    noDays = cal.getActualMaximum(GregorianCalendar.DAY_OF_MONTH);
    monthStart = cal.get(GregorianCalendar.DAY_OF_WEEK);

    for(int i=1; i<= noDays; i++) {

         JLabel label = new JLabel(String.valueOf(i));
          label.setBackground(Color.WHITE);
          label.setBorder(border);
          label.setOpaque(true);

          add(label); 

    }


    System.out.println(months[month]);
    System.out.println(noDays);

}

Toolbar.java

public class Toolbar extends JPanel {

    public JComboBox<Object> months;
    public JLabel monthName;
    private JLabel pictureName;
    private MonthListener monthListener;

    public Toolbar() throws IOException {

        ImageIcon img = new ImageIcon("/Users/naufal/Desktop/pictureC2.jpg");
        pictureName = new JLabel(img);

        String[] monthsList = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
        months = new JComboBox<Object>(monthsList);
        monthName = new JLabel(monthsList[0]);
        setLayout(new FlowLayout());

        add(months);
        add(monthName);
        add(pictureName);



    }

MainFrame.java - 这是发生变化的地方,如果用户更改日历,它将发生变化

public class MainFrame extends JFrame {

    private Toolbar toolBar;
    private MonthPanel monthPanel;
    String[] monthsList = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

    public MainFrame() throws IOException {
        super("Calendar App");
        setLayout(new BorderLayout());

        toolBar = new Toolbar();
        monthPanel = new MonthPanel();

        JComboBox getMonthBox = toolBar.getMonths();

        ActionListener acListener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                 int monthIndex = getMonthBox.getSelectedIndex();
                 try {

                    monthPanel.changeCalendar(monthIndex);
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                 toolBar.monthName.setText(monthsList[boxCount]);


            }
        };

        toolBar.months.addActionListener(acListener);

        setSize(1200,900);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        add(toolBar, BorderLayout.NORTH);
        add(monthPanel);


    }

}

初始日历

在我将月份更改为二月之后,它附加了当前的 JLabel,即 31(January) JLabel 和另一个 28(February) JLabel

标签的父容器是什么?

您可以尝试重新绘制父容器上的标签。检查以下步骤以获取父对象并重新绘制它。当事件发生时使用它。我会把逻辑留给你。

Container parent = label.getParent();
parent.remove(label);
parent.validate();
parent.repaint();

作为替代方案,您可以实例化一个大小为 31 的 JLabels 数组,并使用 JPanel.remove() 删除从第 #noDays 天到第 #31 天的所有 JLabels , 并在必要时再次添加它们。

您甚至可以节省处理时间,因为您不必一直创建新的 JLabels,因为您正在回收它们。

MonthPanel 看起来像这样:

public class MonthPanel extends JPanel {

    private String[] headers = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    private int realDay, realMonth, realYear, currentMonth, currentYear;
    private Toolbar toolbar;
    private String inputTotal = "";
    private JLabel[] labelArray;


    public MonthPanel() throws IOException {

        setLayout(new GridLayout(6,7));

        for (String header : headers) {
             add(new JLabel(header));
        }

        Border border = BorderFactory.createLineBorder(Color.BLACK, 1);

        /* Instantiate JLabel array */
        labelArray = new JLabel[31];
        for( int i = 0; i < 30; i++ ) {
            JLabel label = new JLabel(""+(i+1));
            label.setBackground(Color.WHITE);
            label.setBorder(border);
            label.setOpaque(true);
            labelArray[i] = label;
        }

        changeCalendar();
    }

    public void changeCalendar(int month) throws IOException {

    String[] months = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
    int noDays, monthStart;

    GregorianCalendar lastMonth = new GregorianCalendar(2015, month-1, 1);
    noDaysLastMonth = lastMonth.getActualMaximum(GregorianCalendar.DAY_OF_MONTH);

    GregorianCalendar cal = new GregorianCalendar(2015, month, 1);
    noDays = cal.getActualMaximum(GregorianCalendar.DAY_OF_MONTH);
    monthStart = cal.get(GregorianCalendar.DAY_OF_WEEK);

    if( noDaysLastMonth < noDays ) { // add days if this month has more days than last month
        for( int i = noDaysLastMonth; i < noDays; i++ ) {
            add( labelArray[i] );
        }
    }
    else if ( noDays < noDaysLastMonth ) { // remove days if this month has less days than last month
        for( int i = noDays; i < noDaysLastMonth; i++ ) {
            remove( labelArray[i] );
        }
    }
    validate();
    repaint();

    System.out.println(months[month]);
    System.out.println(noDays);

}

尽管代码未经检查,但这就是逻辑。

我认为这可以完成您想要的工作。
如果您有任何疑问或不明白,请随时提问。
它是如何工作的,在代码中通过注释进行了描述。

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Main extends JFrame implements ActionListener {

    private JComboBox<String> months;
    private String[] monthsList = { "January", "February", "March", "April",
            "May", "June", "July", "August", "September", "October",
            "November", "December" };
    private JPanel panel;

    private int[] days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };// days
                                                                            // of
                                                                            // each
                                                                            // month

    public Main() {
        super("My Caleander!");

        months = new JComboBox<>(monthsList); // Adding months to Combo box.

        panel = new JPanel(); // Panel for adding labels inside.
        setLayout(new BorderLayout());

        panel.setLayout(new GridLayout(0, 7));// 0 for dynamic number of rows
                                                // and 7 for each week.

        for (int i = 0; i < 31; i++) {
            panel.add(new JLabel(String.valueOf(i + 1))); // Adding days of
                                                            // month January.
        }

        months.addActionListener(this);// Adding Action listener for responding
                                        // to change of month.

        add(months, BorderLayout.NORTH);
        add(panel, BorderLayout.CENTER);

        setVisible(true);
        setLocationRelativeTo(null);// Putting JFrame to the center of screen.
        setSize(300, 300);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

    }

    public static void main(String[] args) {

        new Main();

    }

    @Override
    public void actionPerformed(ActionEvent e) {// Listening to changes made by
                                                // ComboBox.

        panel.removeAll();
        int daysOfMonth = months.getSelectedIndex();// Getting the index of
                                                    // current month

        for (int i = 0; i < days[daysOfMonth]; i++) {// Adding the requiered
                                                        // number of months.
            panel.add(new JLabel(String.valueOf(i + 1)));
        }

        panel.revalidate();//Updating panel.
        revalidate();//Upadating frame.

    }

}