【问题标题】:Altering JFrame component based on button press from contained JPanel根据包含的 JPanel 中的按钮按下来更改 JFrame 组件
【发布时间】:2016-04-13 12:48:26
【问题描述】:

我正在尝试创建一个应用程序,当按下按钮时,它将在 LocalDateTime 对象中增加月份。

LocalDateTime 对象和显示月份名称的 JLabel 存储在扩展 JFrame 的 Main 类中。

具有 ActionListener 的 JButton 在按下时将 LocalDateTime 对象的月份加 1,存储在一个名为 Panel1 的单独类中,该类扩展了 JPanel。

Panel1 类被添加到 JFrame。我应该怎么做才能使 JLabel 在按下按钮时反映对 LocalDateTime 对象所做的更改?

主类:

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();
    }

}

面板 1 类:

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);
        }
    }

}

【问题讨论】:

    标签: java swing datetime jpanel actionlistener


    【解决方案1】:

    我应该怎么做才能让 JLabel 在按下按钮时反映对 LocalDateTime 对象所做的更改?

    这是什么:

    • monthLabel 声明为protected static

      protected static JLabel monthLabel;
      

      这样,包中的其他类都可以看到它。

    • 添加行以更改 actionPerformed() 方法中的文本。

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

    【讨论】:

      【解决方案2】:

      如果你想要一个观察者模式,你可以在 swing 组件上使用 PropertyChangeListener。您的 Panel1 应该在属性上触发一个事件

      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());
              }
          }
      
      }
      

      它在您的 Main 类中的以下代码中知道的“月”属性:

      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);
      

      我更喜欢这种解决方案,而不是将摆动组件连接在一起或使它们成为静态的。

      【讨论】:

        猜你喜欢
        • 2015-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多