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"); */ /* */ } } }