full final grafikchat, bääm, geht voll ab xD
This commit is contained in:
commit
3a4b3b4f07
44
src/grafikchat/Start.java
Normal file
44
src/grafikchat/Start.java
Normal file
@ -0,0 +1,44 @@
|
||||
package grafikchat;
|
||||
|
||||
import grafikchat.controller.ConnectController;
|
||||
import grafikchat.controller.GrafikController;
|
||||
import grafikchat.controller.ReceiveAdapter;
|
||||
import grafikchat.model.ChatModel;
|
||||
import grafikchat.view.ChatView;
|
||||
|
||||
/**
|
||||
* Start class, start chat application
|
||||
*
|
||||
* @author marian
|
||||
*/
|
||||
public class Start {
|
||||
|
||||
public Start()
|
||||
{
|
||||
ChatView view = new ChatView();
|
||||
ChatModel model = new ChatModel();
|
||||
|
||||
view.getGvDrawPane().setModel(model);
|
||||
|
||||
ConnectController controllerConnect = new ConnectController(model, view);
|
||||
controllerConnect.registerEvents();
|
||||
|
||||
GrafikController controller = new GrafikController(view, model);
|
||||
controller.registerEvents();
|
||||
|
||||
ReceiveAdapter rxAdapter = new ReceiveAdapter(view);
|
||||
model.addObserver(rxAdapter);
|
||||
|
||||
view.setTitle("Chat");
|
||||
view.setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param args the command line arguments
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Start start = new Start();
|
||||
}
|
||||
|
||||
}
|
113
src/grafikchat/controller/ConnectController.java
Normal file
113
src/grafikchat/controller/ConnectController.java
Normal file
@ -0,0 +1,113 @@
|
||||
package grafikchat.controller;
|
||||
|
||||
import grafikchat.model.ChatModel;
|
||||
import grafikchat.ohmlogger.OhmLogger;
|
||||
import grafikchat.view.ChatView;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
/**
|
||||
* Handle events emitted from connect button
|
||||
*
|
||||
* @author marian
|
||||
*/
|
||||
public class ConnectController implements ActionListener
|
||||
{
|
||||
private ChatModel model;
|
||||
private ChatView view;
|
||||
private static Logger logger = OhmLogger.getLogger();
|
||||
|
||||
/**
|
||||
* Constructor, initialize variables
|
||||
* @param model ChatModel
|
||||
* @param view ChatView
|
||||
*/
|
||||
public ConnectController(ChatModel model, ChatView view)
|
||||
{
|
||||
this.model = model;
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register events for connect button and radio button to select between server and client mode.
|
||||
*/
|
||||
public void registerEvents()
|
||||
{
|
||||
this.view.getBtConnect().addActionListener(this);
|
||||
this.view.getRbClient().addActionListener(this);
|
||||
this.view.getRbServer().addActionListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler to take care of registered events
|
||||
* @param ae occurred event
|
||||
*/
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent ae)
|
||||
{
|
||||
Object object = ae.getSource();
|
||||
|
||||
if (object == view.getBtConnect()) {
|
||||
int port = -1;
|
||||
|
||||
try {
|
||||
port = Integer.parseInt(view.getTfPort().getText());
|
||||
} catch (NumberFormatException e) {
|
||||
JOptionPane.showMessageDialog(view, "Port entspricht keiner Zahl!");
|
||||
logger.severe(e.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (view.getRbClient().isSelected() && (validIP(view.getTfIP().getText()) == false)) {
|
||||
JOptionPane.showMessageDialog(view, "Ungültige IP-Adresse!");
|
||||
logger.severe("IP-Adresse ungültig");
|
||||
return;
|
||||
}
|
||||
|
||||
model.connectToPeer(view.getRbServer().isSelected(), view.getTfIP().getText(), port);
|
||||
|
||||
view.getRbClient().setEnabled(false);
|
||||
view.getRbServer().setEnabled(false);
|
||||
view.getTfIP().setEnabled(false);
|
||||
view.getTfPort().setEnabled(false);
|
||||
} else {
|
||||
view.getTfIP().setEnabled(view.getRbClient().isSelected());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Primitive check if the ip is valid (only IPv4)
|
||||
* @param ip IP to check
|
||||
* @return true if valid, false otherwise
|
||||
*/
|
||||
private boolean validIP (String ip) {
|
||||
try {
|
||||
if ( ip == null || ip.isEmpty() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String[] parts = ip.split( "\\." );
|
||||
if ( parts.length != 4 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for ( String s : parts ) {
|
||||
int i = Integer.parseInt( s );
|
||||
if ( (i < 0) || (i > 255) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( ip.endsWith(".") ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (NumberFormatException e) {
|
||||
logger.severe(e.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
230
src/grafikchat/controller/GrafikController.java
Normal file
230
src/grafikchat/controller/GrafikController.java
Normal file
@ -0,0 +1,230 @@
|
||||
package grafikchat.controller;
|
||||
|
||||
import grafikchat.model.ChatModel;
|
||||
import grafikchat.view.ChatView;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JOptionPane;
|
||||
import grafikchat.model.Figures;
|
||||
import grafikchat.model.TransceiverData;
|
||||
import grafikchat.model.TransceiverDataEvent;
|
||||
import grafikchat.ohmlogger.OhmLogger;
|
||||
|
||||
/**
|
||||
* Handle events from mouse and keyboard
|
||||
*
|
||||
* @author marian
|
||||
*/
|
||||
public class GrafikController implements MouseMotionListener, MouseListener, KeyListener
|
||||
{
|
||||
private final ChatView view;
|
||||
private final ChatModel model;
|
||||
private boolean clicked;
|
||||
private final static Logger logger = OhmLogger.getLogger();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param view UI of zeichenprogramm
|
||||
* @param model Model of zeichenprogramm
|
||||
*/
|
||||
public GrafikController(ChatView view, ChatModel model)
|
||||
{
|
||||
this.view = view;
|
||||
this.model = model;
|
||||
|
||||
this.clicked = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register events for mouse and keyboard
|
||||
*/
|
||||
public void registerEvents()
|
||||
{
|
||||
view.getGvDrawPane().addMouseMotionListener(this);
|
||||
view.getGvDrawPane().addMouseListener(this);
|
||||
view.getGvDrawPane().addKeyListener(this);
|
||||
view.getGvDrawPane().setFocusable(true);
|
||||
|
||||
view.addKeyListener(this);
|
||||
view.setFocusable(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent evt)
|
||||
{
|
||||
if (clicked) {
|
||||
Point p = evt.getPoint();
|
||||
model.getIntern().addPoint(p);
|
||||
model.sendMessage(new TransceiverData(TransceiverDataEvent.NEWPOINT, p));
|
||||
view.getGvDrawPane().drawPoint(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e)
|
||||
{
|
||||
if (e.getButton() == MouseEvent.BUTTON1) {
|
||||
logger.info("Mouse pressed");
|
||||
model.getIntern().newFigure();
|
||||
model.sendMessage(new TransceiverData(TransceiverDataEvent.NEWFIGURE, null));
|
||||
this.clicked = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e)
|
||||
{
|
||||
if (e.getButton() == MouseEvent.BUTTON1) {
|
||||
logger.info("Mouse released");
|
||||
this.clicked = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {}
|
||||
|
||||
/**
|
||||
* Save current graphics to file
|
||||
* @return True if successful, false otherwise
|
||||
*/
|
||||
public boolean saveToFile()
|
||||
{
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setCurrentDirectory(new File(model.getFilename()));
|
||||
int returnVal = fc.showSaveDialog(view);
|
||||
|
||||
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||
File f = fc.getSelectedFile();
|
||||
if(!f.exists()) {
|
||||
try {
|
||||
f.createNewFile();
|
||||
} catch (IOException e) {
|
||||
JOptionPane.showMessageDialog(view, "Datei konnte nicht erstellt werden.", "Warnung", JOptionPane.WARNING_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(view, "Es wurde keine Datei zum speichern ausgewählt.", "Warnung", JOptionPane.WARNING_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
model.setFilename(fc.getSelectedFile().getPath());
|
||||
|
||||
|
||||
try {
|
||||
FileOutputStream fos = new FileOutputStream(model.getFilename());
|
||||
try (ObjectOutputStream oos = new ObjectOutputStream(fos)) {
|
||||
ArrayList<Figures> list = new ArrayList<>();
|
||||
list.add(model.getIntern());
|
||||
list.add(model.getExtern());
|
||||
oos.writeObject(list);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
JOptionPane.showMessageDialog(view, "Grafik konnte nicht gespeichert werden.", "Warning", JOptionPane.WARNING_MESSAGE);
|
||||
}
|
||||
|
||||
JOptionPane.showMessageDialog(view, "Grafik erfolgreich gespeichert.", "Information", JOptionPane.INFORMATION_MESSAGE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read graphics from file
|
||||
* @return True if successful, false otherwise
|
||||
*/
|
||||
public boolean readFromFile()
|
||||
{
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setCurrentDirectory(new File(model.getFilename()));
|
||||
int returnVal = fc.showOpenDialog(view);
|
||||
|
||||
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||
File f = fc.getSelectedFile();
|
||||
if(!f.exists()) {
|
||||
try {
|
||||
f.createNewFile();
|
||||
} catch (IOException e) {
|
||||
JOptionPane.showMessageDialog(view, "Datei konnte nicht erstellt werden.", "Warnung", JOptionPane.WARNING_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
String filepath = f.getPath();
|
||||
ArrayList<Figures> d;
|
||||
FileInputStream is;
|
||||
|
||||
try {
|
||||
is = new FileInputStream(filepath);
|
||||
} catch (IOException e) {
|
||||
JOptionPane.showMessageDialog(view, "Datei wurde nicht gefunden.", "Warnung", JOptionPane.WARNING_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
ObjectInputStream ois = new ObjectInputStream(is);
|
||||
d = (ArrayList<Figures>)ois.readObject();
|
||||
model.getIntern().setFigures(d.get(0).getFigures());
|
||||
model.getExtern().setFigures(d.get(1).getFigures());
|
||||
view.repaint();
|
||||
model.sendMessage(new TransceiverData(TransceiverDataEvent.REPAINT, d));
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
JOptionPane.showMessageDialog(view, "Leeres Adressbuch geöffnet.", "Warnung", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
|
||||
model.setFilename(filepath);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent ke)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent ke)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent ke)
|
||||
{
|
||||
char c = ke.getKeyChar();
|
||||
switch (c)
|
||||
{
|
||||
case 's':
|
||||
saveToFile();
|
||||
break;
|
||||
case 'o':
|
||||
readFromFile();
|
||||
break;
|
||||
case 'p':
|
||||
view.getGvDrawPane().doPrint();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
48
src/grafikchat/controller/ReceiveAdapter.java
Normal file
48
src/grafikchat/controller/ReceiveAdapter.java
Normal file
@ -0,0 +1,48 @@
|
||||
package grafikchat.controller;
|
||||
|
||||
import grafikchat.model.ChatModel;
|
||||
import grafikchat.model.TransceiverDataEvent;
|
||||
import grafikchat.view.ChatView;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
|
||||
/**
|
||||
* Take care of received messages. Show to user in UI
|
||||
*
|
||||
* @author marian
|
||||
*/
|
||||
public class ReceiveAdapter implements Observer
|
||||
{
|
||||
private ChatView view;
|
||||
|
||||
/**
|
||||
* Constructor, get reference to view
|
||||
* @param view ChatView
|
||||
*/
|
||||
public ReceiveAdapter(ChatView view)
|
||||
{
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Incoming information from Observable
|
||||
* @param obs Observable
|
||||
* @param object Received message
|
||||
*/
|
||||
@Override
|
||||
public void update(Observable obs, Object object)
|
||||
{
|
||||
TransceiverDataEvent mode = (TransceiverDataEvent)object;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case NEWPOINT:
|
||||
view.getGvDrawPane().drawPoint(false);
|
||||
break;
|
||||
case REPAINT:
|
||||
view.getGvDrawPane().repaint();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
159
src/grafikchat/model/ChatModel.java
Normal file
159
src/grafikchat/model/ChatModel.java
Normal file
@ -0,0 +1,159 @@
|
||||
package grafikchat.model;
|
||||
|
||||
import grafikchat.ohmlogger.OhmLogger;
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
/**
|
||||
* Model of chat application. Handle communication
|
||||
*
|
||||
* @author marian
|
||||
*/
|
||||
public class ChatModel extends Observable implements Observer
|
||||
{
|
||||
private boolean connected;
|
||||
private boolean mode;
|
||||
private boolean initialized;
|
||||
private Transceiver trx;
|
||||
private Figures intern;
|
||||
private Figures extern;
|
||||
|
||||
private final Preferences prefs;
|
||||
private static Logger logger = OhmLogger.getLogger();
|
||||
|
||||
/**
|
||||
* Constructor, initialize variables
|
||||
*/
|
||||
public ChatModel()
|
||||
{
|
||||
connected = false;
|
||||
mode = false;
|
||||
initialized = false;
|
||||
trx = null;
|
||||
|
||||
intern = new Figures();
|
||||
extern = new Figures();
|
||||
|
||||
prefs = Preferences.userNodeForPackage(this.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get local drawn figure
|
||||
* @return internal figure
|
||||
*/
|
||||
public Figures getIntern()
|
||||
{
|
||||
return intern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get remote drawn figure
|
||||
* @return extern figure
|
||||
*/
|
||||
public Figures getExtern()
|
||||
{
|
||||
return extern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new filename in preferences
|
||||
* @param f
|
||||
*/
|
||||
public void setFilename(String f)
|
||||
{
|
||||
prefs.put("LAST_FILE", f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get latest filename from preferences
|
||||
* @return filename
|
||||
*/
|
||||
public String getFilename()
|
||||
{
|
||||
String last = prefs.get("LAST_FILE", "");
|
||||
System.out.println(last);
|
||||
return last;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to peer
|
||||
* @param mode true to use server mode, false to use client mode
|
||||
* @param ip IP to connect to (not relevant in server mode)
|
||||
* @param port Port to open or connect to (depending on selected mode)
|
||||
*/
|
||||
public void connectToPeer(boolean mode, String ip, int port)
|
||||
{
|
||||
if (initialized) {
|
||||
logger.info("Chat already running");
|
||||
return;
|
||||
}
|
||||
|
||||
this.mode = mode;
|
||||
|
||||
if (mode) {
|
||||
logger.info("Running in server mode");
|
||||
trx = new Server(port);
|
||||
} else {
|
||||
logger.info("Running in client mode");
|
||||
trx = new Client(ip, port);
|
||||
}
|
||||
|
||||
trx.registerObserver(this);
|
||||
trx.init();
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send message to peer
|
||||
* @param d TransceiverData to transmit
|
||||
*/
|
||||
public void sendMessage(TransceiverData d)
|
||||
{
|
||||
if (!initialized) {
|
||||
logger.warning("Chat not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
trx.sendMessage(d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get received data from network
|
||||
* @param obs Observable
|
||||
* @param object Received object
|
||||
*/
|
||||
@Override
|
||||
public void update(Observable obs, Object object)
|
||||
{
|
||||
TransceiverData d = (TransceiverData)object;
|
||||
|
||||
if (object instanceof TransceiverData) {
|
||||
switch (d.getEvent())
|
||||
{
|
||||
case NEWFIGURE:
|
||||
extern.newFigure();
|
||||
break;
|
||||
case NEWPOINT:
|
||||
extern.addPoint((Point)d.getObject());
|
||||
this.setChanged();
|
||||
this.notifyObservers(TransceiverDataEvent.NEWPOINT);
|
||||
break;
|
||||
case REPAINT:
|
||||
ArrayList<Figures> fig = (ArrayList<Figures>)d.getObject();
|
||||
intern.setFigures(fig.get(0).getFigures());
|
||||
extern.setFigures(fig.get(1).getFigures());
|
||||
this.setChanged();
|
||||
this.notifyObservers(TransceiverDataEvent.REPAINT);
|
||||
default:
|
||||
logger.warning("Unknown TransceiverDataEvent");
|
||||
}
|
||||
} else {
|
||||
logger.warning("Received invalid object");
|
||||
}
|
||||
}
|
||||
}
|
148
src/grafikchat/model/Client.java
Normal file
148
src/grafikchat/model/Client.java
Normal file
@ -0,0 +1,148 @@
|
||||
package grafikchat.model;
|
||||
|
||||
import grafikchat.ohmlogger.OhmLogger;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.net.Socket;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* TCP Client
|
||||
*
|
||||
* @author marian
|
||||
*/
|
||||
public class Client extends Observable implements Runnable, Transceiver
|
||||
{
|
||||
private Socket socket;
|
||||
private ObjectInputStream reader;
|
||||
private ObjectOutputStream writer;
|
||||
private boolean ready;
|
||||
private Thread thd;
|
||||
private String ip;
|
||||
private int port;
|
||||
private static Logger logger = OhmLogger.getLogger();
|
||||
|
||||
/**
|
||||
* Constructor, initialize variables
|
||||
* @param ip IP to connect to
|
||||
* @param port Port of remote server
|
||||
*/
|
||||
public Client(String ip, int port)
|
||||
{
|
||||
this.ip = ip;
|
||||
this.port = port;
|
||||
this.socket = null;
|
||||
this.reader = null;
|
||||
this.writer = null;
|
||||
this.ready = false;
|
||||
this.thd = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init client thread, if not already done
|
||||
*/
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
if (thd == null) {
|
||||
thd = new Thread(this);
|
||||
thd.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observer to client
|
||||
* @param o Observer to add
|
||||
*/
|
||||
@Override
|
||||
public void registerObserver(Observer o)
|
||||
{
|
||||
this.addObserver(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the client in thread.
|
||||
*/
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
logger.info("Running client...");
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (socket == null) {
|
||||
try {
|
||||
socket = new Socket(ip, port);
|
||||
logger.info("Connected to server");
|
||||
} catch (IOException e) {
|
||||
logger.severe(e.getMessage());
|
||||
socket = null;
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
reader = new ObjectInputStream(socket.getInputStream());
|
||||
} catch (IOException e) {
|
||||
logger.severe(e.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
writer = new ObjectOutputStream(socket.getOutputStream());
|
||||
} catch (IOException e) {
|
||||
logger.severe(e.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
ready = true;
|
||||
}
|
||||
|
||||
if (ready) {
|
||||
try {
|
||||
//logger.info("Waiting for message");
|
||||
|
||||
Object o = reader.readObject();
|
||||
|
||||
if (o == null) {
|
||||
logger.warning("Reached end of stream");
|
||||
ready = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
this.setChanged();
|
||||
this.notifyObservers(o);
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
logger.severe(e.toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send message to server
|
||||
* @param d TransceiverData to transmit
|
||||
*/
|
||||
@Override
|
||||
public void sendMessage(TransceiverData d)
|
||||
{
|
||||
if (ready) {
|
||||
try {
|
||||
writer.writeObject(d);
|
||||
} catch (IOException e) {
|
||||
logger.severe(e.toString());
|
||||
}
|
||||
} else {
|
||||
logger.warning("Server not ready to send message. Connect first");
|
||||
}
|
||||
}
|
||||
}
|
43
src/grafikchat/model/Figure.java
Normal file
43
src/grafikchat/model/Figure.java
Normal file
@ -0,0 +1,43 @@
|
||||
package grafikchat.model;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Figure drawn by user with mouse
|
||||
*
|
||||
* @author marian
|
||||
*/
|
||||
public class Figure implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 8582433437601788991L;
|
||||
private final ArrayList<Point> points;
|
||||
|
||||
/**
|
||||
* Constructor, initialize figure
|
||||
*/
|
||||
public Figure()
|
||||
{
|
||||
points = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add point to figure
|
||||
* @param p new point
|
||||
*/
|
||||
public void addPoint(Point p)
|
||||
{
|
||||
points.add(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all points of figure
|
||||
* @return all points
|
||||
*/
|
||||
public List<Point> getPoints()
|
||||
{
|
||||
return points;
|
||||
}
|
||||
}
|
107
src/grafikchat/model/Figures.java
Normal file
107
src/grafikchat/model/Figures.java
Normal file
@ -0,0 +1,107 @@
|
||||
package grafikchat.model;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Implementation of a list of figures
|
||||
*
|
||||
* @author marian
|
||||
*/
|
||||
public class Figures implements Serializable
|
||||
{
|
||||
private ArrayList<Figure> figureList;
|
||||
private Figure lastFigure;
|
||||
private Point lastPoint;
|
||||
private Point secondToLastPoint;
|
||||
private static final long serialVersionUID = 8582433437601788990L;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor, initialize variables
|
||||
*/
|
||||
public Figures()
|
||||
{
|
||||
figureList = new ArrayList<>();
|
||||
lastFigure = null;
|
||||
lastPoint = null;
|
||||
secondToLastPoint = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add point to latest figure
|
||||
* @param p new point to add
|
||||
*/
|
||||
public void addPoint(Point p)
|
||||
{
|
||||
lastFigure.addPoint(p);
|
||||
secondToLastPoint = lastPoint;
|
||||
lastPoint = p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new figure
|
||||
*/
|
||||
public void newFigure()
|
||||
{
|
||||
Figure f = new Figure();
|
||||
figureList.add(f);
|
||||
lastFigure = f;
|
||||
|
||||
lastPoint = null;
|
||||
secondToLastPoint = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last two points of the latest figure
|
||||
* @return last two points of latest figure
|
||||
* @throws Exception if not yet available
|
||||
*/
|
||||
public List<Point> getLastTwoPoints() throws Exception
|
||||
{
|
||||
if (secondToLastPoint == null || lastPoint == null) {
|
||||
throw new Exception("Not enough points available");
|
||||
}
|
||||
|
||||
ArrayList<Point> p = new ArrayList<>();
|
||||
p.add(lastPoint);
|
||||
p.add(secondToLastPoint);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get latest figure
|
||||
* @return latest figure
|
||||
* @throws Exception if not yet available
|
||||
*/
|
||||
private List<Point> getFigure() throws Exception
|
||||
{
|
||||
if (lastFigure == null) {
|
||||
throw new Exception("No figure available");
|
||||
}
|
||||
|
||||
return lastFigure.getPoints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new figures
|
||||
* @param f
|
||||
*/
|
||||
public void setFigures(ArrayList<Figure> f)
|
||||
{
|
||||
figureList = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all current figures
|
||||
* @return
|
||||
*/
|
||||
public ArrayList<Figure> getFigures()
|
||||
{
|
||||
return figureList;
|
||||
}
|
||||
|
||||
}
|
151
src/grafikchat/model/Server.java
Normal file
151
src/grafikchat/model/Server.java
Normal file
@ -0,0 +1,151 @@
|
||||
package grafikchat.model;
|
||||
|
||||
import grafikchat.ohmlogger.OhmLogger;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* TCP Server
|
||||
*
|
||||
* @author marian
|
||||
*/
|
||||
public class Server extends Observable implements Runnable, Transceiver
|
||||
{
|
||||
private int port;
|
||||
private ServerSocket server;
|
||||
private Socket client;
|
||||
private static Logger logger = OhmLogger.getLogger();
|
||||
private ObjectInputStream reader;
|
||||
private ObjectOutputStream writer;
|
||||
private volatile boolean ready;
|
||||
private Thread thd;
|
||||
|
||||
/**
|
||||
* Constructor, initialize variables
|
||||
* @param port Port to listen on
|
||||
*/
|
||||
public Server(int port)
|
||||
{
|
||||
this.port = port;
|
||||
this.server = null;
|
||||
this.client = null;
|
||||
this.reader = null;
|
||||
this.writer = null;
|
||||
this.ready = false;
|
||||
this.thd = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init server if not already done
|
||||
*/
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
if (thd == null) {
|
||||
thd = new Thread(this);
|
||||
thd.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add observer to server
|
||||
* @param o Observer to add
|
||||
*/
|
||||
@Override
|
||||
public void registerObserver(Observer o)
|
||||
{
|
||||
this.addObserver(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run server in thread
|
||||
*/
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
logger.info("Running server...");
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (server == null) {
|
||||
try {
|
||||
server = new ServerSocket(port);
|
||||
} catch (IOException e) {
|
||||
logger.severe(e.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info("Waiting for client to connect");
|
||||
try {
|
||||
client = server.accept();
|
||||
} catch (IOException e) {
|
||||
logger.severe(e.toString());
|
||||
return;
|
||||
}
|
||||
logger.info("Client connected");
|
||||
|
||||
try {
|
||||
writer = new ObjectOutputStream(client.getOutputStream());
|
||||
} catch (IOException e) {
|
||||
logger.severe(e.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
reader = new ObjectInputStream(client.getInputStream());
|
||||
} catch (IOException e) {
|
||||
logger.severe(e.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
ready = true;
|
||||
|
||||
}
|
||||
|
||||
if (ready) {
|
||||
try {
|
||||
//logger.info("Waiting for message");
|
||||
|
||||
Object o = reader.readObject();
|
||||
|
||||
if (o == null) {
|
||||
logger.warning("Reached end of stream");
|
||||
ready = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
this.setChanged();
|
||||
this.notifyObservers(o);
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
logger.severe(e.toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send message to client
|
||||
* @param d TransceiverData to transmit
|
||||
*/
|
||||
@Override
|
||||
public void sendMessage(TransceiverData d)
|
||||
{
|
||||
if (ready) {
|
||||
try {
|
||||
writer.writeObject(d);
|
||||
} catch (IOException e) {
|
||||
logger.severe(e.toString());
|
||||
}
|
||||
} else {
|
||||
logger.warning("Server not ready to send message. Connect first");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
28
src/grafikchat/model/Transceiver.java
Normal file
28
src/grafikchat/model/Transceiver.java
Normal file
@ -0,0 +1,28 @@
|
||||
package grafikchat.model;
|
||||
|
||||
import java.util.Observer;
|
||||
|
||||
/**
|
||||
* Interface for server and client
|
||||
*
|
||||
* @author marian
|
||||
*/
|
||||
public interface Transceiver
|
||||
{
|
||||
/**
|
||||
* Initialize the transceiver
|
||||
*/
|
||||
public void init();
|
||||
|
||||
/**
|
||||
* Send object
|
||||
* @param d TransceiverData to send
|
||||
*/
|
||||
public void sendMessage(TransceiverData d);
|
||||
|
||||
/**
|
||||
* Register on transceiver
|
||||
* @param o Object to register
|
||||
*/
|
||||
public void registerObserver(Observer o);
|
||||
}
|
31
src/grafikchat/model/TransceiverData.java
Normal file
31
src/grafikchat/model/TransceiverData.java
Normal file
@ -0,0 +1,31 @@
|
||||
package grafikchat.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* DataPoint for communication between two sockets
|
||||
*
|
||||
* @author marian
|
||||
*/
|
||||
public class TransceiverData implements Serializable
|
||||
{
|
||||
private final TransceiverDataEvent e;
|
||||
private final Object o;
|
||||
private static final long serialVersionUID = 8582433437601788989L;
|
||||
|
||||
public TransceiverData(TransceiverDataEvent e, Object o)
|
||||
{
|
||||
this.e = e;
|
||||
this.o = o;
|
||||
}
|
||||
|
||||
public TransceiverDataEvent getEvent()
|
||||
{
|
||||
return this.e;
|
||||
}
|
||||
|
||||
public Object getObject()
|
||||
{
|
||||
return this.o;
|
||||
}
|
||||
}
|
10
src/grafikchat/model/TransceiverDataEvent.java
Normal file
10
src/grafikchat/model/TransceiverDataEvent.java
Normal file
@ -0,0 +1,10 @@
|
||||
package grafikchat.model;
|
||||
|
||||
|
||||
|
||||
public enum TransceiverDataEvent
|
||||
{
|
||||
NEWPOINT,
|
||||
NEWFIGURE,
|
||||
REPAINT;
|
||||
}
|
34
src/grafikchat/ohmlogger/OhmFormatter.java
Normal file
34
src/grafikchat/ohmlogger/OhmFormatter.java
Normal file
@ -0,0 +1,34 @@
|
||||
package grafikchat.ohmlogger;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.logging.*;
|
||||
|
||||
/**
|
||||
* Formatter with custom format
|
||||
*
|
||||
* @author marian
|
||||
*/
|
||||
class OhmFormatter extends SimpleFormatter {
|
||||
|
||||
private static final DateFormat df = new SimpleDateFormat("dd.MM.yyyy hh:mm:ss.SSS");
|
||||
|
||||
/**
|
||||
* Format message to specified format
|
||||
* @param record Tecord to format
|
||||
* @return Formatted string
|
||||
*/
|
||||
@Override
|
||||
public String format(LogRecord record) {
|
||||
StringBuilder builder;
|
||||
builder = new StringBuilder(1000);
|
||||
builder.append(df.format(new Date(record.getMillis()))).append(" | ");
|
||||
builder.append(record.getLevel()).append(" | ");
|
||||
builder.append(record.getSourceClassName()).append(" | ");
|
||||
builder.append(record.getSourceMethodName()).append(" | ");
|
||||
builder.append(formatMessage(record)).append(" |");
|
||||
builder.append("\n");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
44
src/grafikchat/ohmlogger/OhmLogger.java
Normal file
44
src/grafikchat/ohmlogger/OhmLogger.java
Normal file
@ -0,0 +1,44 @@
|
||||
package grafikchat.ohmlogger;
|
||||
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Logger with custom format
|
||||
*
|
||||
* @author marian
|
||||
*/
|
||||
public class OhmLogger
|
||||
{
|
||||
private static Logger lg;
|
||||
|
||||
/**
|
||||
* Get logger object
|
||||
*
|
||||
* @return logger object
|
||||
*/
|
||||
public static Logger getLogger()
|
||||
{
|
||||
if (lg == null) {
|
||||
lg = Logger.getLogger("OhmLogger");
|
||||
initLogger();
|
||||
}
|
||||
|
||||
return lg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize new logger and set custom formatter
|
||||
*/
|
||||
private static void initLogger()
|
||||
{
|
||||
ConsoleHandler ch = new ConsoleHandler();
|
||||
|
||||
ch.setFormatter(new OhmFormatter());
|
||||
lg.addHandler(ch);
|
||||
lg.setUseParentHandlers(false);
|
||||
lg.setLevel(Level.ALL);
|
||||
}
|
||||
|
||||
}
|
138
src/grafikchat/view/ChatView.form
Normal file
138
src/grafikchat/view/ChatView.form
Normal file
@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.ButtonGroup" name="bgSelect">
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="3"/>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="gvDrawPane" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="rbClient" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="215" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="jSeparator1" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="lbPort" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="tfPort" min="-2" pref="61" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="lbIP" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="tfIP" pref="164" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btConnect" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="rbServer" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="rbClient" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="rbServer" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="lbPort" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="tfPort" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="tfIP" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="lbIP" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btConnect" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jSeparator1" min="-2" pref="10" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="gvDrawPane" pref="205" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextField" name="tfPort">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="3210"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lbPort">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Port:"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lbIP">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="IP:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="tfIP">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="127.0.0.1"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btConnect">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="connect"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSeparator" name="jSeparator1">
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="rbClient">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="bgSelect"/>
|
||||
</Property>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" value="Client"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="rbServer">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="bgSelect"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="Server"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="grafikchat.view.GrafikView" name="gvDrawPane">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout">
|
||||
<Property name="useNullLayout" type="boolean" value="true"/>
|
||||
</Layout>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
218
src/grafikchat/view/ChatView.java
Normal file
218
src/grafikchat/view/ChatView.java
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package grafikchat.view;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author marian
|
||||
*/
|
||||
public class ChatView extends javax.swing.JFrame {
|
||||
|
||||
/**
|
||||
* @return the rbClient
|
||||
*/
|
||||
public javax.swing.JRadioButton getRbClient() {
|
||||
return rbClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the rbServer
|
||||
*/
|
||||
public javax.swing.JRadioButton getRbServer() {
|
||||
return rbServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the btConnect
|
||||
*/
|
||||
public javax.swing.JButton getBtConnect() {
|
||||
return btConnect;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the lbIP
|
||||
*/
|
||||
public javax.swing.JLabel getLbIP() {
|
||||
return lbIP;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the lbPort
|
||||
*/
|
||||
public javax.swing.JLabel getLbPort() {
|
||||
return lbPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the tfIP
|
||||
*/
|
||||
public javax.swing.JTextField getTfIP() {
|
||||
return tfIP;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the tfPort
|
||||
*/
|
||||
public javax.swing.JTextField getTfPort() {
|
||||
return tfPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new form ChatView
|
||||
*/
|
||||
public ChatView() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
bgSelect = new javax.swing.ButtonGroup();
|
||||
tfPort = new javax.swing.JTextField();
|
||||
lbPort = new javax.swing.JLabel();
|
||||
lbIP = new javax.swing.JLabel();
|
||||
tfIP = new javax.swing.JTextField();
|
||||
btConnect = new javax.swing.JButton();
|
||||
jSeparator1 = new javax.swing.JSeparator();
|
||||
rbClient = new javax.swing.JRadioButton();
|
||||
rbServer = new javax.swing.JRadioButton();
|
||||
gvDrawPane = new grafikchat.view.GrafikView();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
|
||||
|
||||
tfPort.setText("3210");
|
||||
tfPort.setToolTipText("");
|
||||
|
||||
lbPort.setText("Port:");
|
||||
lbPort.setToolTipText("");
|
||||
|
||||
lbIP.setText("IP:");
|
||||
|
||||
tfIP.setText("127.0.0.1");
|
||||
|
||||
btConnect.setText("connect");
|
||||
btConnect.setToolTipText("");
|
||||
|
||||
bgSelect.add(rbClient);
|
||||
rbClient.setSelected(true);
|
||||
rbClient.setText("Client");
|
||||
|
||||
bgSelect.add(rbServer);
|
||||
rbServer.setText("Server");
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(gvDrawPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(rbClient, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGap(215, 215, 215))
|
||||
.addComponent(jSeparator1)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(lbPort)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(tfPort, javax.swing.GroupLayout.PREFERRED_SIZE, 61, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(lbIP)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(tfIP, javax.swing.GroupLayout.DEFAULT_SIZE, 164, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btConnect))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(rbServer)
|
||||
.addGap(0, 0, Short.MAX_VALUE)))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(rbClient)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(rbServer)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(lbPort)
|
||||
.addComponent(tfPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(tfIP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lbIP)
|
||||
.addComponent(btConnect))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(gvDrawPane, javax.swing.GroupLayout.DEFAULT_SIZE, 205, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
/**
|
||||
* @param args the command line arguments
|
||||
*/
|
||||
public static void main(String args[]) {
|
||||
/* Set the Nimbus look and feel */
|
||||
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
|
||||
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
|
||||
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
|
||||
*/
|
||||
try {
|
||||
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
|
||||
if ("Nimbus".equals(info.getName())) {
|
||||
javax.swing.UIManager.setLookAndFeel(info.getClassName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFoundException ex) {
|
||||
java.util.logging.Logger.getLogger(ChatView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
|
||||
} catch (InstantiationException ex) {
|
||||
java.util.logging.Logger.getLogger(ChatView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
|
||||
} catch (IllegalAccessException ex) {
|
||||
java.util.logging.Logger.getLogger(ChatView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
|
||||
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
|
||||
java.util.logging.Logger.getLogger(ChatView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
/* Create and display the form */
|
||||
java.awt.EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
new ChatView().setVisible(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.ButtonGroup bgSelect;
|
||||
private javax.swing.JButton btConnect;
|
||||
private grafikchat.view.GrafikView gvDrawPane;
|
||||
private javax.swing.JSeparator jSeparator1;
|
||||
private javax.swing.JLabel lbIP;
|
||||
private javax.swing.JLabel lbPort;
|
||||
private javax.swing.JRadioButton rbClient;
|
||||
private javax.swing.JRadioButton rbServer;
|
||||
private javax.swing.JTextField tfIP;
|
||||
private javax.swing.JTextField tfPort;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
|
||||
/**
|
||||
* @return the gvDrawPane
|
||||
*/
|
||||
public grafikchat.view.GrafikView getGvDrawPane() {
|
||||
return gvDrawPane;
|
||||
}
|
||||
}
|
184
src/grafikchat/view/GrafikView.java
Normal file
184
src/grafikchat/view/GrafikView.java
Normal file
@ -0,0 +1,184 @@
|
||||
package grafikchat.view;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.print.PageFormat;
|
||||
import java.awt.print.Printable;
|
||||
import java.awt.print.PrinterException;
|
||||
import java.awt.print.PrinterJob;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
import javax.print.attribute.HashPrintRequestAttributeSet;
|
||||
import javax.print.attribute.standard.DialogTypeSelection;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JOptionPane;
|
||||
import grafikchat.model.Figure;
|
||||
import grafikchat.model.ChatModel;
|
||||
import grafikchat.model.Figures;
|
||||
import grafikchat.ohmlogger.OhmLogger;
|
||||
|
||||
/**
|
||||
* View of zeichenprogramm
|
||||
*
|
||||
* @author marian
|
||||
*/
|
||||
public class GrafikView extends JComponent implements Printable
|
||||
{
|
||||
private final static Logger lg = OhmLogger.getLogger();
|
||||
private Line2D.Double line;
|
||||
private ChatModel model;
|
||||
private final static Color colorInternal = Color.BLACK;
|
||||
private final static Color colorExternal = Color.RED;
|
||||
|
||||
/**
|
||||
* Constructor, initialize UI
|
||||
*/
|
||||
public GrafikView()
|
||||
{
|
||||
this.model = null;
|
||||
this.setBackground(Color.WHITE);
|
||||
line = new Line2D.Double();
|
||||
|
||||
lg.info("Call constructor of grafikview");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set model
|
||||
* @param model model of MVC
|
||||
*/
|
||||
public void setModel(ChatModel model)
|
||||
{
|
||||
this.model = model;
|
||||
lg.info("Set model of grafik view");
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw point (line with the point before)
|
||||
* @param mode True to draw internal point, false to draw external point
|
||||
*/
|
||||
public void drawPoint(boolean mode)
|
||||
{
|
||||
if (this.model == null) {
|
||||
lg.warning("Model not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
Graphics2D g2 = (Graphics2D) this.getGraphics();
|
||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
if (mode) {
|
||||
drawLine(model.getIntern(), colorInternal, g2);
|
||||
} else {
|
||||
drawLine(model.getExtern(), colorExternal, g2);
|
||||
}
|
||||
g2.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw new line between two points
|
||||
* @param f Figures with points
|
||||
* @param c Color of line
|
||||
* @param g2 Graphics context
|
||||
*/
|
||||
private void drawLine(Figures f, Color c, Graphics2D g2)
|
||||
{
|
||||
List<Point> points;
|
||||
|
||||
try {
|
||||
points = f.getLastTwoPoints();
|
||||
} catch (Exception e) {
|
||||
return;
|
||||
}
|
||||
|
||||
line.setLine(points.get(0), points.get(1));
|
||||
|
||||
g2.setPaint(c);
|
||||
g2.setStroke(new BasicStroke(3));
|
||||
g2.draw(line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Repaint view
|
||||
* @param g Something special
|
||||
*/
|
||||
@Override
|
||||
public void paintComponent(Graphics g)
|
||||
{
|
||||
super.paintComponent(g);
|
||||
|
||||
if (model == null) {
|
||||
lg.warning("Model not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
redrawFigures(model.getIntern(), colorInternal, g2);
|
||||
redrawFigures(model.getExtern(), colorExternal, g2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redraw figure
|
||||
* @param figures Figure to redraw
|
||||
* @param g2 Graphics context
|
||||
*/
|
||||
private void redrawFigures(Figures figures, Color c, Graphics2D g2)
|
||||
{
|
||||
for (Figure f : figures.getFigures()) {
|
||||
List<Point> points = f.getPoints();
|
||||
for (int i=1; i<points.size(); i++) {
|
||||
line.setLine(points.get(i-1), points.get(i));
|
||||
g2.setPaint(c);
|
||||
g2.setStroke(new BasicStroke(3));
|
||||
g2.draw(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to print current graphics
|
||||
*/
|
||||
public void doPrint()
|
||||
{
|
||||
HashPrintRequestAttributeSet printSet = new HashPrintRequestAttributeSet();
|
||||
printSet.add(DialogTypeSelection.NATIVE);
|
||||
PrinterJob pj = PrinterJob.getPrinterJob();
|
||||
pj.setPrintable(this);
|
||||
// Druckdialog
|
||||
if (pj.printDialog(printSet)) {
|
||||
try {
|
||||
pj.print(printSet);
|
||||
} catch (Exception ex) {
|
||||
JOptionPane.showMessageDialog(this, ex.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform print of graphics
|
||||
* @param gp Current graphics
|
||||
* @param pf format of page
|
||||
* @param pageIndex index of page
|
||||
* @return result if successful
|
||||
* @throws PrinterException if something went wrong
|
||||
*/
|
||||
@Override
|
||||
public int print(Graphics gp, PageFormat pf, int pageIndex) throws PrinterException
|
||||
{
|
||||
Graphics2D g2p = (Graphics2D) gp;
|
||||
if (pageIndex == 0) {
|
||||
g2p.translate(pf.getImageableX(), pf.getImageableY());
|
||||
g2p.scale(pf.getImageableWidth()/pf.getWidth(), pf.getImageableHeight() / pf.getHeight());
|
||||
super.print(g2p);
|
||||
return Printable.PAGE_EXISTS;
|
||||
} else {
|
||||
return Printable.NO_SUCH_PAGE;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user