2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2007 - INRIA - Vincent COUVERT
4 * Copyright (C) 2007 - INRIA - Marouane BEN JELLOUL
5 * Copyright (C) 2010-2011 - DIGITEO - Vincent COUVERT
7 * This file must be used under the terms of the CeCILL.
8 * This source file is licensed as described in the file COPYING, which
9 * you should have received as part of this distribution. The terms
10 * are also available at
11 * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
14 package org.scilab.modules.gui.bridge.label;
16 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UI_ICON__;
18 import java.awt.Color;
19 import java.awt.Dimension;
21 import java.awt.Graphics;
22 import java.awt.Graphics2D;
23 import java.awt.GraphicsConfiguration;
24 import java.awt.GraphicsDevice;
25 import java.awt.GraphicsEnvironment;
26 import java.awt.GridBagConstraints;
27 import java.awt.GridBagLayout;
28 import java.awt.Image;
29 import java.awt.image.BufferedImage;
31 import java.io.IOException;
33 import javax.imageio.ImageIO;
34 import javax.swing.BorderFactory;
35 import javax.swing.GrayFilter;
36 import javax.swing.Icon;
37 import javax.swing.ImageIcon;
38 import javax.swing.JComponent;
39 import javax.swing.JEditorPane;
40 import javax.swing.JLabel;
41 import javax.swing.JPanel;
42 import javax.swing.JScrollPane;
43 import javax.swing.JTextPane;
44 import javax.swing.SwingConstants;
45 import javax.swing.UIManager;
46 import javax.swing.border.Border;
47 import javax.swing.event.HyperlinkEvent;
48 import javax.swing.event.HyperlinkListener;
49 import javax.swing.text.html.HTMLDocument;
50 import javax.swing.text.html.StyleSheet;
52 import org.scilab.forge.jlatexmath.TeXConstants;
53 import org.scilab.forge.jlatexmath.TeXFormula;
54 import org.scilab.forge.jlatexmath.TeXIcon;
55 import org.scilab.modules.commons.gui.FindIconHelper;
56 import org.scilab.modules.console.utils.ScilabSpecialTextUtilities;
57 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
58 import org.scilab.modules.gui.SwingViewObject;
59 import org.scilab.modules.gui.SwingViewWidget;
60 import org.scilab.modules.gui.bridge.label.SwingScilabLabel.IconLabel.IconType;
61 import org.scilab.modules.gui.events.callback.CommonCallBack;
62 import org.scilab.modules.gui.label.SimpleLabel;
63 import org.scilab.modules.gui.menubar.MenuBar;
64 import org.scilab.modules.gui.textbox.TextBox;
65 import org.scilab.modules.gui.toolbar.ToolBar;
66 import org.scilab.modules.gui.utils.Position;
67 import org.scilab.modules.gui.utils.PositionConverter;
68 import org.scilab.modules.gui.utils.ScilabAlignment;
69 import org.scilab.modules.gui.utils.ScilabRelief;
70 import org.scilab.modules.gui.utils.ScilabSwingUtilities;
71 import org.scilab.modules.gui.utils.Size;
72 import org.scilab.modules.gui.utils.WebBrowser;
75 * Swing implementation for Scilab Labels in GUIs
76 * @author Vincent COUVERT
77 * @author Marouane BEN JELLOUL
79 public class SwingScilabLabel extends JScrollPane implements SwingViewObject, SimpleLabel {
81 private enum LabelStyle {
82 TEXT, LATEX, MATHML, HTML
85 private static final long serialVersionUID = 7177323379068859441L;
89 private JComponent label = new JLabel(" ");
91 private Border defaultBorder = null;
93 private LabelStyle labelStyle = null;
95 private String horizontalAlignment = "left"; //Horizontal alignment property
97 private String verticalAlignment = "middle"; // Vertical alignment property
99 private final JPanel alignmentPanel = new JPanel(); // Used for alignment
101 private final GridBagLayout alignmentLayout = new GridBagLayout();
103 private String labelText = ""; // Used to save user given text
105 private static HyperlinkListener urlOpener = new HyperlinkListener() {
106 public void hyperlinkUpdate(HyperlinkEvent event) {
107 if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
108 WebBrowser.openUrl(event.getURL(), event.getDescription());
116 public SwingScilabLabel() {
118 alignmentPanel.setLayout(alignmentLayout);
119 setViewportView(label);
120 setBorder(BorderFactory.createEmptyBorder());
121 setViewportBorder(BorderFactory.createEmptyBorder());
122 setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
123 setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
124 // Initialize display
129 * Apply a new font for the label.
130 * @param font new font to use.
132 public void setFont(Font font) {
136 if (labelStyle == LabelStyle.HTML) {
137 StyleSheet styleSheet = ((HTMLDocument) ((JTextPane) label).getDocument()).getStyleSheet();
138 styleSheet.addRule("body {font-family:" + font.getName() + ";}");
139 styleSheet.addRule("body {font-size:" + font.getSize() + "pt;}");
141 styleSheet.addRule("body {font-weight:bold;}");
143 styleSheet.addRule("body {font-weight:normal;}");
145 if (font.isItalic()) {
146 styleSheet.addRule("body {font-style:italic;}");
148 styleSheet.addRule("body {font-style:normal;}");
155 * To set the Foreground color of the element.
156 * @param color the Color
158 public void setForeground(Color color) {
159 super.setForeground(color);
161 label.setForeground(color);
165 public void setEnabled(boolean enabled) {
166 super.setEnabled(enabled);
168 label.setEnabled(enabled);
173 * To set the Background color of the element.
174 * @param color the Color
176 public void setBackground(Color color) {
177 super.setBackground(color);
178 if (alignmentPanel != null) {
179 alignmentPanel.setBackground(color);
182 if (label instanceof JLabel) {
183 ((JLabel) label).setOpaque(true);
185 label.setBackground(color);
190 * Draws a swing Scilab PushButton
191 * @see org.scilab.modules.gui.uielement.UIElement#draw()
194 this.setVisible(true);
199 * Gets the dimensions (width and height) of a swing Scilab element
200 * @return the dimensions of the element
201 * @see org.scilab.modules.gui.uielement.UIElement#getDims()
203 public Size getDims() {
204 return new Size(getWidth(), getHeight());
208 * Gets the position (X-coordinate and Y-coordinate) of a swing Scilab
210 * @return the position of the element
211 * @see org.scilab.modules.gui.uielement.UIElement#getPosition()
213 public Position getPosition() {
214 return PositionConverter.javaToScilab(getLocation(), getSize(), getParent());
218 * Sets the dimensions (width and height) of a swing Scilab element
219 * @param newSize the dimensions to set to the element
220 * @see org.scilab.modules.gui.uielement.UIElement#setDims(org.scilab.modules.gui.utils.Size)
222 public void setDims(Size newSize) {
223 setSize(newSize.getWidth(), newSize.getHeight());
224 // Need validate to force alignement to be applyed
225 setMinimumSize(new Dimension(Math.max((int) label.getMinimumSize().getWidth(), newSize.getWidth()), (int) label.getMinimumSize().getHeight()));
229 * Sets the position (X-coordinate and Y-coordinate) of a swing Scilab
231 * @param newPosition the position to set to the element
232 * @see org.scilab.modules.gui.uielement.UIElement#setPosition(org.scilab.modules.gui.utils.Position)
234 public void setPosition(Position newPosition) {
235 Position javaPosition = PositionConverter.scilabToJava(newPosition, getDims(), getParent());
236 setLocation(javaPosition.getX(), javaPosition.getY());
240 * Add a callback to the Label
241 * @param callback the callback to set.
243 public void setCallback(CommonCallBack callback) {
249 * @param menuBarToAdd the MenuBar associated to the Label.
251 public void addMenuBar(MenuBar menuBarToAdd) {
252 /* Unimplemented for Labels */
253 throw new UnsupportedOperationException();
258 * @param toolBarToAdd the ToolBar associated to the Label.
260 public void addToolBar(ToolBar toolBarToAdd) {
261 /* Unimplemented for Labels */
262 throw new UnsupportedOperationException();
267 * @return MenuBar: the MenuBar associated to the Label.
269 public MenuBar getMenuBar() {
270 /* Unimplemented for Labels */
271 throw new UnsupportedOperationException();
276 * @return ToolBar: the ToolBar associated to the Label.
278 public ToolBar getToolBar() {
279 /* Unimplemented for Labels */
280 throw new UnsupportedOperationException();
284 * Set the horizontal alignment for the Label text
285 * @param alignment the value for the alignment (See ScilabAlignment.java)
287 public void setHorizontalAlignment(String alignment) {
288 horizontalAlignment = alignment;
293 * Set the vertical alignment for the Label text
294 * @param alignment the value for the alignment (See ScilabAlignment.java)
296 public void setVerticalAlignment(String alignment) {
297 verticalAlignment = alignment;
303 * Set the Relief of the Label
304 * @param reliefType the type of the relief to set (See ScilabRelief.java)
306 public void setRelief(String reliefType) {
307 if (defaultBorder == null) {
308 defaultBorder = getBorder();
310 setBorder(ScilabRelief.getBorderFromRelief(reliefType, defaultBorder));
316 public void destroy() {
317 ScilabSwingUtilities.removeFromParent(this);
322 * @param infoBarToAdd the InfoBar associated to the Label.
324 public void addInfoBar(TextBox infoBarToAdd) {
325 /* Unimplemented for Labels */
326 throw new UnsupportedOperationException();
331 * @return the InfoBar associated to the Label.
333 public TextBox getInfoBar() {
334 /* Unimplemented for Labels */
335 throw new UnsupportedOperationException();
339 * get the text displayed in the label
341 * @see org.scilab.modules.gui.text.SimpleText#getText()
343 public String getText() {
348 * Set the text displayed in the label
349 * @param newText the text
350 * @see org.scilab.modules.gui.text.SimpleText#setText(java.lang.String)
352 public void setText(String newText) {
353 // Save the data given by the user so that it can be retrieved
354 // (Java adds HTML tags in the getlabel().getText() returned value)
356 // <math></math> : LateXLabel ( MathML )
357 // <html></html> : JTextPane for clickable links
358 // $...$ : LateXLabel ( LateX )
361 if (newText.equals("")) {
367 if (labelText.startsWith("<math>") && labelText.endsWith("</math>")) {
368 boolean mathML = ScilabSpecialTextUtilities.setText(new JLabel(), labelText);
370 //if MAthML rendering failed use normal renderer ( JLabel)
372 changeLabelType(LabelStyle.MATHML);
373 ((IconLabel) label).setText(labelText);
375 changeLabelType(LabelStyle.TEXT);
376 ((JLabel) label).setText(labelText);
381 if (labelText.startsWith("<html>") && labelText.endsWith("</html>")) {
382 changeLabelType(LabelStyle.HTML);
383 ((JEditorPane) label).setText(labelText);
387 if (labelText.startsWith("$") && labelText.endsWith("$")) {
388 boolean latex = ScilabSpecialTextUtilities.setText(new JLabel(), labelText);
390 //if MAthML rendering failed use normal renderer ( JLabel)
392 changeLabelType(LabelStyle.LATEX);
393 ((IconLabel) label).setText(labelText);
395 changeLabelType(LabelStyle.TEXT);
396 ((JLabel) label).setText(labelText);
401 changeLabelType(LabelStyle.TEXT);
402 ((JLabel) label).setText(labelText);
404 ((JLabel) label).invalidate();
405 ((JLabel) label).validate();
406 ((JLabel) label).repaint();
410 * Change Label type to switch between JLabel abd JEditorPane JLabel is
411 * quicker on simple text JEditorPane can enable HyperLinks
414 private void changeLabelType(LabelStyle style) {
416 if (labelStyle == style) {
421 Color bgColor = label.getBackground();
422 Color fgColor = label.getForeground();
423 Font font = label.getFont();
424 Dimension dims = label.getSize();
425 label.setVisible(false);
427 switch (labelStyle) {
429 alignmentPanel.remove(label);
430 label = new IconLabel(IconType.LATEX);
431 setViewportView(label);
432 setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
435 alignmentPanel.remove(label);
436 label = new IconLabel(IconType.MATHML);
437 setViewportView(label);
438 setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
441 JTextPane newLabel = new JTextPane();
442 newLabel.addHyperlinkListener(urlOpener);
443 newLabel.setContentType("text/html");
444 newLabel.setEditable(false);
445 StyleSheet styleSheet = ((HTMLDocument) newLabel.getDocument()).getStyleSheet();
446 styleSheet.addRule("body {font-family:" + font.getName() + ";}");
447 styleSheet.addRule("body {font-size:" + font.getSize() + "pt;}");
449 styleSheet.addRule("body {font-weight:bold;}");
451 styleSheet.addRule("body {font-weight:normal;}");
453 if (font.isItalic()) {
454 styleSheet.addRule("body {font-style:italic;}");
456 styleSheet.addRule("body {font-style:normal;}");
460 alignmentPanel.add(label);
461 setViewportView(alignmentPanel);
462 setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
466 alignmentPanel.remove(label);
467 label = new JLabel();
468 setViewportView(label);
470 update(__GO_UI_ICON__, GraphicController.getController().getProperty(getId(), __GO_UI_ICON__));
471 ((JLabel) label).setOpaque(false);
472 setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
477 setBackground(bgColor);
478 label.setForeground(fgColor);
481 label.setVisible(true);
486 * Set alignment of the text component
488 private void setAlignment() {
490 if (labelStyle != LabelStyle.HTML) {
491 ((JLabel) label).setVerticalAlignment(ScilabAlignment.toSwingAlignment(verticalAlignment));
492 ((JLabel) label).setHorizontalAlignment(ScilabAlignment.toSwingAlignment(horizontalAlignment));
496 GridBagConstraints gbc = new GridBagConstraints();
505 switch (ScilabAlignment.toSwingAlignment(horizontalAlignment)) {
506 case SwingConstants.LEFT:
507 switch (ScilabAlignment.toSwingAlignment(verticalAlignment)) {
508 case SwingConstants.TOP:
509 gbc.anchor = GridBagConstraints.NORTHWEST;
511 case SwingConstants.CENTER:
512 gbc.anchor = GridBagConstraints.WEST;
514 default: // SwingConstants.BOTTOM
515 gbc.anchor = GridBagConstraints.SOUTHWEST;
519 case SwingConstants.CENTER:
520 switch (ScilabAlignment.toSwingAlignment(verticalAlignment)) {
521 case SwingConstants.TOP:
522 gbc.anchor = GridBagConstraints.NORTH;
524 case SwingConstants.CENTER:
525 gbc.anchor = GridBagConstraints.CENTER;
527 default: // SwingConstants.BOTTOM
528 gbc.anchor = GridBagConstraints.SOUTH;
532 default: // SwingConstants.RIGHT
533 switch (ScilabAlignment.toSwingAlignment(verticalAlignment)) {
534 case SwingConstants.TOP:
535 gbc.anchor = GridBagConstraints.NORTHEAST;
537 case SwingConstants.CENTER:
538 gbc.anchor = GridBagConstraints.EAST;
540 default: // SwingConstants.BOTTOM
541 gbc.anchor = GridBagConstraints.SOUTHEAST;
547 alignmentLayout.setConstraints(label, gbc);
554 public void setId(Integer id) {
562 public Integer getId() {
567 * Generic update method
568 * @param property property name
569 * @param value property value
571 public void update(int property, Object value) {
573 case __GO_UI_ICON__: {
574 if (labelStyle == LabelStyle.TEXT) {
575 String icon = (String) value;
576 if (icon != null && icon.equals("") == false) {
577 File file = new File((String) value);
578 if (file.exists() == false) {
579 String filename = FindIconHelper.findImage((String) value);
580 file = new File(filename);
584 ((JLabel) label).setIcon(new ImageIcon(ImageIO.read(file)));
585 } catch (IOException e) {
588 ((JLabel) label).setIcon(null);
594 SwingViewWidget.update(this, property, value);
599 public void resetBackground() {
600 Color color = (Color) UIManager.getLookAndFeelDefaults().get("Label.background");
602 //bypass setBackground
603 if (label instanceof JLabel) {
604 ((JLabel) label).setOpaque(true);
606 label.setBackground(color);
610 public void resetForeground() {
611 Color color = (Color) UIManager.getLookAndFeelDefaults().get("Label.foreground");
613 label.setForeground(color);
618 * Component to display LaTeX Thank you Calixte
620 public static class IconLabel extends JLabel {
621 public enum IconType {
625 private static final long serialVersionUID = 3885565301114930030L;
626 private final static Font DEFAULTFONT = new Font("serif", Font.PLAIN, 12);
627 private final static boolean isWindows = System.getProperty("os.name").toLowerCase().indexOf("win") != -1;
630 private Icon iconDisable;
631 private float fontSize;
633 private Dimension preferred;
634 IconType type = IconType.MATHML;
636 public IconLabel(IconType type) {
641 preferred = new Dimension(0, 0);
646 * Set the LaTeX content
647 * @param text the LaTeX
649 public void setText(String text) {
655 * Get the LaTeX content
656 * @return the LaTeX string
658 public String getText() {
662 public Dimension getPreferredSize() {
666 public Dimension getMinimumSize() {
667 return getPreferredSize();
670 protected void paintComponent(Graphics g) {
671 super.paintComponent(g);
672 if (isOpaque() && getBackground() != null) {
673 final Color old = g.getColor();
674 g.setColor(getBackground());
675 g.fillRect(0, 0, getWidth(), getHeight());
679 int h = getHorizontalAlignment();
680 int v = getVerticalAlignment();
685 if (h == JLabel.CENTER) {
686 x = (getSize().width - icon.getIconWidth()) / 2;
687 } else if (h == JLabel.RIGHT) {
688 x = getSize().width - icon.getIconWidth();
691 if (v == JLabel.CENTER) {
692 y = (getSize().height - icon.getIconHeight()) / 2;
693 } else if (v == JLabel.BOTTOM) {
694 y = getSize().height - icon.getIconHeight();
697 if (type == IconType.LATEX) {
698 TeXIcon latex = (TeXIcon) icon;
700 latex.setForeground(getForeground());
701 latex.paintIcon(this, g, x, y);
703 if (isWindows && (UIManager.getColor("Label.disabledForeground") instanceof Color) && (UIManager.getColor("Label.disabledShadow") instanceof Color)) {
704 latex.setForeground(UIManager.getColor("Label.disabledShadow"));
705 latex.paintIcon(this, g, x + 1, y + 1);
706 latex.setForeground(UIManager.getColor("Label.disabledForeground"));
707 latex.paintIcon(this, g, x, y);
709 latex.setForeground(getBackground().brighter());
710 latex.paintIcon(this, g, x + 1, y + 1);
711 latex.setForeground(getBackground().darker());
712 latex.paintIcon(this, g, x, y);
716 //enable/disable is made @ icon generation in ScilabSpecialTextUtilities
718 icon.paintIcon(this, g, x, y);
720 icon.paintIcon(this, g, x + 1, y + 1);
721 iconDisable.paintIcon(this, g, x, y);
726 public void setFont(Font f) {
727 this.fontSize = f.getSize2D();
731 public Font getFont() {
736 * Update the component
738 private void update() {
739 if (text.equals("") == false) {
740 if (type == IconType.LATEX) {
741 icon = ScilabSpecialTextUtilities.compileLaTeXExpression(text, (int) fontSize);
744 icon = ScilabSpecialTextUtilities.compileMathMLExpression(text, (int) fontSize);
746 if (isWindows && (UIManager.getColor("Label.disabledForeground") instanceof Color) && (UIManager.getColor("Label.disabledShadow") instanceof Color)) {
747 icon = ScilabSpecialTextUtilities.compileMathMLExpression(text, (int) fontSize, UIManager.getColor("Label.disabledShadow"));
748 iconDisable = ScilabSpecialTextUtilities.compileMathMLExpression(text, (int) fontSize, UIManager.getColor("Label.disabledForeground"));
750 icon = ScilabSpecialTextUtilities.compileMathMLExpression(text, (int) fontSize, getBackground().brighter());
751 iconDisable = ScilabSpecialTextUtilities.compileMathMLExpression(text, (int) fontSize, getBackground().darker());
755 preferred = new Dimension(icon.getIconWidth(), icon.getIconHeight());
760 public void setEnabled(boolean enabled) {
761 super.setEnabled(enabled);