/* * Licensed Materials - Property of Perforce Software, Inc. * © Copyright Perforce Software, Inc. 2014, 2021 * © Copyright IBM Corp. 2009, 2014 * © Copyright ILOG 1996, 2009 * All Rights Reserved. * * Note to U.S. Government Users Restricted Rights: * The Software and Documentation were developed at private expense and * are "Commercial Items" as that term is defined at 48 CFR 2.101, * consisting of "Commercial Computer Software" and * "Commercial Computer Software Documentation", as such terms are * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4, * as applicable. */ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JFrame; import javax.swing.JRootPane; import javax.swing.SwingUtilities; import ilog.views.IlvApplyObject; import ilog.views.IlvGraphic; import ilog.views.IlvManager; import ilog.views.IlvManagerView; import ilog.views.IlvPoint; import ilog.views.IlvRect; import ilog.views.IlvTransformer; import ilog.views.graphic.IlvLine; import ilog.views.graphic.IlvText; /** * This sample shows how the alignment mechanism of rotated text works. * @proofread */ SuppressWarnings("serial") public class RotateAlignText extends JRootPane { { // This sample uses JViews Diagrammer features. When deploying an // application that includes this code, you need to be in possession // of a Perforce JViews Diagrammer Deployment license. // IlvProductUtil.DeploymentLicenseRequired( // IlvProductUtil.JViews_Diagrammer_Deployment); } IlvText text = new IlvText(new IlvPoint(100, 100), "This is a multiline\ntext that\ncan be rotated\nand aligned"); IlvLine normLine = new IlvLine(); IlvLine orthLine = new IlvLine(); IlvManager manager; IlvManagerView view; int initialTextRotationAngle = 10; int initialThresholdAngle = 30; int initialRotationAngle = 45; /** * Initializes the application. */ public void init() { // fill the manager with the text object and the two auxiliary lines manager = new IlvManager(); text.setFont(new Font("arial", Font.BOLD, 15)); text.setAntialiasing(true); text.setFractionalMetrics(true); manager.addObject(text, true); adjust(initialTextRotationAngle, initialRotationAngle, initialThresholdAngle); normLine.setForeground(Color.green); orthLine.setForeground(Color.pink); manager.addObject(normLine, true); manager.addObject(orthLine, true); // create the view view = new IlvManagerView(manager) { Override public void setBounds(int x, int y, int w, int h) { super.setBounds(x, y, w, h); centerText(w, h); } }; view.setBackground(Color.white); view.setAntialiasing(true); // create three dial controls. // The outer dial controls the rotation of the text final JDial outerDial = new JDial(true); outerDial.setAngleColor(new Color(0,200,0)); outerDial.setAngle(initialTextRotationAngle); // the middle dial controls the rotation alignment axes JDial middleDial = new JDial(false); middleDial.setAngleColor(new Color(0,0,200)); middleDial.setAngle(initialRotationAngle); // the innermost dial controls the rotation alignment threshold angle JDial innerDial = new JDial(false); innerDial.setAngleColor(new Color(200,0,0)); innerDial.setShowAngleColorAt4Sides(true); innerDial.setStartAngle(initialRotationAngle); innerDial.setAngle(initialThresholdAngle); // nest the dials and the view inside eachother outerDial.add(middleDial); middleDial.add(innerDial); innerDial.add(view); // configure the labels outerDial.getTopLeftLabel().setForeground(Color.green.darker()); outerDial.getTopRightLabel().setForeground(Color.blue); outerDial.getBottomLeftLabel().setForeground(Color.red.darker()); outerDial.getTopLeftLabel().setText("" + initialTextRotationAngle + " degree"); outerDial.getTopRightLabel().setText("" + initialRotationAngle + " degree"); outerDial.getBottomLeftLabel().setText("" + initialThresholdAngle + " degree"); // outer dial rotates the text outerDial.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent evt) { int angle = ((JDial)evt.getSource()).getAngle(); outerDial.getTopLeftLabel().setText("" + angle + " degree"); adjust(angle, text.getRotationAlignmentAngle(), text.getRotationAlignmentThresholdAngle()); } }); // middle dial sets the rotation alignment angle middleDial.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent evt) { JDial middleDial1 = (JDial)evt.getSource(); int angle = middleDial1.getAngle(); outerDial.getTopRightLabel().setText("" + angle + " degree"); if (angle >= 180) { while (angle >= 180) angle -= 180; // could indicate that the middleDial has only 180 degree range: // middleDial.setAngle(angle); } JDial innerDial1 = (JDial)middleDial1.getContents(); innerDial1.setStartAngle(angle); adjust(getTextAngle(), angle, text.getRotationAlignmentThresholdAngle()); } }); // middle dial sets the rotation alignment angle innerDial.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent evt) { JDial innerDial1 = (JDial)evt.getSource(); int angle = innerDial1.getAngle(); if (angle >= 90) { while (angle >= 90) angle -= 90; innerDial1.setAngle(angle); } outerDial.getBottomLeftLabel().setText("" + angle + " degree"); adjust(getTextAngle(), text.getRotationAlignmentAngle(), angle); } }); getContentPane().setLayout(new BorderLayout(0,0)); getContentPane().add(outerDial, BorderLayout.CENTER); } /** * Adjust the text and the auxiliary lines to the new situation. */ void adjust(final double textAngle, final double rotationAlignmentAngle, final double rotationAlignmentThreshold) { double currentAngle = getTextAngle(); final double deltaAngle = textAngle - currentAngle; text.getGraphicBag().applyToObject(text, new IlvApplyObject() { Override public void apply(IlvGraphic g, Object arg) { text.rotate(new IlvPoint(), deltaAngle); text.setRotationAlignmentAngle(rotationAlignmentAngle); text.setRotationAlignmentThresholdAngle(rotationAlignmentThreshold); } }, null, true); // center the text object if (view != null) { Rectangle r = view.getBounds(); centerText(r.width, r.height); } } /** * Returns the current angle of the text object. */ float getTextAngle() { IlvTransformer t = text.getTransformer(); if (t == null) return 0; return (float)(90 - 180 * Math.atan2(t.getx22(), t.getx21()) / Math.PI); } /** * Center the text object in the view. */ void centerText(final int w, final int h) { // center the text IlvPoint p = text.getEffectiveAnchorPoint(); IlvRect bbox = text.boundingBox(); double dx = p.x - bbox.x; double dy = p.y - bbox.y; double x = w / 2 - dx; double y = h / 2 - dy; manager.moveObject(text, x, y, true); // rotate the two auxiliary lines as necessary manager.applyToObject(normLine, new IlvApplyObject() { Override public void apply(IlvGraphic g, Object arg) { double angle = Math.PI * text.getRotationAlignmentAngle() / 180; int r = Math.max(w, h); IlvPoint p0 = new IlvPoint(w/2 - r * Math.cos(angle), h/2 - r * Math.sin(angle)); IlvPoint p1 = new IlvPoint(w/2 + r * Math.cos(angle), h/2 + r * Math.sin(angle)); normLine.setFrom(p0); normLine.setTo(p1); } }, null, true); manager.applyToObject(normLine, new IlvApplyObject() { Override public void apply(IlvGraphic g, Object arg) { double angle = Math.PI * text.getRotationAlignmentAngle() / 180; int r = Math.max(w, h); IlvPoint p0 = new IlvPoint(w/2 - r * Math.sin(angle), h/2 + r * Math.cos(angle)); IlvPoint p1 = new IlvPoint(w/2 + r * Math.sin(angle), h/2 - r * Math.cos(angle)); orthLine.setFrom(p0); orthLine.setTo(p1); } }, null, true); } /** * The main routine. */ public static void main(String[] args) { // Sun recommends that to put the entire GUI initialization into the // AWT thread SwingUtilities.invokeLater( new Runnable() { Override public void run() { RotateAlignText app = new RotateAlignText(); app.init(); JFrame frame = new JFrame(); frame.setTitle("JViews Rotated Aligned Text Sample"); frame.setSize(600, 620); frame.getContentPane().add(app); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }); } }