简体   繁体   中英

Altering JFrame component based on button press from contained JPanel

I am trying to create an application which will increment the month in a LocalDateTime object when a button is pressed.

The LocalDateTime object and JLabel displaying the month name is stored in the Main class which extends JFrame.

The JButton which has an ActionListener, incrementing the month of the LocalDateTime object by 1 when it is pressed, is stored in a separate class called Panel1 which extends JPanel.

The Panel1 class is added to the JFrame. What should I do to make it so that the JLabel will reflect the changes made to the LocalDateTime object when the button is pressed?

Main Class:

import javax.swing.*;
import java.awt.*;
import java.time.LocalDateTime;

public class Main extends JFrame {

    private LocalDateTime currentTime = LocalDateTime.now();
    private JLabel monthLabel;

    public Main() {
        super();
        setLayout(new BorderLayout());
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        monthLabel = new JLabel(currentTime.getMonth().name());

        add(monthLabel, BorderLayout.NORTH);
        add(new Panel1(currentTime), BorderLayout.SOUTH);

        pack();
        setVisible(true);
    }

    public static void main(String args[]) {
        Main main = new Main();
    }

}

Panel1 Class:

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalDateTime;

public class Panel1 extends JPanel implements ActionListener {

    private LocalDateTime time;
    private JButton incrementMonth;

    public Panel1(LocalDateTime time) {
        this.time = time;

        incrementMonth = new JButton(">");
        incrementMonth.addActionListener(this);
        add(incrementMonth);
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == incrementMonth) {
            time = time.plusMonths(1);
        }
    }

}

If you want an observer pattern, you can use PropertyChangeListener on swing components. Your Panel1 should fire an event on a property

public class Panel1 extends JPanel implements ActionListener {

    private LocalDateTime time;
    private JButton incrementMonth;

    public Panel1(LocalDateTime time) {
        this.time = time;

        incrementMonth = new JButton(">");
        incrementMonth.addActionListener(this);
        add(incrementMonth);
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == incrementMonth) {
            LocalDateTime oldValue = time;
            time = time.plusMonths(1);
            this.firePropertyChange("month", oldValue.getMonth().name(), time.getMonth().name());
        }
    }

}

The "month" property it's aware in the following code, in your Main class:

super();
    setLayout(new BorderLayout());
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    monthLabel = new JLabel(currentTime.getMonth().name());

    add(monthLabel, BorderLayout.NORTH);
    Panel1 panel1 = new Panel1(currentTime);
    panel1.addPropertyChangeListener("month", new PropertyChangeListener() {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            monthLabel.setText(evt.getNewValue().toString());
        }
    });
    add(panel1, BorderLayout.SOUTH);

    pack();
    setVisible(true);

I rather prefer this solution than linking swing components together or making them static.

What should I do to make it so that the JLabel will reflect the changes made to the LocalDateTime object when the button is pressed?

Here's what:

  • Declare monthLabel as protected static .

     protected static JLabel monthLabel; 

    This way, it will be visible to other classes in the package.

  • Add the line to change the text in you actionPerformed() method.

     public void actionPerformed(ActionEvent e) { if (e.getSource() == incrementMonth) { time = time.plusMonths(1); Main.monthLabel.setText(time.getMonth().name()); } } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM