Java 用于netty客户端的MVC前端
我对当前的引用()做了一些修改,并希望构建一个GUI前端。将对象从Java 用于netty客户端的MVC前端,java,swing,user-interface,model-view-controller,netty,Java,Swing,User Interface,Model View Controller,Netty,我对当前的引用()做了一些修改,并希望构建一个GUI前端。将对象从DatagramClientHandler传递到GUI非常简单。然而,GUI引用处理程序似乎很难 QuotesGUI类扩展了JFrame,以利用Netbeans拖放调色板轻松添加Swing组件。这很冗长 显然,解决办法是: 这要看情况而定,因为有不止一种解决方案。一个可能是 将侦听器注入ChannelHandler,然后该处理程序将收到通知 一旦收到消息。另一个解决方案可能是发送 一旦收到消息,将事件发送到主题,并注册 对该主题感
DatagramClientHandler
传递到GUI非常简单。然而,GUI引用处理程序似乎很难
QuotesGUI
类扩展了JFrame,以利用Netbeans拖放调色板轻松添加Swing组件。这很冗长
显然,解决办法是:
这要看情况而定,因为有不止一种解决方案。一个可能是
将侦听器注入ChannelHandler,然后该处理程序将收到通知
一旦收到消息。另一个解决方案可能是发送
一旦收到消息,将事件发送到主题,并注册
对该主题感兴趣的swing部件,因此他们会得到通知
DatagramClientHandler:
package net.bounceme.dur.netty;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;
import java.net.InetSocketAddress;
import java.util.logging.Logger;
import net.bounceme.dur.client.gui.QuotesGUI;
public class DatagramClientHandler extends SimpleChannelInboundHandler<DatagramPacket> {
private static final Logger log = Logger.getLogger(DatagramClientHandler.class.getName());
private final QuotesGUI gui = new QuotesGUI();
private volatile Channel channel = null;
DatagramClientHandler() {
log.info("starting..");
gui.setVisible(true);
}
private DatagramPacket getNext() {
DatagramPacket packet = new DatagramPacket(
Unpooled.copiedBuffer("QOTM?", CharsetUtil.UTF_8),
new InetSocketAddress("localhost", 4454));
return packet;
}
@Override
public void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
String response = msg.content().toString(CharsetUtil.UTF_8);
log.info(response);
gui.setQuote(response);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
log.severe(cause.toString());
ctx.close();
}
}
首先,将你的责任分层 我可能会首先定义某种监听器
接口
,它可以注册到DatagramClientHandler
的实例中。此接口
将允许相关方收到有关DatagramClientHandler
中的更改或事件的通知,并在他们认为合适的情况下处理这些事件
public interface MessageListener {
public void quoteRecieved(SimpleChannelInboundHandler source, String quote);
public void errorOccured(SimpleChannelInboundHandler source, Throwable cause);
}
然后您需要为侦听器提供支持
public class DatagramClientHandler extends SimpleChannelInboundHandler<DatagramPacket> {
private static final Logger log = Logger.getLogger(DatagramClientHandler.class.getName());
//private final QuotesGUI gui = new QuotesGUI();
private volatile Channel channel = null;
private List<MessageListener> listeners;
DatagramClientHandler() {
listeners = new ArrayList<MessageListener>(25);
//...
}
public synchronized void addMessageListener(MessageListener listener) {
listeners.add(listener);
}
public synchronized void removeMessageListener(MessageListener listener) {
listeners.remove(listener);
}
protected synchronized void fireQuoteRecieved(String quote) {
for (MessageListener listener : listeners) {
listener.quoteRecieved(this, quote);
}
}
@Override
public void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
String response = msg.content().toString(CharsetUtil.UTF_8);
log.info(response);
fireQuoteRecieved(response);
}
//...etc...
现在,如果您真的想,您可以进一步使用另一个接口
来解耦代码
public interface QuoteFactory {
public synchronized void addMessageListener(MessageListener listener);
public synchronized void removeMessageListener(MessageListener listener);
}
然后,这将由
DatagramClientHandler
实现,您的UI需要将QuoteFactory
的实例传递给它,以便它可以在发生某些事情时注册对通知的兴趣…如果将层分开,GUI应该不(实际)了解处理程序。它还要求您违反Swing的单线程规则(从EDT上下文之外更新UI)。相反,您可以设置一个侦听器接口
,它可以响应处理程序中的更改并进行适当的更改。这也可以由一个SwingWorker
来支持,它允许处理程序在一个单独的线程中工作,但提供了安全地更新/通知UI的方法…@MadProgrammer是的,这是我的问题。就用伪代码,你能详细说明一下吗?当然,我想把这些层分开--我只是不知道怎么分开。
//...
public void quoteRecieved(SimpleChannelInboundHandler source, final String quote) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
text.setText(packet);
}
});
}
public interface QuoteFactory {
public synchronized void addMessageListener(MessageListener listener);
public synchronized void removeMessageListener(MessageListener listener);
}