在java中使用MVC模式:我有5个类(视图(GUI)、控制器、模型、Class1和Class2)。当我单击“开始”按钮时,控制器启动模型中的一个线程,然后启动另外两个线程T1 (在类1中实现)&T2(在class2中实现)。
T1应该在JTextArea-1上显示一些信息,然后5秒后,T2应该从JTextArea-1中删除数据并粘贴到JTextArea-2。
我让T1工作了。它将信息显示在JTextArea-1上。但我关切的是,下一个步骤的开始及其实施。
T2如何与相同的模型对话并获得要调用的视图的相同更新方法,但要执行不同的操作集?
线程T1在class1中:
public void run() {
while(!R.isFinished()) {
System.out.println("inside kitchen thread");
String report="";int size =0;
String str="";int tn=0;
report = getOrderReport();
size= report.length();
for(int i=1;i<=size;i=i+43){
try
{
Thread.sleep(1000);
str = report.substring(i,i+43);
tn=Integer.parseInt(str.substring(8,9));
System.out.println("inside kitchen thread order seq num: " +OrderSeq.getInstance().getNext());
OrderSeq.getInstance().setLog(str);
R.receiveAnOrder(str,tn);
}
catch (Exception e) {
System.out.println("Kitchen thread exception" + e.getStackTrace());
}
}在上面的代码中: R.receiveAnOrder(str,tn)与模型通信以更新视图。
我如何调用模型中的相同或可能另一个函数来使用来自另一个线程的详细信息更新视图?
发布于 2014-04-01 08:00:26
首先,您需要两个模型类。
你需要一份订单
public Order {
private String name;
public Order(String name) {
this.name = name;
}
public String toString() {
return name;
}
}还有一份订单清单
public OrderList extends DefaultListModel<Order> {
}还有一个厨师来做命令
public void Cook extends Thread implements ActionListener {
private OrderList waiting;
private OrderList finished;
private boolean keepCooking;
public Cook(OrderList waiting, OrderList finished) {
this.waiting = waiting;
this.finished = finished;
this.keepCooking = false;
}
public void run() {
keepCooking = true;
while (keepCooking) {
if (orders.size() > 0) {
try {
currentOrder = orders.remove(0);
} catch (Exception e) {
// someone else emptied the list
}
}
prepareOrder(order);
if (keepCooking && orders.size() <= 0) {
try {
Thread.sleep(1000);
} catch (Exception e) {
// back to work
}
}
}
}
public void prepareOrder(Order order) {
try {
Thread.sleep(Math.random() % 10000);
finished.add(order);
} catch (Exception e) {
waiting.add(order);
}
}
public void goHome() {
keepCooking = false;
}
}你需要一些顾客来下订单
public Customers extends Thread {
private OrderList orders;
public Customers(OrderList orders) {
this.orders = orders;
}
public void run() {
int number = 0;
while (true) {
number++;
try {
Thread.sleep(Math.random() % 10000)
orders.add(new Order(String.format("Order %d", number)));
} catch (Exception e) {
return;
}
}
}
}现在有一个组件来帮助配置控制器
public CloseKitchen extends AbstractAction {
private Cook cook;
public CloseKitchen(Cook cook) {
super("Close Kitchen");
this.cook = cook;
}
public void actionPerformed(ActionEvent e) {
cook.goHome();
}
}..。在某个代码块中..。
// building the model
OrderList waiting = new OrderList();
OrderList finished = new OrderList();
Cook cook = new Cook(waiting, finished);
Customers customers = new Customers(waiting);
// attaching the view
somePanel.add(new JList(waiting));
somePanel.add(new JList(finished));
// building the controller plug-in
CloseKitchen closeKitchen = new CloseKitchen(cook);
// wiring the plugin into the controller
somePanel.add(new JButton(closeKitchen));
// show the view
somePanel.setVisible(true);
// start the cook and customers
cook.start();
customers.start();您将看到订单在一个列表中填充,然后移到另一个列表中。也就是说,直到你点击“关闭厨房”按钮,然后厨师将goHome()和顾客将继续点菜。
有很多方法来实现库克和客户。我故意不使用ListDataListener实现来避免对模型需要使用什么的混淆。基本上,真正的模型不需要使用任何与其内部协调相关的swing,只要它能够适应正确的[List|Table|Button|...]Model接口。
发布于 2014-04-01 06:51:20
您可以让Views观察Model。这意味着每次线程更改Models数据时,都会更新所有已注册的视图。
T1 --- uses `Controller` to manipulate `Model` (e.g. `Model`.value1) --> `Controller`
T2 --- uses `Controller` to manipulate `Model` (e.g. `Model`.value1) --> `Controller`
`View1` --- observes `Model`, shows Model.value1 on update --> `Model`
`View2` --- observes `Model`, shows Model.value2 on update --> `Model`因此,按照您的解释,T2将让Controller读取Model.value1,清除它并将值设置为Model.value2。当Controller更改Models值时,它会指示注册的Views更新(在您的示例中为2个视图)。因此,View1清除其JTextField,因为Model.value1为空,View2将其JTextField更新为Model.value2。
要实现视图的更新机制,请阅读这教程中的观察者模式。
此外,请记住,来自线程的GUI操作(例如,SWING)必须由EventDispatcherThread (EDT)完成。SwingUtilities为此提供了一个函数。只需从其他线程运行所有GUI相关代码,如下所示:
SwingUtilities.invokeLater( new Runnable() {
public void run() {
//Do the gui stuff here
}
});阅读更多关于EDT和SwingUtitlities 这里的信息。
https://stackoverflow.com/questions/22778192
复制相似问题