使用 java,我有一个 JFrame,其中包含多个 JPanel,其中包括各种 JComboBoxes、JTextFields 等……它们连接到 xml 文件中的条目,按日期组织和查看。一切都同步并且正在工作,但是当对条目进行更改(即添加/删除等)时,我一直无法让 JFrame 更新/刷新,尽管当我更改日期时它会刷新。我已经到了触发 PropertyChangeListener(打印到控制台)的地步,但是当我尝试使用该侦听器刷新框架时,我认为我只是在重新验证侦听器?
这是来自 JFrame 的代码(我使用注释来指示失败的段):
package interfaceComponents;
import java.beans.*;
import javax.swing.*;
import org.jdesktop.swingx.JXDatePicker;
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.io.IOException;
import java.util.*;
import java.time.*;
import java.time.format.*;
public class DailyView extends Frame {
private static final long serialVersionUID = 7827570917642254745L;
private final JXDatePicker calendar = new JXDatePicker();
private JLabel focusPoint;
public DailyView(LocalDate d) throws IOException {
DefaultDateModel model = new DefaultDateModel(d);
OperatorMenus menus = new OperatorMenus();
setJMenuBar(menus);
JPanel body = new JPanel();
body.setLayout(new BoxLayout(body, BoxLayout.Y_AXIS));
DayView anchorDay = new DayView(0);
anchorDay.setModel(model);
DayView nextDay = new DayView(1);
nextDay.setModel(model);
body.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("OperatorView.propertyChange");
//***This is where I'm trying to TRIGGER the REFRESH***
refreshFrame(); }
});
body.add(anchorDay);
body.add(nextDay);
add(new JScrollPane(body), BorderLayout.CENTER);
JPanel footer = new JPanel();
NavButtons navPanel = new NavButtons(model);
focusPoint = new JLabel(DateTimeFormatter.ofPattern("E, dd MMM yyyy").format(model.getDate()));
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 DailyView() throws IOException { this(LocalDate.now()); }
//interfaces
public interface DateModel {
public LocalDate getDate();
public void addObserver(Observer o);
public void removeObserver(Observer o); }
public interface MutableDateModel extends DateModel {
public void setDate(LocalDate date); }
//methods
public void refreshFrame() { //***This is where I'm trying to TRIGGER the REFRESH***
this.revalidate();
this.repaint(); }
//inner classes
public class DefaultDateModel extends Observable implements MutableDateModel {
private LocalDate date;
public DefaultDateModel(LocalDate d) { date = d; }
@Override
public void setDate(LocalDate d) {
date = d;
setChanged();
notifyObservers(); }
@Override
public LocalDate getDate() {
return date; }
@Override
public void removeObserver(Observer o) {
deleteObserver(o); }
}
public class ShiftFocus extends AbstractAction implements Observer {
private static final long serialVersionUID = 680383526965967229L;
private MutableDateModel model;
private int shift;
public ShiftFocus(MutableDateModel m, int i) {
setModel(m);
shift = i; }
public void actionPerformed(ActionEvent event) {
MutableDateModel model = getModel();
if (model != null) {
model.setDate(model.getDate().plusDays(shift));
calendar.setDate(Date.from(model.getDate().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
pack(); }
}
public void setModel(MutableDateModel value) {
if (model != null) {
model.removeObserver(this); }
this.model = value;
if (model != null) {
model.addObserver(this); }
}
public MutableDateModel getModel() {
return model; }
@Override
public void update(Observable o, Object arg) {
focusPoint.setText(DateTimeFormatter.ofPattern("E, dd MMM yyyy").format(model.getDate())); }
}
class NavButtons extends JPanel implements Observer {
private static final long serialVersionUID = 914087518688373731L;
//instance variables
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 MutableDateModel model;
//constructor
public NavButtons(MutableDateModel model) {
weekBack.addActionListener(new ShiftFocus(model, -7));
dayBack.addActionListener(new ShiftFocus(model, -1));
returnToday.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
MutableDateModel m = getModel();
m.setDate(LocalDate.now());
setModel(m);
pack(); }
});
nextDay.addActionListener(new ShiftFocus(model, 1));
nextWeek.addActionListener(new ShiftFocus(model, 7));
toolBar.add(weekBack);
toolBar.add(dayBack);
toolBar.add(returnToday);
toolBar.add(nextDay);
toolBar.add(nextWeek);
calendar.setEditable(true);
calendar.setFormats("E, dd MMM yyyy");
calendar.setDate(Date.from(model.getDate().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
calendar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
MutableDateModel model = getModel();
if (model != null) {
model.setDate(LocalDate.parse(new SimpleDateFormat("yyyy-MM-dd").format(calendar.getDate())));
pack(); }
}
});
toolBar.add(calendar);
toolBar.add(new GalileoMode());
add(toolBar);
setModel(model); }
public void setModel (MutableDateModel value) {
if (model != null) {
model.removeObserver(this); }
this.model = value;
if (model != null) {
model.addObserver(this); }
}
public MutableDateModel getModel() {
return model; }
@Override
public void update(Observable o, Object arg) {/* models data changes */}
}
}
编辑
经过一些反馈,到目前为止已经尝试过:
thisFrame = this;
body.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("OperatorView.propertyChange");
// thisFrame.removeAll();
// thisFrame.dispose();
// thisFrame.remove(body);
// thisFrame.add(new JScrollPane(body), BorderLayout.CENTER);
thisFrame.getContentPane().validate();
// thisFrame.revalidate();
thisFrame.getContentPane().repaint();
// thisFrame.refreshFrame();
}
});
在DailyView thisFrame;
顶部声明为实例变量。
编辑
万一有人在读这篇文章,我会让 propertyChangeListener 触发某些事件,这些事件会刷新底层面板,但是当 propertyChangeListener 再次被调用时,这会导致无限循环。(re)validate() 和 repaint() 似乎没有这个问题,但他们没有刷新面板的内容......任何可以指出我正确方向/链接到类似问题等的人都会是非常感激。