【发布时间】:2023-04-11 12:19:01
【问题描述】:
对此可能有更好的问题/答案,但我一直在寻找的东西没有解决,我在为谷歌查询提出问题时遇到了麻烦。基本上,我有一个 JFrame,其中包含几个面板和组件,它们从 xml 文件中提取数据。我使用 JFrame 的实例变量 private Date focusDate = new Date(); 来存储我希望每个面板显示哪一天的信息,到目前为止一切顺利。
现在我的问题来了,我试图在更改“focusDate”后将导航组件的各种操作设置为更新。我在 JPanel NavButtons navPanel = new NavButtons(focusDate); 中有一个工具栏,我将其设置为内部类,控制台报告 focusDate 正在更改,但是当我调用 setFocus(Date d) 方法时,我无法将 JFrame 设置为 validate(), repaint(), etc...。
如果有帮助,我可以包含更多我的代码,但这是有问题的方法:
public void setFocus(Date d) throws IOException {
focusDate = d;
dispose();
// validate(); //Tried revalidate too, but DisplayView extends JFrame
// repaint();
// revalidate();
// pack();
// DisplayView view = new DisplayView(focusDate);
setVisible(true); }
这是我在构造函数中设置 ActionListener 的方式:
public NavButtons(Date d) {
newDate = LocalDate.parse(new SimpleDateFormat("yyyy-MM-dd").format(d));
weekBack.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
newDate = newDate.plusDays(-7);
try { setFocus(Date.from(newDate.atStartOfDay(ZoneId.systemDefault()).toInstant()));
} catch (IOException e) {
e.printStackTrace(); }
//validate();
//repaint();
}
});
我对摇摆不是很熟悉,所以我确定这是一些我没有得到的小细节,但如果有人可以解释如何重新触发参数传递并将框架的子组件更新为非常感谢的业余爱好者。
更新 这是整个 JFrame
package interfaceComponents;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.*;
import java.io.IOException;
import java.text.*;
import java.util.*;
import java.time.*;
public class DisplayView extends JFrame {
//instance variables
private Date focusDate = new Date();
//constructor
public DisplayView(Date d) throws IOException {
DisplayMenus menus = new DisplayMenus();
setJMenuBar(menus);
JPanel body = new JPanel();
body.setLayout(new BoxLayout(body, BoxLayout.Y_AXIS));
body.add(new DayView(focusDate));
LocalDate focusNextDay = LocalDate.now();
body.add(new DayView(Date.from(focusNextDay.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant())));
add(new JScrollPane(body), BorderLayout.CENTER);
JPanel footer = new JPanel();
NavButtons navPanel = new NavButtons(focusDate);
JLabel focusPoint = new JLabel(new SimpleDateFormat("E, dd MMM yyyy").format(focusDate).toString());
focusPoint.setForeground(Color.RED);
footer.setLayout(new BorderLayout());
footer.add(focusPoint, BorderLayout.CENTER);
footer.add(navPanel, BorderLayout.EAST);
footer.setBackground(Color.BLACK);
add(footer, BorderLayout.SOUTH);
pack(); }
public DisplayView() throws IOException { this(new Date()); }
public void setFocus(Date d) throws IOException {
focusDate = d;
SwingUtilities.updateComponentTreeUI(this);
// dispose();
// invalidate();
// validate(); //Tried revalidate too, but DisplayView extends JFrame
repaint();
// revalidate();
// pack();
// DisplayView view = new DisplayView(focusDate);
// setVisible(true);
}
public Date getFocus() { return focusDate; }
class NavButtons extends JPanel {
private JToolBar toolBar = new JToolBar("Navigation");
private JButton weekBack = new JButton("<<");
private JButton dayBack = new JButton("<");
private JButton returnToday = new JButton("Today");
private JButton nextDay = new JButton(">");
private JButton nextWeek = new JButton(">>");
private JButton calendar = new JButton("L");
private LocalDate newDate = LocalDate.now();
public NavButtons(Date d) {
newDate = LocalDate.parse(new SimpleDateFormat("yyyy-MM-dd").format(d));
weekBack.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
newDate = newDate.plusDays(-7);
try { setFocus(Date.from(newDate.atStartOfDay(ZoneId.systemDefault()).toInstant()));
} catch (IOException e) {
e.printStackTrace(); }
// invalidate();
// validate();
// repaint();
}
});
dayBack.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) { newDate = newDate.plusDays(-1); }
});
returnToday.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) { newDate = LocalDate.now(); }
});
nextDay.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) { newDate = newDate.plusDays(1); }
});
nextWeek.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) { newDate = newDate.plusDays(7); }
});
toolBar.add(weekBack);
toolBar.add(dayBack);
toolBar.add(returnToday);
toolBar.add(nextDay);
toolBar.add(nextWeek);
toolBar.add(new GalileoMode());
toolBar.add(calendar);
add(toolBar); }
}
}
正如@MadProgrammer 所指出的,我应该将日期存储在一个单独的对象中(如图所示):
package interfaceComponents;
import java.util.*;
public class FocusDate {
//instance variables
Date focus = new Date();
//constructors
//intentionally blank: public FocusDate() {}
//methods:
public void setFocus(Date d) {
focus = d; }
public Date getFocus() {
return focus; }
}
我这样编辑了框架:
public class DisplayView extends JFrame {
//instance variables
FocusDate focus = new FocusDate();
// private Date focusDate = new Date();
//constructor
public DisplayView(Date d) throws IOException {
// focusDate = d;
Date focusDate = focus.getFocus();
...
public void setFocus(Date d) throws IOException {
// focusDate = d;
focus.setFocus(d);
虽然还是没做对...
【问题讨论】:
-
看看this question对你有没有帮助。
-
考虑提供一个可运行的问题示例。它将消除猜测工作并产生更好的响应
-
什么解决方案是将日期封装在模型中,然后传递给需要它的每个组件。该模型将允许感兴趣的各方注册一个回调,该回调将在日期更改时通知,以便他们可以采取适当的行动(也称为观察者模式)
-
这听起来正是我需要的@MadProgrammer!我会在检查完 Aprendiz 的链接后立即尝试。感谢你们的快速响应(如果我仍然需要帮助,我会回复有效的或包含可运行的版本)。
-
感谢@Aprendiz 的链接,但这似乎没有奏效。也许我在影响 JFrame 的实例而不是对象本身时遇到了麻烦?
标签: java swing model-view-controller repaint abstract-action