Mam probrlem z programem. Nie do konca znam Javę, muszę z niej korzystać ze względu na wymagania przedmiotowe.
Do napisania miałem klient czata i server, na którym ten czat stoi. Serwer mam napisany - działa idealnie.
Z klientem mam jeden problem: w TextArea, w którym wyświetla się tekst rozmów nie mam suwaka i opcji, która pozwoli na automatyczne przesuwanie tekstu do dołu (tak jak np. w GG).
Proszę o pomoc. Czytałem wiele przykładów i nic nie pomogło.
Kod Klienta czata:
// $Id$
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import java.util.*;
public class CzatKlient extends JFrame
{
// Components for the visual display of the chat windows
private JTextField wiadomosc = new JTextField();
private JTextArea tekst = new JTextArea();
private JTextField adres = new JTextField();
private JTextField adresportu = new JTextField();
// The socket connecting us to the server
private static Socket socket;
// The streams we communicate to the server; these come
// from the socket
private static DataOutputStream dout;
private static DataInputStream din;
String host;
int port;
static int znak=0;
static String napis="Połącz";
static String nick;
void DemoButton_actionPerformed(ActionEvent e) {
processMessage(wiadomosc.getText());
wiadomosc.setText( "" );
}
private static void processMessage( String message )
{
try {
message= nick +": " + message;
dout.writeUTF( message );
}
catch( IOException ie ) { System.out.println( ie ); }
}
public static void main(String[] args)
{
JFrame frame = new JFrame("Czat");
frame.setSize(400,600);
JLabel label1 = new JLabel();
label1.setBounds(10, 10, 300, 20);
label1.setText("Wpisz adres serwera:");
JTextField portu = new JTextField();
portu.setBounds(235,10,40,20);
portu.setText("1234");
JTextField adres = new JTextField();
adres.setBounds(150,10,80,20);
adres.setText("127.0.0.1");
final JButton przycisk = new JButton();
przycisk.setBounds(280,10,80,20);
przycisk.setText(napis);
JTextArea tekst = new JTextArea(380,480);
tekst.setBounds(10, 55, 380, 480);
tekst.setEditable(false);
tekst.setAutoscrolls(true);
tekst.setLineWrap(true);
tekst.setWrapStyleWord(true);
tekst.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
JTextField polenick = new JTextField();
polenick.setBounds(15,33,80,20);
polenick.setText("nick");
final JTextField wiadomosc = new JTextField();
wiadomosc.setBounds(10, 540, 380, 20);
Container ct = frame.getContentPane();
ct.setLayout(null);
ct.add(label1);
ct.add(portu);
ct.add(adres);
ct.add(przycisk);
ct.add(tekst);
ct.add(polenick);
ct.add(wiadomosc);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
wiadomosc.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { processMessage(e.getActionCommand()); wiadomosc.setText(""); } } );
przycisk.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e )
{
if (znak==0)
{
znak=1;
}
else
{
znak=0;
try {
napis="Połącz";
przycisk.setText(napis);
socket.close();
}
catch (IOException e1) {
e1.printStackTrace();
}} } } );
while(true)
{
if (znak==1)
{
String host=adres.getText();
int port=Integer.parseInt(portu.getText());
nick=polenick.getText();
try
{
napis="Rozłącz";
przycisk.setText(napis);
socket = new Socket( host, port );
System.out.println( "connected to "+socket );
din = new DataInputStream( socket.getInputStream() );
dout = new DataOutputStream( socket.getOutputStream() );
//new Thread().start();
}
catch( IOException ie ) { System.out.println( ie ); }
try
{
while (true)
{
String message = din.readUTF();
tekst.append( message+"\n" );
}
}
catch( IOException ie ) { System.out.println( ie );
}
} //koniec ifa
} //koniec while'a
}
} //koniec klasy
Kod serwera (musi być wywoływany z terminala - pierwszy argument: port na którym ma stać serwer, np. java Server 1234)
// $Id$
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.net.*;
import java.util.*;
public class Server
{
// The ServerSocket we'll use for accepting new connections
private ServerSocket ss;
// A mapping from sockets to DataOutputStreams. This will
// help us avoid having to create a DataOutputStream each time
// we want to write to a stream.
private Hashtable outputStreams = new Hashtable();
// Constructor and while-accept loop all in one.
public Server( int port ) throws IOException {
// All we have to do is listen
listen( port );
}
private void listen( int port ) throws IOException {
// Create the ServerSocket
ss = new ServerSocket( port );
// Tell the world we're ready to go
System.out.println( "Listening on "+ss );
// Keep accepting connections forever
while (true) {
// Grab the next incoming connection
Socket s = ss.accept();
// Tell the world we've got it
System.out.println( "Connection from "+s );
// Create a DataOutputStream for writing data to the
// other side
DataOutputStream dout = new DataOutputStream( s.getOutputStream() );
// Save this stream so we don't need to make it again
outputStreams.put( s, dout );
// Create a new thread for this connection, and then forget
// about it
new ServerThread( this, s );
}
}
// Get an enumeration of all the OutputStreams, one for each client
// connected to us
Enumeration getOutputStreams() {
return outputStreams.elements();
}
// Send a message to all clients (utility routine)
void sendToAll( String message ) {
// We synchronize on this because another thread might be
// calling removeConnection() and this would screw us up
// as we tried to walk through the list
synchronized( outputStreams ) {
// For each client ...
for (Enumeration e = getOutputStreams(); e.hasMoreElements(); ) {
// ... get the output stream ...
DataOutputStream dout = (DataOutputStream)e.nextElement();
// ... and send the message
try {
String dopliku=message+"\n";
dout.writeUTF( message );
FileChannel fc= new RandomAccessFile("logi.txt","rw").getChannel();
fc.position(fc.size());
fc.write(ByteBuffer.wrap(dopliku.getBytes()));
fc.close();
} catch( IOException ie ) { System.out.println( ie ); }
}
}
}
// Remove a socket, and it's corresponding output stream, from our
// list. This is usually called by a connection thread that has
// discovered that the connectin to the client is dead.
void removeConnection( Socket s ) {
// Synchronize so we don't mess up sendToAll() while it walks
// down the list of all output streamsa
synchronized( outputStreams ) {
// Tell the world
System.out.println( "Removing connection to "+s );
// Remove it from our hashtable/list
outputStreams.remove( s );
// Make sure it's closed
try {
s.close();
} catch( IOException ie ) {
System.out.println( "Error closing "+s );
ie.printStackTrace();
}
}
}
// Main routine
// Usage: java Server <port>
static public void main( String args[] ) throws Exception {
// Get the port # from the command line
int port = Integer.parseInt( args[0] );
// Create a Server object, which will automatically begin
// accepting connections.
new Server( port );
}
}
Do uruchmienia serwera jest porzebna klasa ServerThread:
// $Id$
import java.io.*;
import java.net.*;
public class ServerThread extends Thread
{
// The Server that spawned us
private Server server;
// The Socket connected to our client
private Socket socket;
// Constructor.
public ServerThread( Server server, Socket socket ) {
// Save the parameters
this.server = server;
this.socket = socket;
// Start up the thread
start();
}
// This runs in a separate thread when start() is called in the
// constructor.
public void run() {
try {
// Create a DataInputStream for communication; the client
// is using a DataOutputStream to write to us
DataInputStream din = new DataInputStream( socket.getInputStream() );
// Over and over, forever ...
while (true) {
// ... read the next message ...
String message = din.readUTF();
// ... tell the world ...
System.out.println( "Sending "+message );
// ... and have the server send it to all clients
server.sendToAll( message );
}
} catch( EOFException ie ) {
// This doesn't need an error message
} catch( IOException ie ) {
// This does; tell the world!
ie.printStackTrace();
} finally {
// The connection is closed for one reason or another,
// so have the server dealing with it
server.removeConnection( socket );
}
}
}