Browse Source

full final grafikchat, bääm, geht voll ab xD

master
moreris 2 years ago
commit
3a4b3b4f07

+ 44
- 0
src/grafikchat/Start.java View 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
- 0
src/grafikchat/controller/ConnectController.java View 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
- 0
src/grafikchat/controller/GrafikController.java View 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
- 0
src/grafikchat/controller/ReceiveAdapter.java View 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
- 0
src/grafikchat/model/ChatModel.java View 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
- 0
src/grafikchat/model/Client.java View 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
- 0
src/grafikchat/model/Figure.java View 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
- 0
src/grafikchat/model/Figures.java View 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
- 0
src/grafikchat/model/Server.java View 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
- 0
src/grafikchat/model/Transceiver.java View 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
- 0
src/grafikchat/model/TransceiverData.java View 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
- 0
src/grafikchat/model/TransceiverDataEvent.java View File

@@ -0,0 +1,10 @@
package grafikchat.model;



public enum TransceiverDataEvent
{
NEWPOINT,
NEWFIGURE,
REPAINT;
}

+ 34
- 0
src/grafikchat/ohmlogger/OhmFormatter.java View 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
- 0
src/grafikchat/ohmlogger/OhmLogger.java View 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
- 0
src/grafikchat/view/ChatView.form View 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
- 0
src/grafikchat/view/ChatView.java View 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
- 0
src/grafikchat/view/GrafikView.java View 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…
Cancel
Save