package iiuf.swing.graph; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridBagLayout; import java.awt.GridBagConstraints; import java.awt.GraphicsEnvironment; import java.awt.Dimension; import java.awt.Font; import java.awt.Stroke; import java.awt.BasicStroke; import java.awt.Shape; import java.util.ArrayList; import java.util.Enumeration; import java.util.Dictionary; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.JPanel; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JCheckBox; import javax.swing.JRadioButton; import javax.swing.JColorChooser; import javax.swing.JSlider; import javax.swing.JComponent; import javax.swing.AbstractButton; import javax.swing.DefaultListCellRenderer; import javax.swing.ButtonGroup; import javax.swing.SwingConstants; import javax.swing.event.ChangeListener; import javax.swing.event.ChangeEvent; import javax.swing.border.EmptyBorder; import javax.swing.plaf.basic.BasicComboBoxEditor; import iiuf.awt.Awt; import iiuf.util.Attributable; import iiuf.util.Preferences; import iiuf.swing.Resource; import iiuf.swing.LocatedIcon; import iiuf.swing.JNumberField; import iiuf.swing.SetSelectionModel; import iiuf.util.graph.GraphNode; /** Editor panel for component font, alignment, foreground color and background color.<p> (c) 2001, DIUF<p> @author $Author: ohitz $ @version $Name: $ $Revision: 1.1 $ */ public class StyleEditor extends JPanel implements ChangeListener { static final String GP_NULL = "Graph panel not set. Call setGraphPanel() first."; private static final int P_SIZE = 0x001; private static final int P_FONT = 0x002; private static final int P_HALIGN = 0x004; private static final int P_VALIGN = 0x008; private static final int P_BCOLOR = 0x010; private static final int P_FCOLOR = 0x020; private static final int P_BOLD = 0x040; private static final int P_ITALIC = 0x080; private static final int P_FONT_ALL = 0x100; private static final String PREFS = "cmp_style_editor.dtyle"; protected GraphPanel gp; Style userStyle; Style selStyle; JComboBox font; JComboBox size = new JComboBox(new String[] {"8", "9", "10", "11", "12", "14", "16", "18", "20", "22", "24", "26", "28", "36", "48", "72"}); ColorIcon color = new ColorIcon(); JLabel colorc = new JLabel(color); JCheckBox bold = new JCheckBox(Resource.BOLD); JCheckBox italic = new JCheckBox(Resource.ITALIC); JCheckBox anorth = new JCheckBox(Resource.ALIGN_NORTH); JCheckBox aeast = new JCheckBox(Resource.ALIGN_EAST); JCheckBox asouth = new JCheckBox(Resource.ALIGN_SOUTH); JCheckBox awest = new JCheckBox(Resource.ALIGN_WEST); JCheckBox acenterh = new JCheckBox(Resource.ALIGN_CENTERH); JCheckBox acenterv = new JCheckBox(Resource.ALIGN_CENTERV); int selectFontCnt; JPanel alignp = new JPanel(); public StyleEditor(GraphPanel graphPanel) { setGraphPanel(graphPanel); userStyle = (Style)Preferences.get(PREFS, new Style()); colorc.setBorder(new EmptyBorder(5, 5, 5, 5)); size.setEditor(new FontSizeEditor()); size.setEditable(true); size.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setSizes(); } }); bold.setSelectedIcon(Resource.BOLD_SEL); bold.setHorizontalAlignment(SwingConstants.RIGHT); bold.setBorder(new EmptyBorder(0, 4, 0, 0)); bold.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setBold(((JCheckBox)e.getSource()).isSelected()); } }); italic.setSelectedIcon(Resource.ITALIC_SEL); italic.setHorizontalAlignment(SwingConstants.LEFT); italic.setBorder(new EmptyBorder(0, 0, 0, 4)); italic.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setItalic(((JCheckBox)e.getSource()).isSelected()); } }); ArrayList fontsa = new ArrayList(); fontsa.add("?"); String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); for(int i = 0; i < fonts.length; i++) if(fonts[i].length() > 2) fontsa.add(fonts[i]); font = new JComboBox(fontsa.toArray()); font.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setFonts(); } }); ButtonGroup valign = new ButtonGroup(); anorth.setSelectedIcon(Resource.ALIGN_NORTH_SEL); anorth.setBorder(new EmptyBorder(0, 4, 0, 0)); anorth.setHorizontalAlignment(SwingConstants.RIGHT); anorth.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {setVAligns(SwingConstants.TOP);}}); valign.add(anorth); acenterv.setSelectedIcon(Resource.ALIGN_CENTERV_SEL); acenterv.setBorder(null); acenterv.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {setVAligns(SwingConstants.CENTER);}}); valign.add(acenterv); asouth.setSelectedIcon(Resource.ALIGN_SOUTH_SEL); asouth.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {setVAligns(SwingConstants.BOTTOM);}}); asouth.setHorizontalAlignment(SwingConstants.LEFT); asouth.setBorder(new EmptyBorder(0, 0, 0, 4)); valign.add(asouth); ButtonGroup halign = new ButtonGroup(); awest.setSelectedIcon(Resource.ALIGN_WEST_SEL); awest.setBorder(new EmptyBorder(0, 4, 0, 0)); awest.setHorizontalAlignment(SwingConstants.RIGHT); awest.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {setHAligns(SwingConstants.LEFT);}}); halign.add(awest); acenterh.setSelectedIcon(Resource.ALIGN_CENTERH_SEL); acenterh.setBorder(null); acenterh.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {setHAligns(SwingConstants.CENTER);}}); halign.add(acenterh); aeast.setSelectedIcon(Resource.ALIGN_EAST_SEL); aeast.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {setHAligns(SwingConstants.RIGHT);}}); halign.add(aeast); setLayout(new GridBagLayout()); alignp.add(anorth); alignp.add(acenterv); alignp.add(asouth); alignp.add(awest); alignp.add(acenterh); alignp.add(aeast); alignp.setBorder(null); add(alignp, Awt.constraints(true)); add(size, Awt.constraints(false)); add(colorc, Awt.constraints(false)); add(bold, Awt.constraints(false)); add(italic, Awt.constraints(true)); add(font, Awt.constraints(true, GridBagConstraints.HORIZONTAL)); colorc.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { int x = e.getX() - color.getX(); int y = e.getY() - color.getY(); if(x > 10 && x < 17 && y > 0 && y < 5) { Color c = getCurrStyle().foreground; getCurrStyle().foreground = getCurrStyle().background; getCurrStyle().background = c; setBackgrounds(); setForegrounds(); e.getComponent().repaint(); } else if(x > 0 && x < 10 && y > 0 && y < 10) { Color c = JColorChooser.showDialog(StyleEditor.this, "Foreground color", getCurrStyle().foreground); if(c != null) { getCurrStyle().foreground = c; setForegrounds(); } } else if(x > 5 && x < 17 && y > 5 && y < 17) { Color c = JColorChooser.showDialog(StyleEditor.this, "Background color", getCurrStyle().background); if(c != null) { getCurrStyle().background = c; setBackgrounds(); } } e.getComponent().repaint(); } }); setupUI(userStyle); } private void setupUI(Style style) { size.getEditor().setItem(style.font.getSize() + ""); bold.setSelected((style.font.getStyle() & Font.BOLD) != 0); italic.setSelected((style.font.getStyle() & Font.ITALIC) != 0); selectFont(style.font.getFamily()); switch(style.vAlign) { case SwingConstants.TOP: anorth.setSelected(true); break; case SwingConstants.CENTER: acenterv.setSelected(true); break; case SwingConstants.BOTTOM: asouth.setSelected(true); break; } switch(style.hAlign) { case SwingConstants.LEFT: awest.setSelected(true); break; case SwingConstants.CENTER: acenterh.setSelected(true); break; case SwingConstants.RIGHT: aeast.setSelected(true); break; } } public static Style getStyle(Component c) { return new Style(c); } public static Component setStyle(Component c, Style style) { style.set(c); return c; } public void preset(Component c, boolean dontColorize) { Color svb = getCurrStyle().background; Color svf = getCurrStyle().foreground; if(dontColorize) { getCurrStyle().background = c.getBackground(); getCurrStyle().foreground = c.getForeground(); } setStyle(c, getCurrStyle()); getCurrStyle().background = svb; getCurrStyle().foreground = svf; } void setHAligns(int align) { if(gp != null) { Object[] sel = gp.getSelectionModel().getSelection(); for(int i = 0; i < sel.length; i++) setProperty(P_HALIGN, sel[i], align); userStyle.vAlign = align; Preferences.set(PREFS, userStyle); } } void setVAligns(int align) { if(gp != null) { Object[] sel = gp.getSelectionModel().getSelection(); for(int i = 0; i < sel.length; i++) setProperty(P_VALIGN, sel[i], align); userStyle.hAlign = align; Preferences.set(PREFS, userStyle); } } void setFonts() { if(gp != null && selectFontCnt == 0) { Object[] sel = gp.getSelectionModel().getSelection(); String f = (String)font.getSelectedItem(); if(f == null || f.equals("?")) return; for(int i = 0; i < sel.length; i++) setProperty(P_FONT, sel[i], f); userStyle.font = new Font(f, userStyle.font.getStyle(), userStyle.font.getSize()); Preferences.set(PREFS, userStyle); } } void setSizes() { if(gp != null) { Object[] sel = gp.getSelectionModel().getSelection(); try { float sz = Float.parseFloat((String)size.getEditor().getItem()); for(int i = 0; i < sel.length; i++) setProperty(P_SIZE, sel[i], sz); userStyle.font = userStyle.font.deriveFont(sz); Preferences.set(PREFS, userStyle); } catch(Exception e) {} } } void setBold(boolean state) { if(gp != null) { Object[] sel = gp.getSelectionModel().getSelection(); for(int i = 0; i < sel.length; i++) if(sel[i] instanceof Attributable) setProperty(P_BOLD, sel[i], state); if(state) userStyle.font = userStyle.font.deriveFont(userStyle.font.getStyle() | Font.BOLD); else userStyle.font = userStyle.font.deriveFont(userStyle.font.getStyle() & ~Font.BOLD); Preferences.set(PREFS, userStyle); } } void setItalic(boolean state) { if(gp != null) { Object[] sel = gp.getSelectionModel().getSelection(); for(int i = 0; i < sel.length; i++) if(sel[i] instanceof Attributable) setProperty(P_ITALIC, sel[i], state); if(state) userStyle.font = userStyle.font.deriveFont(userStyle.font.getStyle() | Font.ITALIC); else userStyle.font = userStyle.font.deriveFont(userStyle.font.getStyle() & ~Font.ITALIC); } } void setBackgrounds() { if(getCurrStyle().background == null) return; if(gp != null) { Object[] sel = gp.getSelectionModel().getSelection(); for(int i = 0; i < sel.length; i++) setProperty(P_BCOLOR, sel[i], getCurrStyle().background); userStyle.background = getCurrStyle().background; } } void setForegrounds() { if(getCurrStyle().foreground == null) return; if(gp != null) { Object[] sel = gp.getSelectionModel().getSelection(); for(int i = 0; i < sel.length; i++) setProperty(P_FCOLOR, sel[i], getCurrStyle().foreground); userStyle.foreground = getCurrStyle().foreground; } } public void setGraphPanel(GraphPanel graphPanel) { if(graphPanel == gp) return; if(gp != null) gp.getSelectionModel().removeChangeListener(this); gp = graphPanel; gp.getSelectionModel().addChangeListener(this); } public Dimension getMaximumSize() { return getPreferredSize(); } public void stateChanged(ChangeEvent e) { SetSelectionModel sm = (SetSelectionModel)e.getSource(); Attributable[] sel = (Attributable[])sm.getSelection(Attributable.class); int cmpCnt = 0; for(int i = 0; i < sel.length; i++) if(sel[i].get(gp.COMPONENT) != null) cmpCnt++; Component[] cmps = new Component[cmpCnt]; cmpCnt = 0; for(int i = 0; i < sel.length; i++) { Component c = (Component)sel[i].get(gp.COMPONENT); if(c != null) cmps[cmpCnt++] = c; } set(cmps); } Component getCmp(Component cmp) { if(cmp instanceof JSlider) { Dictionary d = ((JSlider)cmp).getLabelTable(); if(d != null) { for(Enumeration e = d.elements(); e.hasMoreElements();) { Object o = e.nextElement(); if(o instanceof JLabel) { cmp = (Component)o; break; } } } } return cmp; } void set(Component[] c) { String ff = null; int sz = -1; int st = -1; int ha = -1; int va = -1; Color fg = null; Color bg = null; boolean enAlign = false; if(c != null && c.length != 0) { Component cmp = getCmp(c[0]); fg = cmp.getForeground(); bg = cmp.getBackground(); ff = cmp.getFont().getFamily(); sz = cmp.getFont().getSize(); st = cmp.getFont().getStyle(); for(int i = 0; i < c.length; i++) { cmp = getCmp(c[i]); if(fg != null && !fg.equals(cmp.getForeground())) fg = null; if(bg != null && !bg.equals(cmp.getBackground())) bg = null; if(ff != null && !ff.equals(cmp.getFont().getFamily())) ff = null; if(sz != -1 && cmp.getFont().getSize() != sz) sz = -1; if(st != -1 && cmp.getFont().getStyle() != st) st = -1; if(cmp instanceof JLabel) { ha = ((JLabel)cmp).getHorizontalAlignment(); va = ((JLabel)cmp).getVerticalAlignment(); } if(cmp instanceof AbstractButton) { ha = ((AbstractButton)cmp).getHorizontalAlignment(); va = ((AbstractButton)cmp).getVerticalAlignment(); } } selStyle = new Style(ff, st, sz, ha, va, bg, fg); } else { selStyle = null; } setupUI(getCurrStyle()); repaint(); } void selectFont(String family) { selectFontCnt++; for(int i = 0; i < font.getItemCount(); i++) if(font.getItemAt(i).equals(family)) { font.setSelectedIndex(i); selectFontCnt--; return; } font.setSelectedIndex(0); selectFontCnt--; } static class FontSizeEditor extends BasicComboBoxEditor { FontSizeEditor() { editor = new JNumberField(5, 1, 1000); } } class ColorIcon extends LocatedIcon { ColorIcon() { super(Resource.TWO_COLOR); } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); if(getCurrStyle().foreground != null) { g.setColor(getCurrStyle().foreground); g.fillRect(x + 1, y + 1, 9, 9); } if(getCurrStyle().background != null ) { g.setColor(getCurrStyle().background); g.fillRect(x + 6, y + 11, 9, 4); g.fillRect(x + 11, y + 6, 4, 5); } } } public Style getCurrStyle() { return selStyle == null ? userStyle : selStyle; } private boolean setPrefs; private void setProperty(int property, Object o, int i) {setProperty(property, o, i, null, null, false, null);} private void setProperty(int property, Object o, float f) {setProperty(property, o, f, null, null, false, null);} private void setProperty(int property, Object o, String s) {setProperty(property, o, 0, s, null, false, null);} private void setProperty(int property, Object o, Color col) {setProperty(property, o, 0, null, col, false, null);} private void setProperty(int property, Object o, boolean b) {setProperty(property, o, 0, null, null, b, null);} private void setProperty(Component c, Font f) {setProperty(P_FONT_ALL, c, 0, null, null, false, f);} private void setProperty(int property, Object o, double d, String s, Color col, boolean b, Font f) { if(o == null) return; if(o instanceof Attributable) setProperty(property, ((Attributable)o).get(gp.COMPONENT), d, s, col, b, f); if(o instanceof Container) { Object[] os = ((Container)o).getComponents(); for(int i = 0; i < os.length; i++) setProperty(property, os[i], d, s, col, b, f); } if(o instanceof JSlider) { for(Enumeration e = ((JSlider)o).getLabelTable().elements(); e.hasMoreElements();) setProperty(property, e.nextElement(), d, s, col, b, f); ((Component)o).repaint(); } else if(o instanceof Component) { Component c = (Component)o; switch(property) { case P_SIZE: c.setFont(c.getFont().deriveFont((float)d)); break; case P_FONT: c.setFont(new Font(s, c.getFont().getStyle(), c.getFont().getSize())); break; case P_HALIGN: if(!validHorizontalKey((int)d)) break; if(c instanceof AbstractButton) ((AbstractButton)c).setHorizontalAlignment((int)d); else if(c instanceof JLabel) ((JLabel)c).setHorizontalAlignment((int)d); break; case P_VALIGN: if(!validVerticalKey((int)d)) break; if(c instanceof AbstractButton) ((AbstractButton)c).setVerticalAlignment((int)d); else if(c instanceof JLabel) ((JLabel)c).setVerticalAlignment((int)d); break; case P_BCOLOR: c.setBackground(col); break; case P_FCOLOR: c.setForeground(col); break; case P_BOLD: c.setFont(c.getFont().deriveFont(b ? c.getFont().getStyle() | Font.BOLD : c.getFont().getStyle() & ~Font.BOLD)); break; case P_ITALIC: c.setFont(c.getFont().deriveFont(b ? c.getFont().getStyle() | Font.ITALIC : c.getFont().getStyle() & ~Font.ITALIC)); break; case P_FONT_ALL: c.setFont(f); break; } } } public static class Style implements Cloneable, java.io.Serializable { int hAlign; int vAlign; Color background; Color foreground; Font font; Style() { hAlign = SwingConstants.CENTER; vAlign = SwingConstants.CENTER; background = Color.white; foreground = Color.black; font = new Font("Dialog", Font.PLAIN, 12); } Style(String font_, int style, int size, int halign, int valign, Color back, Color fore) { hAlign = halign; vAlign = valign; background = back; foreground = fore; try {font = new Font(font_, style, size);} catch(Exception e) {} } Style(Component c) { if(c instanceof JLabel) { hAlign = ((JLabel)c).getHorizontalAlignment(); vAlign = ((JLabel)c).getVerticalAlignment(); } if(c instanceof AbstractButton) { hAlign = ((AbstractButton)c).getHorizontalAlignment(); vAlign = ((AbstractButton)c).getVerticalAlignment(); } background = c.getBackground(); foreground = c.getForeground(); font = c.getFont(); } void set(Component c) { if(c instanceof Container) { Component[] cmps = ((Container)c).getComponents(); for(int i = 0; i < cmps.length; i++) set(cmps[i]); } if(c instanceof JLabel) { if(validHorizontalKey(hAlign)) ((JLabel)c).setHorizontalAlignment(hAlign); if(validVerticalKey(vAlign)) ((JLabel)c).setVerticalAlignment(vAlign); } if(c instanceof AbstractButton) { if(validHorizontalKey(hAlign)) ((AbstractButton)c).setHorizontalAlignment(hAlign); if(validVerticalKey(vAlign)) ((AbstractButton)c).setVerticalAlignment(vAlign); } if(c instanceof JSlider) { for(Enumeration e = ((JSlider)c).getLabelTable().elements(); e.hasMoreElements();) set((Component)e.nextElement()); c.repaint(); } if(font != null) c.setFont(font); if(foreground != null) c.setForeground(foreground); if(background != null) c.setBackground(background); } public Object clone() { try{return super.clone();}catch(Exception e){return null;} } } static boolean validHorizontalKey(int key) { return ((key == SwingConstants.LEFT) || (key == SwingConstants.CENTER) || (key == SwingConstants.RIGHT) || (key == SwingConstants.LEADING) || (key == SwingConstants.TRAILING)); } static boolean validVerticalKey(int key) { return ((key == SwingConstants.TOP) || (key == SwingConstants.CENTER) || (key == SwingConstants.BOTTOM)); } } /* $Log: StyleEditor.java,v $ Revision 1.1 2002/07/11 12:09:52 ohitz Initial checkin Revision 1.4 2001/03/15 16:05:13 schubige cleanup and various fixes Revision 1.3 2001/03/12 17:52:00 schubige Added version support to sourcewatch and enhanced soundium Revision 1.2 2001/03/11 17:59:39 schubige Fixed various soundium and iiuf.swing.graph bugs Revision 1.1 2001/03/09 15:55:08 schubige Added markers to graph panel Revision 1.2 2001/03/07 17:36:28 schubige soundium properties panel beta Revision 1.1 2001/03/07 07:52:07 schubige soundium properites panel */