/* * Copyright 2003-2010 Tufts University Licensed under the * Educational Community License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may * obtain a copy of the License at * * http://www.osedu.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS IS" * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing * permissions and limitations under the License. */ package tufts.vue.gui.formattingpalette; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.GraphicsEnvironment; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Enumeration; import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.AbstractButton; import javax.swing.BorderFactory; import javax.swing.ButtonModel; import javax.swing.ImageIcon; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JToggleButton; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.Caret; import javax.swing.text.Document; import javax.swing.text.Element; import javax.swing.text.JTextComponent; import javax.swing.text.StyleConstants; import javax.swing.text.Utilities; import javax.swing.text.html.HTML; import tufts.Util; import tufts.vue.DEBUG; import tufts.vue.PaletteButton; import tufts.vue.PaletteButtonItem; import tufts.vue.TextBox; import tufts.vue.VUE; import tufts.vue.VueResources; import tufts.vue.VueTool; import tufts.vue.VueUtil; import tufts.vue.gui.GUI; import tufts.vue.gui.VueButton; import tufts.vue.gui.VueButton.Toggle; public class TextPropsPane extends JPanel implements CaretListener// , // KeyListener { private final int topPad = 2; private final int botPad = 2; private final Insets labelInsets = new Insets(topPad, 25, botPad, GUI.LabelGapRight); private final Insets tightInsets = new Insets(topPad, 5, botPad, 5); private final Insets fieldInsets = new Insets(topPad, 0, botPad, 25); private final Object[] sizes = { "8", "9", "10", "11", "12", "14", "16", "18", "20", "22", "24", "26", "28", "36", "48", "72", "96" }; private TextBox textBox; // private boolean bulletMode = false; private Toggle boldButton = new VueButton.Toggle("font.button.bold"); private Toggle italicButton = new VueButton.Toggle("font.button.italic"); private Toggle underlineButton = new VueButton.Toggle( "font.button.underline"); private AlignmentDropDown alignmentButton = new AlignmentDropDown(); private JComboBox sizeField = new JComboBox(sizes); private AbstractButton orderedListButton = new VueButton( "list.button.ordered"); private AbstractButton unorderedListButton = new VueButton( "list.button.unordered"); private JComboBox field = new JComboBox(getFontFaces()); // private final String START_UNORDEREDLIST_STRING = "\u2022 "; // private final String INDENT_STRING = " "; // private final String BULLET="\u2022"; // private int previousAlignment = 1; // private String previousRow = ""; // private int indentNext; // private int listDepth =0; //private PaletteButton button = null; private VueColorButton colorButton = new VueColorButton(new Dimension(18, 18)); public TextPropsPane() { this.setFocusable(false); addComponents(); addListeners(); activateAll(false); } public void setActiveTextControl(tufts.vue.TextBox box) { // If this has previously been set remove the old listener.. if (textBox != null) textBox.removeCaretListener(this); textBox = box; if (textBox !=null) textBox.addCaretListener(this); if (textBox == null) activateAll(false); else activateAll(true); } private void activateAll(boolean b) { boldButton.setEnabled(b); italicButton.setEnabled(b); underlineButton.setEnabled(b); alignmentButton.getComboBox().setEnabled(b); sizeField.setEnabled(b); orderedListButton.setEnabled(b); unorderedListButton.setEnabled(b); field.setEnabled(b); colorButton.setEnabled(b); return; } private Vector getFontFaces() { GraphicsEnvironment ge = GraphicsEnvironment .getLocalGraphicsEnvironment(); Font[] fonts = ge.getAllFonts(); Vector list = new Vector(); // Process each font for (int i = 0; i < fonts.length; i++) { // Get font's family and face String familyName = fonts[i].getFamily(); String faceName = fonts[i].getName(); list.add(faceName); } return list; } public void refreshOnUpdate() { disableCaretListener(); textBox.setText(textBox.getText()); enableCaretListener(); textBox.repaint(); } public void disableCaretListener() { textBox.removeCaretListener(this); } public void enableCaretListener() { textBox.addCaretListener(this); } private void addListeners() { /* colorButton.addMouseListener(new MouseAdapter(){ public void mouseClicked(MouseEvent e) { AttributeSet paragraphSet = textBox.getParagraphAttributes(); Color cur = ((Color)paragraphSet.getAttribute(StyleConstants.Foreground)); if (cur == null) cur = Color.black; cur = Util.runColorChooser("Choose Font Color", cur, TextPropsPane.this); textBox.setForegroundAction(cur); } }); boldButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { textBox.boldAction.actionPerformed(e); } }); underlineButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { textBox.underlineAction.actionPerformed(e); } }); italicButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { textBox.italicAction.actionPerformed(e); } }); unorderedListButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { VUE.getFormattingPanel().getTextPropsPane().disableCaretListener(); textBox.actionListUnordered.actionPerformed(e); VUE.getFormattingPanel().getTextPropsPane().enableCaretListener(); } }); orderedListButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { VUE.getFormattingPanel().getTextPropsPane().disableCaretListener(); textBox.actionListOrdered.actionPerformed(e); VUE.getFormattingPanel().getTextPropsPane().enableCaretListener(); } }); alignmentButton.getComboBox().addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent arg0) { try { if (arg0.getStateChange() == ItemEvent.SELECTED) { int val = (new Integer(arg0.getItem().toString())) .intValue(); ///VUE.getFormattingPanel().getTextPropsPane().disableCaretListener(); if (val == 0) textBox.leftAlignmentAction.actionPerformed(null); else if (val == 1) textBox.centerAlignmentAction.actionPerformed(null); else if (val == 2) textBox.rightAlignmentAction.actionPerformed(null); // textBox.setText(textBox.getText()); /// VUE.getFormattingPanel().getTextPropsPane().enableCaretListener(); } } catch(java.lang.IllegalStateException ise) {}; } }); sizeField.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent arg0) { if (arg0.getStateChange() == ItemEvent.SELECTED) textBox.setFontSizeAction(new Integer((String)arg0.getItem()).intValue()); } }); field.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent arg0) { if (arg0.getStateChange() == ItemEvent.SELECTED) textBox.setFontFaceAction((String)arg0.getItem()); } }); */ } private void addComponents() { this.setLayout(new GridBagLayout()); // Labels JLabel label = new JLabel(VueResources .getString("formatting.text.font.label")); JLabel fontSizeLabel = new JLabel(VueResources .getString("formatting.text.size.label")); JLabel fontColorLabel = new JLabel(VueResources .getString("formatting.text.color.label")); field.setSelectedItem(new String("Arial")); sizeField.setSelectedItem(new String("14")); GridBagConstraints c = new GridBagConstraints(); colorButton.setColor(Color.black); // ------------------------------------------------------- // Add the font face field label // ------------------------------------------------------- c.gridx = 0; c.gridy = 0; c.insets = new Insets(10, 25, botPad, GUI.LabelGapRight); // c.gridwidth = GridBagConstraints.RELATIVE; // next-to-last in row c.fill = GridBagConstraints.NONE; // the label never grows c.anchor = GridBagConstraints.EAST; c.weightx = 0.0; // do not expand this.add(label, c); // ------------------------------------------------------- // Add the font face field // ------------------------------------------------------- c.gridx = 1; c.gridwidth = GridBagConstraints.REMAINDER; // last in row c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(10, 0, botPad, 25); // c.gridwidth=3; this.add(field, c); // ------------------------------------------------------- // Add the size label // ------------------------------------------------------- c.gridx = 0; c.gridy = 1; c.insets = labelInsets; c.gridwidth = 1; // c.gridwidth = GridBagConstraints.RELATIVE; // next-to-last in row c.fill = GridBagConstraints.NONE; // the label never grows c.anchor = GridBagConstraints.EAST; c.weightx = 0.0; // do not expand this.add(fontSizeLabel, c); // ------------------------------------------------------- // Add the font size field value // ------------------------------------------------------- c.gridx = 1; c.gridy = 1; // c.gridwidth = GridBagConstraints.REMAINDER; // last in row c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(topPad, 0, botPad, 10); c.weightx = 1; // field value expands horizontally to use all space c.ipadx=10; this.add(sizeField, c); c.ipadx=0; // ------------------------------------------------------- // Add the bold button // ------------------------------------------------------- c.gridx = 2; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = tightInsets; c.weightx = 1.33; this.add(boldButton, c); // ------------------------------------------------------- // Add the italic button // ------------------------------------------------------- c.gridx = 3; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = tightInsets; c.weightx = 1.33; this.add(italicButton, c); // ------------------------------------------------------- // Add the underline button // ------------------------------------------------------- c.gridx = 4; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = tightInsets; c.weightx = 4; this.add(underlineButton, c); // ------------------------------------------------------- // Add the font color label // ------------------------------------------------------- c.gridx = 0; c.gridy = 2; c.insets = labelInsets; // c.gridwidth = GridBagConstraints.RELATIVE; // next-to-last in row c.fill = GridBagConstraints.NONE; // the label never grows c.anchor = GridBagConstraints.EAST; c.weightx = 0.0; // do not expand this.add(fontColorLabel, c); // ------------------------------------------------------- // Add the font colorfield value // ------------------------------------------------------- c.gridx = 1; c.gridy = 2; // c.gridwidth = GridBagConstraints.REMAINDER; // last in row c.anchor = GridBagConstraints.WEST; c.insets = fieldInsets; c.weightx = 1.0; // field value expands horizontally to use all space this.add(colorButton, c); // ------------------------------------------------------- // Add the unordered list button // ------------------------------------------------------- c.gridx = 2; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = tightInsets; c.weightx = 1.33; this.add(unorderedListButton, c); // ------------------------------------------------------- // Add the ordered list button // ------------------------------------------------------- c.gridx = 3; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = tightInsets; c.weightx = 1.33; this.add(orderedListButton, c); // ------------------------------------------------------- // alignment button // ------------------------------------------------------- c.gridx = 4; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; c.insets = tightInsets; c.weightx = 4; alignmentButton.setBorder(BorderFactory.createEmptyBorder()); this.add(alignmentButton, c); } /* * Return the current line number at the Caret position. */ /* * private int getLineAtCaret(JTextComponent component) { int caretPosition = * component.getCaretPosition(); Element root = * component.getDocument().getDefaultRootElement(); return * root.getElementIndex( caretPosition ) + 1; } * * public String getRowOfText() { int offset = textBox.getCaretPosition(); * try { int start = Utilities.getRowStart(textBox, offset); return * textBox.getText(start, offset-start); } catch (BadLocationException e) { // * TODO Auto-generated catch block e.printStackTrace(); } * * return ""; } */ /* * private int getCaretColumnPosition(JTextComponent comp) { int offset = * comp.getCaretPosition(); int column; try { column = offset - * Utilities.getRowStart(comp, offset); } catch (BadLocationException e) { * column = -1; } return column; } */ /* * private boolean enterBulletMode() { //If you're already in bullet mode * the user is misusing this, ignore. if (bulletMode) return false; * bulletMode = true; listDepth++; previousAlignment = * textBox.getAlignmentMode(); * textBox.setAlignmentMode(TextBox.LEFT_JUSTIFY); * * return true; } * * private void exitBulletMode() { bulletMode = false; * textBox.setAlignmentMode(previousAlignment); } * * private void insertBullet() { * * Caret c = textBox.getCaret(); int pos = textBox.getCaretPosition(); try { * Document d = textBox.getDocument(); //You're not at the beginngin of a * new line...so you're gonna //have to take what's on the current line and * put it in the list //fill space * * * * if (getCaretColumnPosition(textBox) > 0) { * textBox.getDocument().insertString(pos-getCaretColumnPosition(textBox),START_UNORDEREDLIST_STRING, * null); } else { * textBox.getDocument().insertString(pos,START_UNORDEREDLIST_STRING, null); } * * * * for (int p=0; p< indentNext;p++) * textBox.getDocument().insertString(Utilities.getRowStart(textBox, pos)," * ",null); // * textBox.setCaretPosition(pos+START_UNORDEREDLIST_STRING.length()); } * catch (BadLocationException e1) { // TODO Auto-generated catch block * e1.printStackTrace(); } } * * * private boolean isThisAList() { return false; } * * private void insertTab() { * * Caret c = textBox.getCaret(); int pos = textBox.getCaretPosition(); try { * Document d = textBox.getDocument(); int begin = pos - * getCaretColumnPosition(textBox); * textBox.getDocument().insertString(begin,INDENT_STRING, null); } catch * (BadLocationException e1) { } } * * private void matchPreviousIndent() { indentNext = * previousRow.indexOf(BULLET); * } */ public void caretUpdate(CaretEvent arg0) { // System.out.println(arg0.toString()); if (textBox != null) { AttributeSet attsSet = textBox.getCharacterAttributes(); AttributeSet paragraphSet = textBox.getParagraphAttributes(); Boolean b = (Boolean) attsSet.getAttribute(StyleConstants.Bold); if (b != null) { boldButton.setSelected(b.booleanValue()); } else boldButton.setSelected(false); b = (Boolean) attsSet.getAttribute(StyleConstants.Underline); if (b != null) underlineButton.setSelected(b.booleanValue()); else underlineButton.setSelected(false); b = (Boolean) attsSet.getAttribute(StyleConstants.Italic); if (b != null) italicButton.setSelected(b.booleanValue()); else italicButton.setSelected(false); Integer ival = ((Integer) attsSet.getAttribute(StyleConstants.Alignment)); int align =0; if (ival != null) align = ival.intValue(); alignmentButton.getComboBox().setSelectedIndex(align); Color cur = ((Color)attsSet.getAttribute(StyleConstants.Foreground)); if (cur != null) { colorButton.setColor(cur); } int size =0; Integer sizeInt = ((Integer)attsSet.getAttribute(StyleConstants.FontSize)); if (sizeInt != null) size = sizeInt.intValue(); if (size > 0) { sizeField.setSelectedItem(new Integer(size).toString()); } String face =((String)attsSet.getAttribute(StyleConstants.FontFamily)); if (face != null) { field.setSelectedItem(face); } } } /* * public void keyTyped(KeyEvent e) { if (bulletMode) { * * * if ((e.getKeyChar() == KeyEvent.VK_TAB)) e.consume(); * * if ((e.getKeyChar() == KeyEvent.VK_ENTER)) { matchPreviousIndent(); * insertBullet(); } } * } * * public void keyPressed(KeyEvent arg0) { if ((arg0.getKeyChar() == * KeyEvent.VK_TAB)) { if (bulletMode) { //if you hit a tab in bullet mode, * and you haven't yet typed any characters you want to //ident the tab. * otherwise you don't want to do anything special insertTab(); listDepth++; * arg0.consume(); } } * * try { if (bulletMode) { if (arg0.getKeyChar() == KeyEvent.VK_BACK_SPACE && * (textBox.getDocument().getText(textBox.getCaretPosition()-1, * 1).equals(BULLET))) { System.out.println("removing a list depth level"); * listDepth--; * * if (listDepth ==0) exitBulletMode(); else { int rowStart = * Utilities.getRowStart(textBox, textBox.getCaretPosition()); * textBox.setCaretPosition(rowStart); // * textBox.getDocument().remove(textBox.getCaretPosition(), 1); * matchPreviousIndent(); // * textBox.getDocument().insertString(textBox.getCaretPosition(),BULLET, * null); previousRow = getRowOfText(); insertBullet(); * System.out.println("move row"); return; } } * } }catch (BadLocationException e1) {} * * * if ((arg0.getKeyChar() == KeyEvent.VK_ENTER)) { previousRow = * getRowOfText(); System.out.println("PREVIOUS ROW: " + previousRow); } } * * public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub * } */ private void out(String s) { System.out.println("TextPropsPane@" + Integer.toHexString(hashCode()) + " " + s); } private void out(String s, Dimension d) { out(VueUtil.pad(' ', 9, s, true) + " " + tufts.Util.out(d)); } private void out(String s, Dimension d, String s2) { out(VueUtil.pad(' ', 9, s, true) + " " + tufts.Util.out(d) + " " + s2); } private void outc(String s) { System.out.println(this + " " + Integer.toHexString(hashCode()) + " " + s); } }