Question & Answer
Question
How do you automatically adjust the dimensions of diagram elements to fit their contents using the IBM Rational Rhapsody API?
Cause
You would like to automatically calculate and adjust the width and height of a diagram element so that the full text fits within the element..
Answer
All source code and/or binaries attached to this document are referred to here as "the Program". IBM is not providing program services of any kind for the Program. IBM is providing the Program on an "AS IS" basis without warranty of any kind. IBM WILL NOT BE LIABLE FOR ANY ACTUAL, DIRECT, SPECIAL, INCIDENTAL, OR INDIRECT DAMAGES OR FOR ANY ECONOMIC CONSEQUENTIAL DAMAGES (INCLUDING LOST PROFITS OR SAVINGS), EVEN IF IBM, OR ITS RESELLER, HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. |
---|
This is possible using the IBM Rational Rhapsody API.
You must do the following:
- Retrieve the font information from the diagram element
- Render the text in a separate Canvas object using that font data and calculate its dimensions in pixels
- Set the width and height of the diagram element using these dimensions so that the full text fits within the element.
For example:
import java.awt.Canvas;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.font.TextAttribute;
import java.awt.font.TextMeasurer;
import java.awt.geom.Rectangle2D;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.util.List;
import com.telelogic.rhapsody.core.IRPApplication;
import com.telelogic.rhapsody.core.IRPDiagram;
import com.telelogic.rhapsody.core.IRPGraphElement;
import com.telelogic.rhapsody.core.IRPModelElement;
import com.telelogic.rhapsody.core.IRPState;
import com.telelogic.rhapsody.core.RhapsodyAppServer;
public class Test {
public static void main(String[] args) {
IRPApplication app = RhapsodyAppServer.getActiveRhapsodyApplication();
IRPDiagram diagram = (IRPDiagram)app.getSelectedElement();
if(diagram instanceof IRPDiagram) {
List<IRPGraphElement> lGrElements = diagram.getGraphicalElements().toList();
for (IRPGraphElement grElement : lGrElements) {
IRPModelElement grElementMoEl = grElement.getModelObject();
IRPState state = null;
try {
state = (IRPState) grElementMoEl;
if (state != null) {
String actionBody = state.getEntryAction();
if (!actionBody.isEmpty()) {
String fontName = grElement.getGraphicalProperty("TextFontName").getValue();
String fontSizeString = grElement.getGraphicalProperty("TextFontSize").getValue();
String[] splittedLines = actionBody.split("\\r?\\n");
int maxWidthInt = 0, maxHeightInt = 0, fontSize = 0;
double maxWidthDouble = 0, maxHeightDouble = 0;
if (fontSizeString.isEmpty()) {
fontSize = 10; // Default value
} else {
fontSize = Integer.parseInt(fontSizeString);
}
int screenRes = java.awt.Toolkit.getDefaultToolkit().getScreenResolution();
int fontSizeNew = (int) Math.round(fontSize * (screenRes / 60));
Font f = new Font(fontName, Font.PLAIN, fontSizeNew);
Canvas c = new Canvas();
FontMetrics fm = c.getFontMetrics(f);
for (int i = 0; i < splittedLines.length; i++) {
AttributedString as = new AttributedString(splittedLines[i]);
as.addAttribute(TextAttribute.FONT, f);
AttributedCharacterIterator aci = as.getIterator();
TextMeasurer tm = new TextMeasurer(aci, fm.getFontRenderContext());
Rectangle2D r2d = tm.getLayout(0, aci.getEndIndex()).getBounds();
if (r2d.getWidth() > maxWidthDouble) {
maxWidthDouble = r2d.getMaxX();
}
maxHeightDouble += (r2d.getHeight() + r2d.getMaxY()) ;
}
maxHeightInt = (int) Math.round(maxHeightDouble);
maxWidthInt = (int) Math.round(maxWidthDouble);
grElement.setGraphicalProperty("Width", String.valueOf(maxWidthInt));
grElement.setGraphicalProperty("Height", String.valueOf(maxHeightInt));
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
}
Product Synonym
Rational Rhapsody
Was this topic helpful?
Document Information
Modified date:
27 May 2022
UID
swg21692965