JETTY_DIR="jetty-distribution-$JETTY_VERSION"
JETTY_PACKAGE="$JETTY_DIR.tar.gz"
JETTY_UTIL_AJAX=jetty-util-ajax-$JETTY_VERSION.jar
+export JAVA_HOME=$BASE_DIR/jdk1.8.0
+
+# NOTE:
+# http://stackoverflow.com/questions/22806946/getting-error-scanning-file-when-running-jetty-9-on-java-8-using-the-maven-jetty
+# http://forge.ow2.org/project/showfiles.php?group_id=23&release_id=5424
OPT_FETCH=0;
OPT_COMPILE=0
if [ $OPT_COMPILE -eq 1 ]; then
echo "Compiling..."
cd $BASE_DIR/src;
- javac -Xlint:unchecked -d ../WEB-INF/classes/ -cp "../$JETTY_DIR/lib/*:../$JETTY_DIR/lib/websocket/*" org/evergreen_ils/hatch/*.java;
+ $JAVA_HOME/bin/javac -Xlint:unchecked -d ../WEB-INF/classes/ -cp "../$JETTY_DIR/lib/*:../$JETTY_DIR/lib/websocket/*" org/evergreen_ils/hatch/*.java;
fi;
if [ $OPT_RUN -eq 1 ]; then
echo "Running..."
cd $BASE_DIR/$JETTY_DIR;
- java -jar start.jar
+ $JAVA_HOME/bin/java -jar start.jar
fi;
import org.eclipse.jetty.util.log.Logger;
import java.util.Arrays;
import java.util.List;
+import java.util.HashMap;
@WebSocket
public class HatchSocket {
this.session = null;
}
- private void sendJSONMessage(Object json) {
+ private void reply(Object json) {
+ reply(json, true);
+ }
+
+ private void reply(Object json, boolean success) {
+
+ HashMap<String, Object> response = new HashMap<String, Object>();
+ if (success) {
+ response.put("success", json);
+ } else {
+ response.put("error", json);
+ }
+
try {
- session.getRemote().sendString(JSON.toString(json));
+ String jsonString = JSON.toString(response);
+ if (!success) logger.warn(jsonString);
+ session.getRemote().sendString(jsonString);
} catch (IOException e) {
logger.warn(e);
}
}
@OnWebSocketMessage
+ @SuppressWarnings("unchecked") // direct casting JSON-parsed objects
public void onMessage(String message) {
if (session == null || !session.isOpen()) return;
logger.info("onMessage() " + message);
+ HashMap<String,String> params = null;
+
+ try {
+ params = (HashMap<String,String>) JSON.parse(message);
+ } catch (ClassCastException e) {
+ reply("Invalid WebSockets JSON message " + message, false);
+ }
+
FileIO io;
- /*
- * TODO: inbound message should be a JSON blob
- String action = request.getParameter("action");
- String key = request.getParameter("key");
- String value = request.getParameter("value");
- */
- String action = "keys";
- String key = "";
- String value = "";
+ String action = params.get("action");
+ String key = params.get("key");
+ String value = params.get("value");
+ String mime = params.get("mime");
// all requests require an action
- /*
if (action == null || action.equals("")) {
- String err = JSON.toString("No action specified in request");
- sendJSONMessage(err);
- logger.info(err);
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ reply("No action specified in request", false);
return;
}
- */
if (action.equals("keys")) {
io = new FileIO(profileDirectory);
String[] keys = io.keys(key); // OK for key to be null
-
if (keys != null) {
- sendJSONMessage(keys);
+ reply(keys);
} else {
- /*
- response.setStatus(
- HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- */
+ reply("key lookup error", false);
}
return;
}
if (action.equals("printers")) {
List printers = new PrintDriver().getPrinters();
- //response.setStatus(HttpServletResponse.SC_OK);
- sendJSONMessage(printers);
+ reply(printers);
return;
}
// all remaining requests require a key
if (key == null || key.equals("")) {
- String err = "No key specified in request";
- sendJSONMessage(err);
- logger.info(err);
- //response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ reply("No key specified in request", false);
return;
}
BufferedReader reader = io.get(key);
if (reader != null) {
String line;
- //response.setStatus(HttpServletResponse.SC_OK);
try {
while ( (line = reader.readLine()) != null) {
// relay lines of text to the caller as we read them
// assume the text content is JSON and return it
// un-JSON-ified.
- sendJSONMessage(line);
+ reply(line);
}
} catch (IOException e) {
logger.warn(e);
}
} else {
- /*
- response.setStatus(
- HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- */
+ reply("Error accessing property " + key, false);
}
return;
}
if (action.equals("delete")) {
io = new FileIO(profileDirectory);
if (io.delete(key)) {
- //response.setStatus(HttpServletResponse.SC_OK);
+ reply("Delete of " + key + " successful");
} else {
- //response.setStatus(
- //HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ reply("Delete of " + key + " failed", false);
}
return;
}
// all remaining actions require value
if (value == null) {
- String err = "No value specified in request";
- sendJSONMessage(err);
- logger.info(err);
- //response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ reply("No value specified in request", false);
return;
}
- switch(action) {
+ switch (action) {
case "print" :
- boolean ok = new PrintDriver().printWithDialog(key, value);
+ boolean ok = new PrintDriver().printWithDialog(mime, value);
if (ok) {
- //response.setStatus(HttpServletResponse.SC_OK);
+ reply("print succeeded");
} else {
- //response.setStatus(
- //HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ reply("print failed", false);
}
break;
case "set" :
io = new FileIO(profileDirectory);
if (io.set(key, value)) {
- //response.setStatus(HttpServletResponse.SC_OK);
+ reply("setting value for " + key + " succeeded");
} else {
- //response.setStatus(
- //HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ reply("setting value for " + key + " succeeded", false);
}
break;
case "append" :
io = new FileIO(profileDirectory);
if (io.append(key, value)) {
- //response.setStatus(HttpServletResponse.SC_OK);
+ reply("appending value for " + key + " succeeded");
} else {
- //response.setStatus(
- //HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ reply("appending value for " + key + " succeeded", false);
}
break;
default:
- //response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- sendJSONMessage(
- "\"No Such Action: " + action + "\"");
- logger.info("No such action: " + action);
+ reply("No such action: " + action, false);
}
-
}
}
public class PrintDriver implements Printable {
private String printText;
+ private String mimeType;
private static final Logger logger = Log.getLogger("PrintDriver");
private final static int POINTS_PER_INCH = 72;
- public int print(Graphics g, PageFormat pf, int page)
- throws PrinterException {
+ public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
+
+ switch (mimeType) {
+ case "text/csv" : return printTextCSV(g, pf, page);
+ case "text/plain" : return printTextPlain(g, pf, page);
+ case "text/html" : return printTextHTML(g, pf, page);
+ default :
+ logger.warn("Print MIME type not supported: " + mimeType);
+ }
+
+ return NO_SUCH_PAGE;
+ }
+
+ private int printTextHTML(Graphics g, PageFormat pf, int page) {
+ return PAGE_EXISTS;
+ }
+
+ private int printTextPlain(Graphics g, PageFormat pf, int page) {
// for now, assume we only have one page
if (page > 0) return NO_SUCH_PAGE;
Graphics2D g2d = (Graphics2D)g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
- /* --------------------------------------------- */
- /* -- rendering the print text as paragraph --- */
+ // ---------------------------------------------
+ // -- rendering the print text as paragraph ---
Point2D.Double pen = new Point2D.Double(
0.25 * POINTS_PER_INCH, 0.25 * POINTS_PER_INCH);
double width = 7.5 * POINTS_PER_INCH;
//--- the leading of the font
pen.y += layout.getDescent() + layout.getLeading();
}
- /* -------------------------------------------- */
+ // --------------------------------------------
+
+ return PAGE_EXISTS;
+ }
+
+ private int printTextCSV(Graphics g, PageFormat pf, int page) {
+ // for now, assume we only have one page
+ if (page > 0) return NO_SUCH_PAGE;
- /*
+ // find the imageable area
+ Graphics2D g2d = (Graphics2D)g;
+ g2d.translate(pf.getImageableX(), pf.getImageableY());
int x = 5;
int y = 5;
for (String line : printText.split("\n"))
g.drawString(line, x, y += g.getFontMetrics().getHeight());
- */
return PAGE_EXISTS;
}
/**
* Spawns standard JAVA-driven print dialog and prints text
*/
- public boolean printWithDialog(String key, String text) {
+ public boolean printWithDialog(String mime, String text) {
debugPrintService(null); // testing
printText = text;
+ mimeType = mime;
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(this);
if (!job.printDialog()) return true; // print canceled by user
try {
job.print();
} catch (PrinterException ex) {
- logger.warn("Error printing document for key " + key);
+ logger.warn("Error printing document for mime " + mime);
logger.warn(ex);
return false;
}
+++ /dev/null
-#!/bin/bash
-set -e
-
-BASE_DIR=$PWD
-JETTY_VERSION=9.1.2.v20140210
-JETTY_DIR="jetty-distribution-$JETTY_VERSION"
-JETTY_PACKAGE="$JETTY_DIR.tar.gz"
-JETTY_UTIL_AJAX=jetty-util-ajax-$JETTY_VERSION.jar
-
-OPT_FETCH=0;
-OPT_COMPILE=0
-OPT_RUN=0
-
-DEPENDS="javax.websocket-api-1.0.jar javax-websocket-client-impl-$JETTY_VERSION.jar javax-websocket-server-impl-$JETTY_VERSION.jar jetty-http-$JETTY_VERSION.jar jetty-io-$JETTY_VERSION.jar jetty-security-$JETTY_VERSION.jar jetty-server-$JETTY_VERSION.jar jetty-servlet-$JETTY_VERSION.jar jetty-util-$JETTY_VERSION.jar servlet-api-3.1.jar websocket-api-$JETTY_VERSION.jar websocket-client-$JETTY_VERSION.jar websocket-common-$JETTY_VERSION.jar websocket-server-$JETTY_VERSION.jar websocket-servlet-$JETTY_VERSION.jar"
-
-# return here on exit
-trap "{ cd $BASE_DIR; }" EXIT
-
-function usage() {
- echo ""
- echo "Fetch dependencies, compile, and run Hatch:";
- echo ""
- echo "$0 -fcr";
- echo ""
-}
-
-while getopts "fcrh" flag; do
- case $flag in
- "f") OPT_FETCH=1;;
- "c") OPT_COMPILE=1;;
- "r") OPT_RUN=1;;
- "h"|*) usage;;
- esac;
-done
-
-if [ $OPT_FETCH -eq 1 ]; then
-
- mkdir -p lib;
-
- if [ ! -f $JETTY_PACKAGE ]; then
- echo "Fetching Jetty package...";
- wget "http://carroll.aset.psu.edu/pub/eclipse/jetty/$JETTY_VERSION/dist/$JETTY_PACKAGE";
- fi;
-
- if [ ! -d $JETTY_DIR ]; then
- echo "Unpacking Jetty...";
- tar xf $JETTY_PACKAGE;
- for jar in $DEPENDS; do
- find $JETTY_DIR -name "$jar" -exec cp -v {} lib/ \;
- done;
- fi;
-fi;
-
-if [ $OPT_COMPILE -eq 1 ]; then
- echo "Compiling..."
- javac -Xlint:unchecked -cp "lib/*" org/evergreen_ils/hatch/*.java
-fi;
-
-if [ $OPT_RUN -eq 1 ]; then
- echo "Running..."
- java -cp ".:lib/*" org.evergreen_ils.hatch.EventServer
-fi;
+++ /dev/null
-package org.evergreen_ils.hatch;
-
-import java.net.URI;
-import javax.websocket.ContainerProvider;
-import javax.websocket.Session;
-import javax.websocket.WebSocketContainer;
-
-import org.eclipse.jetty.util.component.LifeCycle;
-
-public class EventClient
-{
- public static void main(String[] args)
- {
- URI uri = URI.create("ws://localhost:8080/hatch/");
-
- try
- {
- WebSocketContainer container = ContainerProvider.getWebSocketContainer();
-
- try
- {
- // Attempt Connect
- Session session = container.connectToServer(EventSocket.class,uri);
- // Send a message
- session.getBasicRemote().sendText("Hello");
- // Close session
- session.close();
- }
- finally
- {
- // Force lifecycle stop when done with container.
- // This is to free up threads and resources that the
- // JSR-356 container allocates. But unfortunately
- // the JSR-356 spec does not handle lifecycles (yet)
- if (container instanceof LifeCycle)
- {
- ((LifeCycle)container).stop();
- }
- }
- }
- catch (Throwable t)
- {
- t.printStackTrace(System.err);
- }
- }
-}
+++ /dev/null
-package org.evergreen_ils.hatch;
-
-// Code derived from
-// https://github.com/jetty-project/embedded-jetty-websocket-examples/tree/master/javax.websocket-example
-
-import javax.websocket.server.ServerContainer;
-
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
-
-public class EventServer
-{
- public static void main(String[] args)
- {
- Server server = new Server();
- ServerConnector connector = new ServerConnector(server);
- connector.setPort(8080);
- server.addConnector(connector);
-
- // Setup the basic application "context" for this application at "/"
- // This is also known as the handler tree (in jetty speak)
- ServletContextHandler context =
- new ServletContextHandler(ServletContextHandler.SESSIONS);
- context.setContextPath("/");
- server.setHandler(context);
-
- try {
- // Initialize javax.websocket layer
- ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext(context);
-
- // Add WebSocket endpoint to javax.websocket layer
- wscontainer.addEndpoint(EventSocket.class);
-
- server.start();
- server.dump(System.err);
- server.join();
-
- } catch (Throwable t) {
- t.printStackTrace(System.err);
- }
- }
-}
+++ /dev/null
-package org.evergreen_ils.hatch;
-
-import javax.websocket.ClientEndpoint;
-import javax.websocket.CloseReason;
-import javax.websocket.OnClose;
-import javax.websocket.OnError;
-import javax.websocket.OnMessage;
-import javax.websocket.OnOpen;
-import javax.websocket.Session;
-import javax.websocket.server.ServerEndpoint;
-
-@ClientEndpoint
-@ServerEndpoint(value="/hatch/")
-public class EventSocket
-{
- @OnOpen
- public void onWebSocketConnect(Session sess)
- {
- System.out.println("Socket Connected: " + sess);
- }
-
- @OnMessage
- public void onWebSocketText(String message)
- {
- System.out.println("Received TEXT message: " + message);
- }
-
- @OnClose
- public void onWebSocketClose(CloseReason reason)
- {
- System.out.println("Socket Closed: " + reason);
- }
-
- @OnError
- public void onWebSocketError(Throwable cause)
- {
- cause.printStackTrace(System.err);
- }
-}
+++ /dev/null
-package org.evergreen_ils.hatch;
-
-import java.io.*;
-import java.util.LinkedList;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-public class FileIO {
-
- String basePath;
- private static final Logger logger = Log.getLogger("FileIO");
-
- public FileIO(String directory) {
- basePath = directory;
- }
-
- protected File getFile(String key) {
- File dir = new File(basePath);
- if (!dir.exists()) {
- if (!dir.mkdir()) {
- logger.info("Unable to create director: " + basePath);
- return null;
- }
- }
- return new File(dir, key);
- }
-
- public boolean set(String key, String text) {
- logger.info("set => " + key);
- File file = getFile(key);
-
- try {
-
- // delete the file if it exists
- if (!file.exists() && !file.createNewFile()) {
- logger.info(
- "Unable to create file: " + file.getCanonicalPath());
- return false;
- }
-
- // destructive write (replace existing text)
- Writer outStream = new BufferedWriter(
- new FileWriter(file.getAbsoluteFile()));
-
- outStream.write(text);
- outStream.close();
-
- } catch(IOException e) {
- logger.warn("Error calling set() with key " + key);
- logger.warn(e);
- return false;
- }
-
- return true;
- }
-
- public boolean append(String key, String text) {
- logger.info("append => " + key);
- File file = getFile(key);
-
- try {
-
- // create the file if it doesn's already exist
- if (!file.exists() && !file.createNewFile()) {
- logger.info(
- "Unable to create file: " + file.getCanonicalPath());
- return false;
- }
-
- // non-destructive write (append)
- Writer outStream = new BufferedWriter(
- new FileWriter(file.getAbsoluteFile(), true));
- outStream.write(text);
- outStream.close();
-
- } catch(IOException e) {
- logger.warn("Error in append() with key " + key);
- logger.warn(e);
- return false;
- }
-
- return true;
- }
-
- public BufferedReader get(String key) {
- logger.info("get => " + key);
- File file = getFile(key);
- if (!file.exists()) return null;
-
- StringBuffer sbuf = new StringBuffer();
- try {
- return new BufferedReader(
- new FileReader(file.getAbsoluteFile()));
- } catch (IOException e) {
- logger.warn("Error reading key: " + key);
- logger.warn(e);
- return null;
- }
- }
-
- public boolean delete(String key) {
- logger.info("delete => " + key);
- File file = getFile(key);
- try {
- if (file.exists() && !file.delete()) {
- logger.info(
- "Unable to delete file: " + file.getCanonicalPath());
- return false;
- }
- return true;
- } catch (IOException e) {
- logger.warn("Error deleting key: " + key);
- logger.warn(e);
- return false;
- }
- }
-
- public String[] keys() {
- return keys(null);
- }
-
- public String[] keys(String prefix) {
- logger.info("keys => " + prefix);
- File dir = new File(basePath);
- if (!dir.exists()) return new String[0];
-
- LinkedList<String> nameList = new LinkedList<String>();
- File[] files = dir.listFiles();
-
- for (File file : files) {
- if (file.isFile()) {
- String name = file.getName();
- if (prefix == null) {
- nameList.add(name);
- } else {
- if (name.startsWith(prefix)) {
- nameList.add(name);
- }
- }
- }
- }
-
- return (String[]) nameList.toArray(new String[0]);
- }
-}
+++ /dev/null
-package org.evergreen_ils.hatch;
-
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-import java.awt.*;
-import java.awt.event.*;
-import javax.swing.*;
-import java.awt.print.*;
-
-import javax.print.PrintService;
-import javax.print.PrintServiceLookup;
-import javax.print.attribute.Attribute;
-import javax.print.attribute.AttributeSet;
-
-import java.awt.font.FontRenderContext;
-import java.awt.font.LineBreakMeasurer;
-import java.awt.font.TextAttribute;
-import java.awt.font.TextLayout;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.text.AttributedString;
-
-import java.util.Map;
-import java.util.List;
-import java.util.HashMap;
-import java.util.LinkedList;
-
-public class PrintDriver implements Printable {
-
- private String printText;
- private static final Logger logger = Log.getLogger("PrintDriver");
-
- private final static int POINTS_PER_INCH = 72;
-
- public int print(Graphics g, PageFormat pf, int page)
- throws PrinterException {
-
- // for now, assume we only have one page
- if (page > 0) return NO_SUCH_PAGE;
-
- // find the imageable area
- Graphics2D g2d = (Graphics2D)g;
- g2d.translate(pf.getImageableX(), pf.getImageableY());
-
- /* --------------------------------------------- */
- /* -- rendering the print text as paragraph --- */
- Point2D.Double pen = new Point2D.Double(
- 0.25 * POINTS_PER_INCH, 0.25 * POINTS_PER_INCH);
- double width = 7.5 * POINTS_PER_INCH;
- AttributedString paragraphText = new AttributedString(printText);
-
- LineBreakMeasurer lineBreaker = new LineBreakMeasurer(
- paragraphText.getIterator(), new FontRenderContext(null, true, true));
-
- //--- Create the TextLayout object
- TextLayout layout;
-
- //--- LineBreakMeasurer will wrap each line to correct length and
- //--- return it as a TextLayout object
- while ((layout = lineBreaker.nextLayout((float) width)) != null) {
- //--- Align the Y pen to the ascend of the font, remember that
- //--- the ascend is origin (0, 0) of a font. Refer to figure 1
- pen.y += layout.getAscent();
-
- //--- Draw the line of text
- layout.draw(g2d, (float) pen.x, (float) pen.y);
-
- //--- Move the pen to the next position adding the descent and
- //--- the leading of the font
- pen.y += layout.getDescent() + layout.getLeading();
- }
- /* -------------------------------------------- */
-
- /*
- int x = 5;
- int y = 5;
- for (String line : printText.split("\n"))
- g.drawString(line, x, y += g.getFontMetrics().getHeight());
- */
-
- return PAGE_EXISTS;
- }
-
- /**
- * Spawns standard JAVA-driven print dialog and prints text
- */
- public boolean printWithDialog(String key, String text) {
- debugPrintService(null); // testing
- printText = text;
- PrinterJob job = PrinterJob.getPrinterJob();
- job.setPrintable(this);
- if (!job.printDialog()) return true; // print canceled by user
- try {
- job.print();
- } catch (PrinterException ex) {
- logger.warn("Error printing document for key " + key);
- logger.warn(ex);
- return false;
- }
- return true;
- }
-
- /**
- * Print using defaults
- *
- * Sends the print job to the configured printer based on the key
- * and user settings.
- */
- public boolean printWithoutDialog(String key, String text) {
- printText = text;
- PrinterJob job = PrinterJob.getPrinterJob();
- job.setPrintable(this);
-
- // TODO: load user settings, find the right printer, send the
- // correct attributes, etc.
-
- try {
- job.print();
- } catch (PrinterException ex) {
- logger.warn("Error printing document for key " + key);
- logger.warn(ex);
- return false;
- }
- return true;
- }
-
- private void debugPrintService(PrintService printer) {
-
- PrintService[] printServices;
- String defaultPrinter = "";
-
- if (printer != null) {
- printServices = new PrintService[] {printer};
- } else {
- printServices = PrintServiceLookup.lookupPrintServices(null, null);
- PrintService def = PrintServiceLookup.lookupDefaultPrintService();
- if (def != null) defaultPrinter = def.getName();
- }
-
- for (PrintService service : printServices) {
- logger.info("Printer Debug: found printer " + service.getName());
- if (service.getName().equals(defaultPrinter)) {
- logger.info(" Printer Debug: Is Default");
- }
-
- AttributeSet attributes = service.getAttributes();
- for (Attribute a : attributes.toArray()) {
- String name = a.getName();
- String value = attributes.get(a.getClass()).toString();
- logger.info(" Printer Debug: " + name + " => " + value);
- }
- }
- }
-
- public List<HashMap> getPrinters() {
-
- List<HashMap> printers = new LinkedList<HashMap>();
- PrintService[] printServices =
- PrintServiceLookup.lookupPrintServices(null, null);
-
- String defaultPrinter = "";
- PrintService def = PrintServiceLookup.lookupDefaultPrintService();
- if (def != null) defaultPrinter = def.getName();
-
- for (PrintService service : printServices) {
- HashMap<String, Object> printer = new HashMap<String, Object>();
- printers.add(printer);
-
- if (service.getName().equals(defaultPrinter))
- printer.put("is-default", new Boolean(true));
-
- AttributeSet attributes = service.getAttributes();
- for (Attribute a : attributes.toArray()) {
- String name = a.getName();
- String value = attributes.get(a.getClass()).toString();
- printer.put(name, value);
- }
- }
-
- return printers;
- }
-
- // experiment
- // show our own print dialog before the real print action takes over
- // currently just shows Print and Cancel.
- // Not sure if there is a need for such a thing..
- public void printWithCustomDialog(String key, String msg) {
- UIManager.put("swing.boldMetal", Boolean.FALSE);
- JFrame f = new JFrame("Hello World Printer");
-
- // close the frame when Cancel / X are clicked
- f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
-
- final String printMsg = msg;
- final String printKey = key;
- JButton printButton = new JButton("Print '" + msg + "'");
- printButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- printWithDialog(printKey, printMsg);
- }
- });
-
- JButton cancelButton = new JButton("Cancel");
- cancelButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- Component component = (Component) e.getSource();
- JFrame frame = (JFrame) SwingUtilities.getRoot(component);
- WindowEvent windowClosing =
- new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
- frame.dispatchEvent(windowClosing);
- }
- });
-
- JPanel grid = new JPanel(new FlowLayout(FlowLayout.LEFT,3,3));
- f.add(grid);
- grid.add(cancelButton);
- grid.add(printButton);
- f.pack();
- f.setVisible(true);
- }
-}
-
-