package com.horstmann.violet.product.diagram.property.text; import com.horstmann.violet.product.diagram.property.text.decorator.OneLineText; import javax.swing.*; import javax.swing.border.EmptyBorder; import java.awt.*; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.io.Serializable; import java.util.*; import java.util.List; /** * This class is a container for text * * @author Adrian Bobrowski <adrian071993@gmail.com> * @date 16.12.2015 */ public abstract class LineText implements Serializable, Cloneable, EditableText { public interface Converter { /** * converts plain text to one that may contain decorators * @param text * @return */ OneLineText toLineString(String text); } public interface ChangeListener { /** * This function is called when the text is changed */ void onChange(); } public LineText() { this(DEFAULT_CONVERTER); } public LineText(Converter converter) { this.converter = converter; } protected LineText(LineText lineText) throws CloneNotSupportedException { getLabel().setHorizontalAlignment(lineText.getLabel().getHorizontalAlignment()); getLabel().setVerticalAlignment(lineText.getLabel().getVerticalAlignment()); getLabel().setForeground(lineText.getLabel().getForeground()); getLabel().setBorder(lineText.getLabel().getBorder()); getLabel().setText(lineText.getLabel().getText()); converter = lineText.converter; } public final void reconstruction() { this.reconstruction(DEFAULT_CONVERTER); } public void reconstruction(Converter converter) { this.converter = converter; } @Override public LineText clone() { try { return copy(); } catch (CloneNotSupportedException e) { return null; } } protected LineText copy() throws CloneNotSupportedException { return null; } /** * set converter * @param converter * @see Converter */ public final void setConverter(Converter converter) { this.converter = converter; } /** * @return bounds of text in label */ public final Rectangle2D getBounds() { if(null == bounds) { bounds = new Rectangle2D.Double(0, 0, 0, 0); } return bounds; } public final void setText(EditableText text) { setText(text.toEdit()); } /** * @return label color */ public final Color getTextColor() { return getLabel().getForeground(); } /** * sets label color * @param color */ public final void setTextColor(Color color) { getLabel().setForeground(color); } /** * sets label padding * @param padding */ public final void setPadding(int padding) { setPadding(padding, padding); } /** * sets label padding * @param vertical * @param horizontal */ public final void setPadding(int vertical, int horizontal) { setPadding(vertical, horizontal, vertical, horizontal); } /** * sets label padding * @param top * @param left * @param bottom * @param right */ public final void setPadding(int top, int left, int bottom, int right) { getLabel().setBorder(new EmptyBorder(top, left, bottom, right)); refresh(); } /** * sets label alignments * @param flag * LEFT * CENTER * RIGHT */ public final void setAlignment(int flag) { getLabel().setHorizontalAlignment(flag); refresh(); } /** * @return label alignments */ public final int getAlignment() { return getLabel().getHorizontalAlignment(); } /** * Draws text with specific size * @param graphics * @param rect */ public final void draw(Graphics2D graphics, Rectangle2D rect) { getLabel().setBounds(0, 0, (int) rect.getWidth(), (int) rect.getHeight()); draw(graphics, new Point2D.Double(rect.getX(), rect.getY())); } /** * Draws text shifted by offset * @param graphics * @param point */ public final void draw(Graphics2D graphics, Point2D point) { graphics.translate(point.getX(), point.getY()); getLabel().paint(graphics); graphics.translate(-point.getX(), -point.getY()); } /** * Draws text * @param graphics */ public final void draw(Graphics2D graphics) { getLabel().setBounds(0, 0, (int) getBounds().getWidth(), (int) getBounds().getHeight()); draw(graphics, new Point2D.Double(0, 0)); } /** * add listener * @param changeListener */ public final void addChangeListener(ChangeListener changeListener) { if(null == changeListener) { throw new NullPointerException("ChangeListener can't be null"); } getChangeListeners().add(changeListener); } /** * notify all listeners that there is a change */ protected final void notifyAboutChange() { for (ChangeListener changeListener : getChangeListeners()) { changeListener.onChange(); } } /** * set text to label * @param text */ protected final void setLabelText(String text) { if(text.isEmpty()) { getLabel().setText(""); } else { getLabel().setText("<html>"+text+"<html>"); } refresh(); } /** * Recalculate preferred size for text */ private void refresh() { if(getLabel().getText().isEmpty()) { this.bounds = new Rectangle2D.Double(0, 0, 0, 0); } else { Dimension dimension = getLabel().getPreferredSize(); this.bounds = new Rectangle2D.Double(0, 0, dimension.getWidth(), dimension.getHeight()); } } /** * @return label * @see JLabel */ private JLabel getLabel() { if (null == label || null == label.getText()) { label = new JLabel(""); } return label; } /** * @return list of listeners */ private List<ChangeListener> getChangeListeners() { if(null == changeListeners) { changeListeners = new ArrayList<ChangeListener>(); } return changeListeners; } public static final Converter DEFAULT_CONVERTER = new Converter() { @Override public OneLineText toLineString(String text) { return new OneLineText(text); } }; public static final int LEFT = SwingConstants.LEFT; public static final int CENTER = SwingConstants.CENTER; public static final int RIGHT = SwingConstants.RIGHT; protected transient Converter converter; private transient JLabel label; private transient Rectangle2D bounds; private transient List<ChangeListener> changeListeners; }