Files
artloglaby/java/org/artisanlogiciel/games/maze/gui/Display.java
philippe lhardy a70ead877a export many layers
- remark : wrong merge code ( dverged on two latptops .. ) possible loss
2020-12-19 16:56:55 +01:00

585 lines
19 KiB
Java

package org.artisanlogiciel.games.maze.gui;
import org.artisanlogiciel.games.maze.*;
import org.artisanlogiciel.games.maze.persist.MazePersistRaw;
import org.artisanlogiciel.games.maze.persist.MazePersistWorldEdit;
import org.artisanlogiciel.games.maze.solve.SolvingModel;
import org.artisanlogiciel.games.stl.Maze3dParams;
import org.artisanlogiciel.games.stl.Wall3dStream;
import org.artisanlogiciel.graphics.Drawing;
import org.artisanlogiciel.graphics.SvgWriter;
import org.artisanlogiciel.osm.OsmReader;
import org.artisanlogiciel.osm.convert.OsmToDrawing;
import org.artisanlogiciel.xpm.Xpm;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Locale;
/**
* Display is Main JFrame for this tool
**/
public class Display extends JFrame
implements StatusListener
{
// to please eclipse, not supposed to be serialized
private static final long serialVersionUID = 8500214871372184418L;
LabyLayers layers = new LabyLayers();
int layer = 0;
MazeComponent maze;
MazeControler controler;
LabyModel model;
boolean autoSize;
boolean statusEnable = true;
boolean mGrow = false;
MazeParams params = null;
JTextField statusField = null;
Maze3dSettings stlsettings;
Display(LabyModel model, int W, int H, MazeParams params) {
super(MazeDefault.labels.getString("title"));
if (params != null) {
// fixedParams = new MazeParamsFixed(params.getSaveDir(),params.getWidth(),params.getHeight(),params.getMaxDepth());
this.params = params;
}
this.model = model;
maze = createMazeComponent(model, W, H);
Container con = this.getContentPane();
JScrollPane scrollableMaze = new JScrollPane(maze);
con.add(scrollableMaze, BorderLayout.CENTER);
controler = new MazeControler(this,params);
con.add(controler.getMoveControl(), BorderLayout.NORTH);
con.add(controler.getGenerationControl(), BorderLayout.SOUTH);
/*
scrollableMaze.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
if (autoSize) {
maze.getAutoSize();
}
}
});
*/
model.setMazeListener(maze);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(W, H, W, H);
setVisible(true);
}
private MazeComponent createMazeComponent(LabyModel model, int W, int H) {
MazeCellParameters cp = new MazeCellParameters(model.getWidth(), model.getHeight(), W, H, 0, 0);
MazeComponent comp = new MazeComponent(model, cp, this);
Xpm xpm = new Xpm();
try {
xpm.parse(new FileInputStream(MazeDefault.getInstance().getXpmBackground()));
comp.setXpm(xpm);
}
catch(Exception e)
{
System.err.println("Missing background file " + e);
}
return comp;
}
void recreateModel() {
// recreate labyrinth
if (params != null) {
// Keep current model to be able to complete a manualy edited one
maze.resetWallsProvider(model);
model.setMazeListener(maze);
model.reset();
// we are in GUI event thread, need to release it and do it outside.
new Thread() {
public void run() {
model.generateWithEntry(0, 0);
model.addEntryOrExit(-1, 0);
model.addEntryOrExit(params.getWidth(), params.getHeight() - 1);
}
}.start();
}
}
void setModel( LabyModel model)
{
this.model = model;
layers.addLabyModel(layer, model);
}
void resetModel() {
// recreate labyrinth
if (params != null) {
params = controler.getSettings().resetParams();
setModel(new LabyModel(params));
refresh();
}
}
void refresh()
{
// reinit labyrinth view
if (params != null) {
maze.resetWallsProvider(model);
model.setMazeListener(maze);
// we are in GUI event thread, need to release it and do it outside.
new Thread() {
public void run() {
maze.changed(null, null, model);
}
}.start();
}
}
void resolve() {
SolvingModel solving = new SolvingModel(model);
// should transform current model to be a SolvingModel
model = solving;
model.reset();
solving.resolve(solving.getWidth() - 1, solving.getHeight() - 1, maze);
}
boolean reverse(boolean grow) {
boolean done = model.reverse(grow);
if ( done ) {
refresh();
}
return done;
}
void goNorth() {
maze.goNorth();
}
void goSouth() {
maze.goSouth();
}
void goEast() {
maze.goEast();
}
void goWest() {
maze.goWest();
}
void setWallSize(int size) {
maze.setWallSize(size);
}
void setAutoSize(boolean autoSize) {
this.autoSize = autoSize;
if (autoSize) {
maze.getAutoSize();
}
}
// to allow to log / write somewher into screen...
void writeSentence(String pSentence) {
// TODO
addStatus(pSentence);
}
void writeError(String pError) {
System.err.println(pError);
}
public Drawing createDrawing() {
return new DrawingGenerator(model).createDrawing();
}
void saveImc() {
Drawing d = createDrawing();
if (d != null) {
File outfile = getFileForExtension("imc");
writeSentence("Saving to " + outfile + " ...");
try {
DataOutputStream out = new DataOutputStream(new FileOutputStream(outfile));
d.saveLinesKompressed(out);
out.flush();
out.close();
writeSentence("... Done.");
} catch (IOException io) {
io.printStackTrace(System.err);
}
}
}
File getFileForExtension(final String extension)
{
return new File(params.getSaveDir(), params.getName() + "." + extension);
}
void saveSvg() {
Drawing d = createDrawing();
if (d != null) {
File outfile = getFileForExtension("svg");
writeSentence("Saving to " + outfile + " ...");
try {
DataOutputStream out = new DataOutputStream(new FileOutputStream(outfile));
SvgWriter writer = new SvgWriter(d.getInternLines());
writer.writeTo(out);
out.flush();
out.close();
writeSentence("... Done.");
} catch (IOException io) {
io.printStackTrace(System.err);
}
} else {
writeError("drawing creation failed");
}
}
void savePng() {
File file = getFileForExtension("png");
// BufferedImage bi = new BufferedImage(this.getSize().width, this.getSize().height, BufferedImage.TYPE_INT_ARGB);
BufferedImage bi = new BufferedImage(maze.getSize().width, maze.getSize().height, BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
// this.paint(g);
maze.paint(g);
g.dispose();
try {
ImageIO.write(bi, "png", file);
} catch (Exception e) {
e.printStackTrace();
}
}
void saveText() {
File outfile = getFileForExtension("txt");
writeSentence("Saving to " + outfile + " ...");
try {
DataOutputStream out = new DataOutputStream(new FileOutputStream(outfile));
out.write(model.toLabyMap().toString().getBytes());
out.flush();
out.close();
writeSentence("... Done.");
} catch (IOException io) {
io.printStackTrace(System.err);
}
}
public void addStatus(String pStatus)
{
if ( statusEnable ) {
statusField.setText(pStatus);
}
}
void loadRaw() {
File infile = new File(params.getSaveDir(), params.getName() + ".raw");
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(infile);
setModel(new MazePersistRaw().parseInputStream("raw",inputStream));
} catch (IOException io) {
io.printStackTrace(System.err);
statusField.setText("[ERROR] Can't load " + infile.getAbsolutePath());
}
finally
{
if (inputStream != null )
{
// cleanup
try {
inputStream.close();
}
catch (Exception any)
{
// don't care really
}
}
}
}
void loadOsm(boolean add, int mulx, int muly) {
if ( maze != null ) {
new Thread() {
@Override
public void run() {
File infile = new File(params.getSaveDir(), params.getName() + ".osm");
FileInputStream inputStream = null;
try {
// TODO really use InputStream and not pathname
OsmReader reader = new OsmReader(infile.getCanonicalPath());
reader.read();
OsmToDrawing converter = new OsmToDrawing(reader, mulx,muly);
Drawing drawing = converter.getDrawing(reader.getWays());
statusEnable = false;
maze.addDrawing(drawing,add);
statusEnable = true;
} catch (IOException io) {
io.printStackTrace(System.err);
statusField.setText("[ERROR] Can't load " + infile.getAbsolutePath());
} finally {
if (inputStream != null) {
// cleanup
try {
inputStream.close();
} catch (Exception any) {
// don't care really
}
}
}
}
}.start();
}
}
void loadImc(boolean add) {
if ( maze != null ) {
new Thread() {
@Override
public void run() {
File infile = new File(params.getSaveDir(), params.getName() + ".imc");
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(infile);
// TODO
// model = new MazePersistRaw().parseInputStream("raw",inputStream);
Drawing drawing = new Drawing();
drawing.loadLinesExpanded(new DataInputStream(inputStream));
statusEnable = false;
maze.addDrawing(drawing,add);
statusEnable = true;
} catch (IOException io) {
io.printStackTrace(System.err);
statusField.setText("[ERROR] Can't load " + infile.getAbsolutePath());
} finally {
if (inputStream != null) {
// cleanup
try {
inputStream.close();
} catch (Exception any) {
// don't care really
}
}
}
}
}.start();
}
}
void loadDrawing(boolean add) {
if ( maze != null ) {
new Thread() {
@Override
public void run() {
File infile = new File(params.getSaveDir(), params.getName() + ".drawing");
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(infile);
// TODO
// model = new MazePersistRaw().parseInputStream("raw",inputStream);
Drawing drawing = new Drawing();
drawing.loadLines(new DataInputStream(inputStream));
statusEnable = false;
maze.addDrawing(drawing,add);
statusEnable = true;
} catch (IOException io) {
io.printStackTrace(System.err);
statusField.setText("[ERROR] Can't load " + infile.getAbsolutePath());
} finally {
if (inputStream != null) {
// cleanup
try {
inputStream.close();
} catch (Exception any) {
// don't care really
}
}
}
}
}.start();
}
}
void loadWorldEdit(boolean add) {
if ( maze != null ) {
File infile = new File(params.getSaveDir(), params.getName() + ".we");
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(infile);
LabyLayers newLayers = new MazePersistWorldEdit().parseInputStream("we",inputStream);
if ( ! newLayers.isEmpty()) {
int l = layer;
for (int i = newLayers.getMin(); i <= newLayers.getMax(); i++) {
LabyModel m = newLayers.getLayer(i);
if (m != null) {
System.out.println("add layer " + l);
layers.addLabyModel(l, m);
l++;
}
}
setModel(layers.getLayer(layer));
}
} catch (IOException io) {
io.printStackTrace(System.err);
statusField.setText("[ERROR] Can't load " + infile.getAbsolutePath());
} finally {
if (inputStream != null) {
// cleanup
try {
inputStream.close();
} catch (Exception any) {
// don't care really
}
}
}
}
}
JButton addDirection(final JPanel panel, final String direction, String key, Action goAction) {
String actionName = "go" + direction;
JButton button = new JButton(direction);
button.addActionListener(goAction);
KeyStroke keystroke = KeyStroke.getKeyStroke(key);
// attach keys to maze
maze.getInputMap().put(keystroke, actionName);
maze.getActionMap().put(actionName, goAction);
return button;
}
private static void setupDisplay(LabyModel model, int W, int H, MazeParams params) {
Display display = new Display(model, W, H, params);
}
void saveWorldEdit() {
File outfile = getFileForExtension("we");
if (!outfile.exists()) {
addStatus("Saving we to " + outfile + " ...");
try {
FileOutputStream out = new FileOutputStream(outfile);
new MazePersistWorldEdit(layers).streamOut("we", out);
out.close();
addStatus("... Done.");
} catch (IOException io) {
io.printStackTrace(System.err);
}
} else {
addStatus("we file " + outfile + " already exists");
}
}
public void saveStl(MazeParamsFixed params, LabyModel model, Maze3dParams wallparams) {
File outfile = getFileForExtension("stl");
if (!outfile.exists()) {
addStatus("Saving stl to " + outfile + " ...");
try {
FileOutputStream out = new FileOutputStream(outfile);
new Wall3dStream(params.getName(), model, out, wallparams).stream();
out.close();
addStatus("... Done.");
} catch (IOException io) {
io.printStackTrace(System.err);
}
} else {
addStatus("stl file " + outfile + " already exists");
}
}
public void save(MazeParamsFixed params, LabyModel model) {
File outfile = getFileForExtension("raw");
if (!outfile.exists()) {
addStatus("Saving to " + outfile + " ...");
try {
FileOutputStream out = new FileOutputStream(outfile);
MazePersistRaw persist = new MazePersistRaw(model);
persist.streamOut("raw", out);
out.flush();
out.close();
addStatus("... Done.");
} catch (IOException io) {
io.printStackTrace(System.err);
}
} else {
addStatus("" + outfile + " already exists");
}
}
int setLayer(int x)
{
addStatus("set layer " + x);
LabyModel layermodel = layers.getLayer(x);
if ( layermodel == null )
{
// clone it
model = new LabyModel(model);
layers.addLabyModel(x, model);
}
else
{
model = layermodel;
}
layer = x;
refresh();
return layer;
}
public static void main(String pArgs[]) {
LabyModel model = null;
int W = 600;
int H = 400;
System.out.println("Default Locale " + Locale.getDefault());
if ((pArgs.length > 0) && (pArgs[0].length() > 0)) {
try {
model = new MazePersistRaw().parseInputStream("raw",new FileInputStream(pArgs[0]));
} catch (IOException io) {
io.printStackTrace(System.err);
System.exit(1);
}
setupDisplay(model, W, H, null);
} else {
MazeParamsFixed params = new MazeParamsFixed(MazeDefault.getInstance().getParams());
model = new LabyModel(params);
setupDisplay(model, W, H, params);
/*
model.generateWithEntry(0, 0);
model.addEntryOrExit(-1, 0);
model.addEntryOrExit(params.getWidth(), params.getHeight() - 1);
addStatus("Generation completed");
*/
/*
*/
}
}
}