gpt4 book ai didi

java - 在 Swing 中为 MVC 模型使用撤消/重做?

转载 作者:行者123 更新时间:2023-11-29 03:41:47 24 4
gpt4 key购买 nike

我有一个 MVC 模型,我正在尝试向它添加撤消/重做功能。用户可以在 JTextField 中放置一个数字,当他们单击 UNDO 按钮时,它应该被删除。我已经为实现它的类提供了代码。我得到的错误在底部。

控制包:

ButtonnGUIControl.java

包控制;

/** * 此类将控制 GUI 的按钮 Action 。它实现了 actionListener() 方法 * 并且基于被点击的按钮,它初始化 * 模型类中的相应组件。 * */

public class ButtonGUIControl implements ActionListener{
private SudokuModel model;
private ButtonGUI bgui;
final UndoManager manager = new UndoManager();



public ButtonGUIControl(SudokuModel model) {
this.model = model;
}

/*This method will listen for user events, and act accordingly
* */

public void actionPerformed(ActionEvent e) {
try {
if(e.getActionCommand().equals("Check My Answer!")){

model.checkGame();
}


else if (e.getActionCommand().equals("Undo")){

try {

manager.undo();
} catch (CannotUndoException ex) { ex.printStackTrace(); }
finally {
//updateButtons();
}
}
else if (e.getActionCommand().equals("Redo")){

manager.redo();
System.out.println("e.getActionCommand().equals redo");
}

//otherwise, it simply places the selected number in the grid
else{

model.setNumber(Integer.parseInt(e.getActionCommand()));
}

} catch (NumberFormatException e1) {}

catch (IOException e1) {}
catch (CannotUndoException ex) {
System.out.println("Unable to undo: " + ex);
ex.printStackTrace();
}
catch (CannotRedoException ex) {
System.out.println("Unable to redo: " + ex);
ex.printStackTrace();
}

}

public void undoableEditHappened(UndoableEditEvent evt) {

manager.addEdit(evt.getEdit());

//bgui.updateButtons();

}


在 View 包中:按钮GUI.java

我向按钮添加一个 actionListner:

RedoBttn.addActionListener(buttonController);

UndoBttn.addActionListener(buttonController);


在扩展 JTextField 的 Grid.java 中:

public class Grid extends JTextField {
private int x;
private int y;

final UndoManager manager = new UndoManager();


public Grid(int x, int y) {
super("");
this.x = x;
this.y = y;
getDocument().addUndoableEditListener(manager);



setPreferredSize(new Dimension(40, 40));
setBorder(BorderFactory.createLineBorder(Color.GREEN));
setOpaque(true);
}


public void setNumber(int number, boolean userInput) {


if(number > 0 & !userInput){
setText(""+number);
setEditable(false);


}

//These set of numbers are the only ones that the user can undo/redo
else if (number > 0 & userInput){
setText(""+number);
setEditable(true);
}
else
setText("");

我还在 View 包的另一个类中为每个 JTextFields 添加了一个鼠标监听器。所以我认为我的撤消/重做结构是正确的。当我运行该程序时,我可以选择一个数字并将其放在 JTextField(网格)中,但是一旦我点击“撤消”,我就会收到以下异常:

    javax.swing.undo.CannotUndoException
at javax.swing.undo.UndoManager.undo(UndoManager.java:411)
at control.ButtonGUIControl.actionPerformed(ButtonGUIControl.java:76)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6505)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6270)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2713)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
at java.awt.EventQueue.access$000(EventQueue.java:101)
at java.awt.EventQueue$3.run(EventQueue.java:666)
at java.awt.EventQueue$3.run(EventQueue.java:664)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:680)
at java.awt.EventQueue$4.run(EventQueue.java:678)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

第 76 行是我调用的地方:

    manager.undo() 

在 try/catch block 中。

知道有什么问题吗?是我的撤消/重做实现还是其他?

谢谢!!!

最佳答案

尝试像这样包装 manager.undo();:

if(manager.canUndo())
manager.undo();

我怀疑 JTextField 的默认 UndoListener 实现不会添加系统更新(即调用 setText(""+number); 到撤消队列) - 仅从 UI 更新。

编辑

经过一些测试,setText("") 函数似乎确实向 UndoManager 添加了撤消,所以这不是您遇到的问题。因此,您可以通过确保有任何可撤消的操作来撤消来防止错误;但是,如果您在 UndoManager 中没有获得任何可撤消的操作,则问题可能出在代码的其他地方。

关于java - 在 Swing 中为 MVC 模型使用撤消/重做?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12823044/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com