1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.scenegraph.swing;
\r
14 import java.awt.Color;
\r
15 import java.awt.Font;
\r
16 import java.awt.FontMetrics;
\r
17 import java.awt.Graphics2D;
\r
18 import java.awt.event.ActionEvent;
\r
19 import java.awt.event.ActionListener;
\r
20 import java.awt.event.FocusEvent;
\r
21 import java.awt.event.FocusListener;
\r
22 import java.awt.geom.Rectangle2D;
\r
23 import java.beans.PropertyChangeEvent;
\r
24 import java.beans.PropertyChangeListener;
\r
26 import javax.swing.JTextField;
\r
27 import javax.swing.border.Border;
\r
29 import org.simantics.scenegraph.utils.InitValueSupport;
\r
31 public class SymbolMonitorNode extends ComponentNode<JTextField> implements ActionListener, FocusListener, PropertyChangeListener, InitValueSupport {
\r
33 private static final long serialVersionUID = 6438147255141035799L;
\r
35 final static private Font defaultFont = Font.decode("Arial 3");
\r
37 protected boolean editable = false;
\r
39 protected String value = "";
\r
41 protected transient ActionListener actionListener = null;
\r
43 private boolean doResize = false;
\r
45 protected Font font = null;
\r
46 protected Color color = null;
\r
48 static class TextField extends JTextField {
\r
49 private static final long serialVersionUID = -668522226693100386L;
\r
51 // workaround for 4530952
\r
53 public void setText(String s) {
\r
54 if (getText().equals(s)) {
\r
61 public void setBorder(Border border) {
\r
62 super.setBorder(null);
\r
65 public void setBorder(double borderWidth) {
\r
66 super.setBorder(null);
\r
71 public String toString() {
\r
72 return super.toString() + "[editable=" + editable + ", value=" + value + "]";
\r
76 public void init() {
\r
77 component = new TextField();
\r
78 component.setEditable(editable);
\r
79 component.setEnabled(editable);
\r
80 component.addActionListener(this);
\r
81 component.addFocusListener(this);
\r
86 @SyncField("editable")
\r
87 public void setEditable(boolean value) {
\r
88 this.editable = value;
\r
90 if(component != null) {
\r
91 component.setEditable(value);
\r
92 component.setEnabled(value);
\r
96 // private static final FontRenderContext FRC =
\r
97 // new FontRenderContext(
\r
98 // new AffineTransform(),
\r
101 @SyncField("value")
\r
102 public void setText(String value) {
\r
103 this.value = value;
\r
105 if(value == null) {
\r
112 // RemoteViewer does not have component initialized
\r
113 if (component != null) {
\r
114 component.setText(value);
\r
121 public void setFont(Font font) {
\r
123 if (component != null) {
\r
124 setComponentFont(font);
\r
129 @SyncField("color")
\r
130 public void setColor(Color color) {
\r
131 this.color = color;
\r
132 if (component != null) {
\r
133 component.setForeground(color);
\r
139 public void render(Graphics2D g2d) {
\r
142 recalculateSize(g2d);
\r
144 // TODO: fix this!!
\r
145 component.setScrollOffset(0);
\r
149 private void recalculateSize(Graphics2D g2d) {
\r
150 if(component == null || value == null) return;
\r
151 Font font = component.getFont();
\r
152 if (font != null) {
\r
153 FontMetrics metrics = component.getFontMetrics(font);
\r
154 Rectangle2D size = metrics.getStringBounds(value, g2d);
\r
157 setBounds(new Rectangle2D.Double(0, 0, xPadding + (int) Math.ceil(size.getWidth()), yPadding + (int) Math.ceil(size.getHeight())));
\r
158 component.setScrollOffset(0);
\r
162 public String getText() {
\r
167 public void propertyChange(PropertyChangeEvent evt) {
\r
168 if("value".equals(evt.getPropertyName()) && component != null) {
\r
169 component.setText((String)evt.getNewValue());
\r
171 } else if("editable".equals(evt.getPropertyName()) && component != null) {
\r
172 component.setEditable((Boolean)evt.getNewValue());
\r
173 component.setEnabled((Boolean)evt.getNewValue());
\r
178 public void setActionListener(ActionListener actionListener) {
\r
179 this.actionListener = actionListener;
\r
183 public void actionPerformed(ActionEvent e) {
\r
184 // performAction(e);
\r
185 if(container.getParent() != null)
\r
186 container.getParent().requestFocusInWindow(); // Loose focus
\r
190 public void focusGained(FocusEvent arg0) {
\r
194 public void focusLost(FocusEvent arg0) {
\r
195 ActionEvent e = new ActionEvent(component, ActionEvent.ACTION_PERFORMED, ((TextField)component).getText());
\r
200 * Wrapper method to send event to serverside
\r
205 public void performAction(ActionEvent e) {
\r
206 if(actionListener != null)
\r
207 actionListener.actionPerformed(e);
\r
210 public void setValue(String key, Object value) {
\r
211 if("text".equals(key)) {
\r
212 // System.out.println("monitornode text -> " + value);
\r
213 if(value instanceof String) {
\r
214 setText((String)value);
\r
216 String error = "monitornode expects a string as 'text' (got " + (value != null ? value.getClass().getName() : "null") + ").";
\r
217 System.out.println(error);
\r
221 if("font".equals(key)) {
\r
222 // System.out.println("monitornode font -> " + value);
\r
223 setFont(Font.decode((String)value));
\r
228 public void initValues() {
\r
230 setFont(defaultFont);
\r