/* * * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Oracle nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.FileDialog; import java.awt.Frame; import java.awt.Graphics; import java.awt.GraphicsEnvironment; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.lang.reflect.InvocationTargetException; import java.util.MissingResourceException; import java.util.ResourceBundle; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JTextPane; import javax.swing.SwingUtilities; import javax.swing.text.DefaultStyledDocument; import javax.swing.text.Document; import javax.swing.text.JTextComponent; import javax.swing.text.StyleContext; import javax.swing.text.StyledEditorKit; import javax.swing.text.TextAction; /** * Sample application using JTextPane. * * @author Timothy Prinzing */ @SuppressWarnings("serial") public class Stylepad extends Notepad { private static ResourceBundle resources; private FileDialog fileDialog; private static final String[] MENUBAR_KEYS = {"file", "edit", "color", "font", "debug"}; private static final String[] FONT_KEYS = {"family1", "family2", "family3", "family4", "-", "size1", "size2", "size3", "size4", "size5", "-", "bold", "italic", "underline"}; private static final String[] TOOLBAR_KEYS = {"new", "open", "save", "-", "cut", "copy", "paste", "-", "bold", "italic", "underline", "-", "left", "center", "right"}; static { try { properties.load(Stylepad.class.getResourceAsStream( "resources/StylepadSystem.properties")); resources = ResourceBundle.getBundle("resources.Stylepad"); } catch (MissingResourceException | IOException mre) { System.err.println("Stylepad.properties or StylepadSystem.properties not found"); System.exit(0); } } public Stylepad() { super(); } public static void main(String[] args) { try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { JFrame frame = new JFrame(); frame.setTitle(resources.getString("Title")); frame.setBackground(Color.lightGray); frame.getContentPane(). setLayout(new BorderLayout()); Stylepad stylepad = new Stylepad(); frame.getContentPane().add("Center", stylepad); frame.setJMenuBar(stylepad.createMenubar()); frame.addWindowListener(new AppCloser()); frame.pack(); frame.setSize(600, 480); frame.setVisible(true); } }); } catch (InterruptedException ex) { Logger.getLogger(Stylepad.class.getName()).log(Level.SEVERE, null, ex); } catch (InvocationTargetException ex) { Logger.getLogger(Stylepad.class.getName()).log(Level.SEVERE, null, ex); } } /** * Fetch the list of actions supported by this * editor. It is implemented to return the list * of actions supported by the superclass * augmented with the actions defined locally. */ @Override public Action[] getActions() { Action[] defaultActions = { new NewAction(), new OpenAction(), new SaveAction(), new StyledEditorKit.FontFamilyAction("font-family-SansSerif", "SansSerif"), }; Action[] a = TextAction.augmentList(super.getActions(), defaultActions); return a; } /** * Try and resolve the resource name in the local * resource file, and if not found fall back to * the superclass resource file. */ @Override protected String getResourceString(String nm) { String str; try { str = Stylepad.resources.getString(nm); } catch (MissingResourceException mre) { str = super.getResourceString(nm); } return str; } /** * Create an editor to represent the given document. */ @Override protected JTextComponent createEditor() { StyleContext sc = new StyleContext(); DefaultStyledDocument doc = new DefaultStyledDocument(sc); initDocument(doc, sc); JTextPane p = new JTextPane(doc); p.setDragEnabled(true); //p.getCaret().setBlinkRate(0); return p; } /** * Create a menu for the app. This is redefined to trap * a couple of special entries for now. */ @Override protected JMenu createMenu(String key) { if (key.equals("color")) { return createColorMenu(); } return super.createMenu(key); } @Override protected String[] getItemKeys(String key) { switch (key) { case "font": return FONT_KEYS; default: return super.getItemKeys(key); } } @Override protected String[] getMenuBarKeys() { return MENUBAR_KEYS; } @Override protected String[] getToolBarKeys() { return TOOLBAR_KEYS; } // this will soon be replaced JMenu createColorMenu() { ActionListener a; JMenuItem mi; JMenu menu = new JMenu(getResourceString("color" + labelSuffix)); mi = new JMenuItem(resources.getString("Red")); mi.setHorizontalTextPosition(JButton.RIGHT); mi.setIcon(new ColoredSquare(Color.red)); a = new StyledEditorKit.ForegroundAction("set-foreground-red", Color.red); //a = new ColorAction(se, Color.red); mi.addActionListener(a); menu.add(mi); mi = new JMenuItem(resources.getString("Green")); mi.setHorizontalTextPosition(JButton.RIGHT); mi.setIcon(new ColoredSquare(Color.green)); a = new StyledEditorKit.ForegroundAction("set-foreground-green", Color.green); //a = new ColorAction(se, Color.green); mi.addActionListener(a); menu.add(mi); mi = new JMenuItem(resources.getString("Blue")); mi.setHorizontalTextPosition(JButton.RIGHT); mi.setIcon(new ColoredSquare(Color.blue)); a = new StyledEditorKit.ForegroundAction("set-foreground-blue", Color.blue); //a = new ColorAction(se, Color.blue); mi.addActionListener(a); menu.add(mi); return menu; } void initDocument(DefaultStyledDocument doc, StyleContext sc) { Wonderland w = new Wonderland(doc, sc); w.loadDocument(); } JComboBox createFamilyChoices() { JComboBox b = new JComboBox<>(); String[] fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment(). getAvailableFontFamilyNames(); for (String fontName : fontNames) { b.addItem(fontName); } return b; } /** * Trys to read a file which is assumed to be a * serialization of a document. */ class OpenAction extends AbstractAction { OpenAction() { super(openAction); } @Override public void actionPerformed(ActionEvent e) { Frame frame = getFrame(); if (fileDialog == null) { fileDialog = new FileDialog(frame); } fileDialog.setMode(FileDialog.LOAD); fileDialog.setVisible(true); String file = fileDialog.getFile(); if (file == null) { return; } String directory = fileDialog.getDirectory(); File f = new File(directory, file); if (f.exists()) { try { FileInputStream fin = new FileInputStream(f); ObjectInputStream istrm = new ObjectInputStream(fin); Document doc = (Document) istrm.readObject(); if (getEditor().getDocument() != null) { getEditor().getDocument().removeUndoableEditListener( undoHandler); } getEditor().setDocument(doc); doc.addUndoableEditListener(undoHandler); resetUndoManager(); frame.setTitle(file); validate(); } catch (IOException io) { // should put in status panel System.err.println("IOException: " + io.getMessage()); } catch (ClassNotFoundException cnf) { // should put in status panel System.err.println("Class not found: " + cnf.getMessage()); } } else { // should put in status panel System.err.println("No such file: " + f); } } } /** * Trys to write the document as a serialization. */ class SaveAction extends AbstractAction { SaveAction() { super(saveAction); } @Override public void actionPerformed(ActionEvent e) { Frame frame = getFrame(); if (fileDialog == null) { fileDialog = new FileDialog(frame); } fileDialog.setMode(FileDialog.SAVE); fileDialog.setVisible(true); String file = fileDialog.getFile(); if (file == null) { return; } String directory = fileDialog.getDirectory(); File f = new File(directory, file); try { FileOutputStream fstrm = new FileOutputStream(f); ObjectOutput ostrm = new ObjectOutputStream(fstrm); ostrm.writeObject(getEditor().getDocument()); ostrm.flush(); frame.setTitle(f.getName()); } catch (IOException io) { // should put in status panel System.err.println("IOException: " + io.getMessage()); } } } /** * Creates an empty document. */ class NewAction extends AbstractAction { NewAction() { super(newAction); } @Override public void actionPerformed(ActionEvent e) { if (getEditor().getDocument() != null) { getEditor().getDocument().removeUndoableEditListener(undoHandler); } getEditor().setDocument(new DefaultStyledDocument()); getEditor().getDocument().addUndoableEditListener(undoHandler); resetUndoManager(); getFrame().setTitle(resources.getString("Title")); validate(); } } class ColoredSquare implements Icon { Color color; public ColoredSquare(Color c) { this.color = c; } @Override public void paintIcon(Component c, Graphics g, int x, int y) { Color oldColor = g.getColor(); g.setColor(color); g.fill3DRect(x, y, getIconWidth(), getIconHeight(), true); g.setColor(oldColor); } @Override public int getIconWidth() { return 12; } @Override public int getIconHeight() { return 12; } } }