大家好!
所以是的,我试图用Java创建聊天功能。问题是我有两个班。一个用于客户端,一个用于ClientGUI。客户端具有Logic的东西,ClientGUI的设计。问题是第46行,new ListenFromServer().start();
出错
"不能访问类型为Controller的封闭实例。必须 使用封闭的类型实例限定分配 COntroller(例如x.new A(),其中x是Controller的一个实例)。 "
我希望有人可以帮助我!
**Controller (Client logic)**
package Server;
import java.io.*;
import java.net.*;
import java.util.*;
public class Controller {
private static ObjectInputStream input;
private static ObjectOutputStream output;
private static Socket socket;
private static ClientGUI clientgui;
private static String username;
private static String server;
private static int port;
public static boolean startClient(){
try{
socket = new Socket(server, port);
}catch (Exception ex){
System.out.print("Error connecting to the server: " + ex);
return false;
}
String message = "Connection is accepted; " + socket.getInetAddress() +" - "+ socket.getPort();
System.out.println(message);
try {
input=new ObjectInputStream(socket.getInputStream());
output =new ObjectOutputStream(socket.getOutputStream());
}
catch (IOException io) {
System.out.print("Exception creating new Input/Output Stream: "+ io);
return false;
}
**********new ListenFromServer().start();********* //The problem is here
try {
output.writeObject(username);
}
catch(IOException io) {
System.out.print("Exception doing login: " + io);
disconnect();
return false;
}
return true;
}
private void display(String message) {
if(clientgui == null)
System.out.println(message);
else
clientgui.append(message +"\n");
}
public static void sendMessage(Message message) {
try {
output.writeObject(message);
}
catch(IOException exd) {
System.out.print("Eceptionwritingtoserver: " + exd);
}
}
private static void disconnect() {
try {
if(input != null)
input.close();
}catch (Exception ex){}
try{
if(output != null)
output.close();
}catch(Exception ex){}
try{
if(socket != null)
socket.close();
}catch(Exception ex){};
if (clientgui != null)
clientgui.connectionFailed();
}
public class ListenFromServer extends Thread{
public void run() {
while(true){
try{
String message = (String) input.readObject();
if(clientgui == null){
System.out.println(message);
System.out.print(":");
}
else {
clientgui.append(message);
}
}
catch(IOException io){
System.out.print("Server has closed the connection");
if(clientgui != null)
clientgui.connectionFailed();
break;
}
catch(ClassNotFoundException classex){
}
}
}
}
}
ClientGUI
package Server;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/*
* The Client with its GUI
*/
public class ClientGUI extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
private JLabel lblusername;
private JTextField textfieldusername, textfieldserver, textfieldportnumber;
private JButton btnlogin, btnlogout, btnonline;
private JTextArea textareamessage;
private boolean connected;
private Client client;
private int defaultPort;
private String defaultHost;
ClientGUI(String host, int port) {
super("Chat Client");
defaultPort = port;
defaultHost = host;
JPanel northPanel = new JPanel(new GridLayout(2,2));
JPanel serverAndPort = new JPanel(new GridLayout(1,2, 2, 2));
JLabel lblserveraddress = new JLabel("Server Address: ");
JLabel lblchat = new JLabel(" #BallIsLife");
JLabel lblportnumber = new JLabel("Port Number: ");
textfieldserver = new JTextField(host);
textfieldserver.setHorizontalAlignment(SwingConstants.LEFT);
textfieldserver.setFont(new Font("Tahoma", Font.PLAIN, 20));
textfieldportnumber = new JTextField("" + port);
textfieldportnumber.setFont(new Font("Tahoma", Font.PLAIN, 20));
textfieldportnumber.setHorizontalAlignment(SwingConstants.LEFT);
lblserveraddress.setFont(new Font("Tahoma", Font.PLAIN, 19));
serverAndPort.add(lblserveraddress);
serverAndPort.add(textfieldserver);
serverAndPort.add(lblchat);
serverAndPort.add(lblportnumber);
serverAndPort.add(textfieldportnumber);
lblchat.setForeground(Color.RED);
lblportnumber.setFont(new Font("Tahoma", Font.PLAIN, 19));
northPanel.add(serverAndPort);
getContentPane().add(northPanel, BorderLayout.NORTH);
JPanel panelbtn = new JPanel();
northPanel.add(panelbtn);
btnlogin = new JButton("Login");
panelbtn.add(btnlogin);
btnlogin.setFont(new Font("Tahoma", Font.PLAIN, 17));
btnlogin.addActionListener(this);
btnonline = new JButton("Online");
panelbtn.add(btnonline);
btnonline.setFont(new Font("Tahoma", Font.PLAIN, 17));
btnonline.addActionListener(this);
btnonline.setEnabled(false);
btnlogout = new JButton("Logout");
panelbtn.add(btnlogout);
btnlogout.setFont(new Font("Tahoma", Font.PLAIN, 17));
btnlogout.addActionListener(this);
btnlogout.setEnabled(false);
JButton btnPicture = new JButton("Picture");
btnPicture.setFont(new Font("Tahoma", Font.PLAIN, 17));
btnPicture.setEnabled(false);
panelbtn.add(btnPicture);
textareamessage = new JTextArea("Welcome to the #BallIsLife Chat room.\n");
textareamessage.setFont(new Font("Monospaced", Font.PLAIN, 15));
textareamessage.setLineWrap(true);
textareamessage.setEditable(false);
JPanel centerPanel = new JPanel(new GridLayout(1,1));
JScrollPane scrollPane = new JScrollPane(textareamessage);
centerPanel.add(scrollPane);
getContentPane().add(centerPanel, BorderLayout.CENTER);
JPanel southPanel = new JPanel();
getContentPane().add(southPanel, BorderLayout.SOUTH);
lblusername = new JLabel("Enter your username", SwingConstants.CENTER);
lblusername.setFont(new Font("Tahoma", Font.PLAIN, 15));
southPanel.add(lblusername);
textfieldusername = new JTextField("Write your username here.");
textfieldusername.setFont(new Font("Tahoma", Font.PLAIN, 14));
textfieldusername.setColumns(50);
southPanel.add(textfieldusername);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(823, 665);
setVisible(true);
}
//Logiken
void append(String str) {
textareamessage.append(str);
textareamessage.setCaretPosition(textareamessage.getText().length() - 1);
}
void connectionFailed() {
btnlogin.setEnabled(true);
btnlogout.setEnabled(false);
btnonline.setEnabled(false);
lblusername.setText("Enter your username");
textfieldusername.setText("Write your username here");
textfieldportnumber.setText("" + defaultPort);
textfieldserver.setText(defaultHost);
textfieldserver.setEditable(false);
textfieldportnumber.setEditable(false);
textfieldusername.removeActionListener(this);
connected = false;
}
//
public void actionPerformed(ActionEvent e) {
Object button = e.getSource();
if(button == btnlogout) {
Controller.sendMessage(new Message("", Message.LOGOUT)); //Ändra till Chatmessage klass
btnlogin.setText("Login");
return;
}
if(button == btnonline) {
Controller.sendMessage(new Message("", Message.ONLINE)); //Ändra till Chatmessage klass
return;
}
if(connected) {
Controller.sendMessage(new Message(textfieldusername.getText(), Message.MESSAGE)); //Ändra till Chatmessage klass
textfieldusername.setText("");
return;
}
if(button == btnlogin) {
String username = textfieldusername.getText();
if(username.length() == 0)
return;
String server = textfieldserver.getText();
if(server.length() == 0)
return;
String portNumber = textfieldportnumber.getText();
if(portNumber.length() == 0)
return;
int port = 0;
try {
port = Integer.parseInt(portNumber);
}
catch(Exception en) {
return;
}
client = new Client(server, username, port, this);
if(!Controller.startClient())
return;
}
connected = true;
textfieldusername.setText("");
btnlogin.setText("Send message");
btnlogin.setEnabled(true);
btnlogout.setEnabled(true);
btnonline.setEnabled(true);
textfieldserver.setEditable(false);
textfieldportnumber.setEditable(false);
textfieldusername.addActionListener(this);
}
// to start the whole thing the server
public static void main(String[] args) {
new ClientGUI("localhost", 1500);
}
}
答案 0 :(得分:0)
看看这个嵌套类。如果嵌套的内部类不是静态,则它可以访问外部对象及其字段。这里的内部类有一个Outer.this
。对于new Inner()
的分配,必须提供外部对象:outer.new Inner()
。通常,人们可能首先尝试使内部类静态,以查看是否需要外部类。
class Outer {
String s;
void p() {
StaticInner x = new StaticInner();
Inner y = this.new Inner();
}
static class StaticInner {
void f() {
// CANNOT use field s.
}
}
class Inner {
int n;
void g() {
n;
this.n;
this;
Outer.this;
Outer.this.s;
s;
}
}
}
最简单的方法是让你的内心阶级静止。"
public static class ListenFromServer extends Thread{
一般情况下,会删除所有static
并仅创建一个Controller对象。这节省了打字。