现在我有一个 CheckIn
舞台。 CheckIn
用textarea接收用户名和psd,然后创建一个 Client
类,并将信息发送到服务器。收到消息后,服务器将其签入数据库并发送一个状态码。然后这里出了点问题。javafx只能在自己的线程中创建新阶段。因此,当我尝试在clienthandler中调用controller中的方法时,会出现错误 Not on FX application thread; currentThread = NioProcessor-2
.
这是我的登录阶段:
public class CheckInController extends Controller implements ClientHandler.Callback {
private Label statusInfo=new Label();
private void initLogIn(){
LogIn.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
String userName=UserName.getText();
String passWord=PassWord.getText();
checkAndReact(userName,passWord);
}
});
statusInfo.textProperty().addListener((observable, oldValue, newValue) -> {
int status=Integer.parseInt(newValue);
if(status== Status.IS_MATCHED){
startMenu();
}else if(status==Status.WRONG_PASSWD){
wrongPsw();
HintInfo.setText(HINT_INFO_WRONG_PSD);
}else if(status==Status.USER_ID_NOT_EXISTS){
wrongUsrId();
HintInfo.setText(HINT_INFO_USER_NOT_EXISTS);
}
});
}
private void checkAndReact(String usrId, String psw){
UserInfo userInfo=new UserInfo();
userInfo.setPassWord(psw);
userInfo.setUserName(usrId);
Platform.runLater(() -> connect(userInfo));
}
static int CONNECT_TIMEOUT=10000;
static final String HOSTNAME= Constants.HOST_NAME;
static final int PORT= Constants.PORT;
public void connect(AbstractMessage message) {
NioSocketConnector connector = new NioSocketConnector();
connector.setConnectTimeoutMillis(CONNECT_TIMEOUT);
connector.getFilterChain().addLast("codec",
new ProtocolCodecFilter(new NoteProtocolCodecFactory()));
connector.getFilterChain().addLast("logger", new LoggingFilter());
connector.setHandler(new ClientHandler( this));
IoSession session;
for (;;) {
try {
ConnectFuture future = connector.connect(new InetSocketAddress(HOSTNAME, PORT));
future.awaitUninterruptibly();
session = future.getSession();
session.write(message);
break;
} catch (RuntimeIoException e) {
System.err.println("Failed to connect.");
e.printStackTrace();
}
}
// wait until the summation is done
session.getCloseFuture().awaitUninterruptibly();
connector.dispose();
}
private void startMenu(){
// WindowManager will start a new Stage with FXMLoader
WindowManager.startWindow("Menu");
WindowManager.stopWindow("CheckIn",stage);
}
// This method will be the first to call
public void init(Stage primaryStage){
this.stage =primaryStage;
initLogIn();
}
// This is because CheckInController implement interface CallBack
@Override
public void loggedStatus(int status) {
statusInfo.setText(String.valueOf(status));
}
``` `NoteProtocolCodecFactory` :
public class NoteProtocolCodecFactory extends DemuxingProtocolCodecFactory {
public NoteProtocolCodecFactory(){
super.addMessageDecoder(AbstractMessageDecoder.class);
super.addMessageEncoder(AbstractMessage.class,AbstractMessageEncoder.class);
}
}
解码器:
public class AbstractMessageDecoder implements MessageDecoder {
@Override
public MessageDecoderResult decodable(IoSession ioSession, IoBuffer ioBuffer) {
if(ioBuffer.remaining()<Constants.TYPE_LEN){
return MessageDecoderResult.NEED_DATA;
}
return MessageDecoderResult.OK;
}
@Override
public MessageDecoderResult decode(IoSession ioSession, IoBuffer ioBuffer, ProtocolDecoderOutput protocolDecoderOutput){
AbstractMessage message=null;
try {
message = (AbstractMessage) ioBuffer.getObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if(message instanceof UserInfo){
//
}else if(message instanceof Result){
message=(Result)message;
}
protocolDecoderOutput.write(message);
return MessageDecoderResult.OK;
}
编码器:
public class AbstractMessageEncoder implements MessageEncoder {
@Override
public void encode(IoSession session,T message, ProtocolEncoderOutput out) throws Exception {
IoBuffer buffer=IoBuffer.allocate(4);
buffer.setAutoExpand(true);
buffer.putObject(message);
buffer.flip();
out.write(buffer);
}
客户端处理程序:
public class ClientHandler extends IoHandlerAdapter{
private AbstractMessage response=null;
public interface Callback{
void loggedStatus(int status);
// ... other methods
}
private final Callback callback;
public ClientHandler(Callback callback){
this.callback =callback;
}
@Override
public void sessionOpened(IoSession session) { }
@Override
public void messageReceived(IoSession session, Object message) {
if(message instanceof Note){
//
}else if(message instanceof NoteBook){
//
}else{ // it will come in here
callback.loggedStatus(((Result)message).getStatus());
session.close();
}
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) {
session.close(true);
}
}
服务器:
public class Server
{
private static final int PORT= Constants.PORT;
public static void main( String[] args ) throws IOException {
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );
acceptor.getFilterChain().addLast( "codec",
new ProtocolCodecFilter( new NoteProtocolCodecFactory()));
acceptor.setHandler(new ServerHandler());
acceptor.getSessionConfig().setReadBufferSize( 2048 );
acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
acceptor.bind(new InetSocketAddress(PORT));
}
}
服务器处理程序:
public class ServerHandler extends IoHandlerAdapter {
@Override
public void messageReceived(IoSession session, Object message) {
if(message instanceof UserInfo){
UserInfo userInfo=(UserInfo)message;
int status= CheckPswDao.isMatched(userInfo.getUserName(),userInfo.getPassWord());
Result res=new Result();
res.setStatus(status);
session.write(res);
}
}
}
我试着把它包起来 `Task` 以及 `Platform` ,但在这种情况下,程序将被卡在行中 `new Stage()` . 我很困惑,因为我不知道我能做些什么来解决这个问题。如果有人能给我一些建议或相关的文章或文件,我将非常感谢。
暂无答案!
目前还没有任何答案,快来回答吧!