How to rotate text together with a Rectangle2D?

Hi forum
I hope you can help me out here. See the follow code example. I have a Rectangle2D, in which some text is rendered. What I'm trying to do here is the following: rotate the Rectangle2D - no problem here - but the text should follow - ie. still be rendered the same way inside the Rectangle2D after the rotation transform is applied. The theta value is just an example - it should work the same for any theta value.
Ie - after the rotation, the text is drawn with the first letter just right of the left angle of the rotated Rectangle2D, just as with the original drawn text.
I'm aware, that the key to doing this is to figure out what point to rotate the text around. I would believe, that the correct answer would be the same point as the Rectangle2D, but that doesn't seem to work, as you can see, if you run the code. Can someone help me to get this to work correctly?
Any help would be appreciated! Thanks in advance!
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import javax.swing.*;
public class ScaleToFill extends JPanel {
    Rectangle2D.Float rect = new Rectangle2D.Float(200,200,220,35);
    float theta = 1.1748778437843f;
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setPaint(Color.blue);
        Font font = g2.getFont().deriveFont(18f);
        g2.setFont(font);
        FontRenderContext frc = g2.getFontRenderContext();
        String s = "This text should be rotated";
        float width = (float)font.getStringBounds(s, frc).getWidth();
        LineMetrics lm = font.getLineMetrics(s, frc);
        float height = lm.getAscent() + lm.getDescent();
        // Draw text as-is.
        // Scale text into rect.
        float xScale = rect.width / width;
        float yScale = rect.height / height;
        // Locate string origin.
        double x = rect.x;
        double y = rect.y + rect.height - yScale*lm.getDescent();
        AffineTransform at = AffineTransform.getTranslateInstance(x, y);
        float scale;
        if (xScale > yScale)
          scale = yScale;
        else
          scale = xScale;
        at.scale(scale, scale);
        AffineTransform rotator = new AffineTransform();
        rotator.rotate(theta, rect.getX()+(rect.getWidth() / 2), rect.getY()+(rect.getHeight() / 2) );
        GeneralPath rect2 = new GeneralPath(rotator.createTransformedShape(rect));
        g2.draw(rect);
        g2.draw(rect2);
        g2.setFont(font.deriveFont(at));
        g2.setPaint(Color.red);
        g2.drawString(s, 0, 0);
        at.rotate(theta, rect.getX()+(rect.getWidth() / 2), rect.getY()+(rect.getHeight() / 2) );
        g2.draw(rect2);
        Font rotateFont = font.deriveFont(rotator);
        g2.setFont(rotateFont);
        g2.setPaint(Color.red);
        g2.drawString(s, 0, 0);
        // Check scaled string bounds.
    public static void main(String[] args) {
        ScaleToFill test = new ScaleToFill();
        test.setPreferredSize(new Dimension(800,600));
        JFrame f = new JFrame();
        f.getContentPane().add(test);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);
        System.out.println(new Color(0,255,0,0));
}

import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import javax.swing.*;
public class STF extends JPanel {
    Rectangle2D.Float rect = new Rectangle2D.Float(200,200,220,35);
//    float theta = 1.1748778437843f;
    double theta = Math.PI/6;
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
                            RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
                            RenderingHints.VALUE_STROKE_PURE);
        g2.setPaint(Color.blue);
        Font font = g2.getFont().deriveFont(18f);
        g2.setFont(font);
        FontRenderContext frc = g2.getFontRenderContext();
        String s = "This text should be rotated";
        float width = (float)font.getStringBounds(s, frc).getWidth();
        LineMetrics lm = font.getLineMetrics(s, frc);
        float height = lm.getAscent() + lm.getDescent();
        // Scale text into rect.
        float xScale = rect.width / width;
        float yScale = rect.height / height;
        float scale = (xScale > yScale) ? yScale : xScale;
        // Locate string origin.
        double x = rect.x;
        double y = rect.y + (rect.height + scale*height)/2 - scale*lm.getDescent();
        AffineTransform at = AffineTransform.getTranslateInstance(x, y);
        at.scale(scale, scale);
        AffineTransform rotator = new AffineTransform();
        rotator.rotate(theta, rect.getCenterX(), rect.getCenterY());
        GeneralPath rect2 = new GeneralPath(rotator.createTransformedShape(rect));
        // Draw with no rotation.
        g2.draw(rect);
        g2.setPaint(Color.red);
        g2.setFont(font.deriveFont(at));
        g2.drawString(s, 0, 0);
        // Rotate once.
        g2.setPaint(Color.blue);
        g2.draw(rect2);
        rotator.concatenate(at);
        g2.setFont(font.deriveFont(rotator));
        g2.setPaint(Color.red);
        g2.drawString(s, 0, 0);
        // Rotate again.
        rotator.setToIdentity();
        rotator.rotate(2*theta, rect.getCenterX(), rect.getCenterY());
        rect2 = new GeneralPath(rotator.createTransformedShape(rect));
        g2.setPaint(Color.blue);
        g2.draw(rect2);
        rotator.concatenate(at);
        g2.setFont(font.deriveFont(rotator));
        g2.setPaint(Color.red);
        g2.drawString(s, 0, 0);
        // Check scaled string bounds.
        // this was handled by the fractional metrics rendering hint
    public static void main(String[] args) {
        STF test = new STF();
        test.setPreferredSize(new Dimension(800,600));
        JFrame f = new JFrame();
        f.getContentPane().add(test);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);
}

Similar Messages

  • How to make text columns with adobe muse

    Hi,How to make text columns with adobe muse (like InDesign)?

    Multiple columns can be acheived with CSS - http://www.w3schools.com/css/css3_multiple_columns.asp
    div
    -moz-column-count:3; /* Firefox */
    -webkit-column-count:3; /* Safari and Chrome */
    column-count:3;
    I'm surprised that Muse does not support text columns yet, but perhaps the custom CSS can be added in style tags on page properties. Haven't tried it, but don't see why it wouldn't work.

  • How do I text somebody with an iPod?

    How do I text somebody with an iPod?

    Use iMessage
    What software does your and the others iPod have

  • How notification system work together with Acrobat X Pro?

    Hi everyone,
    I use Adobe Acrobat 10 Pro to implement Distributed PDF Form in my organization. I have some problem about this.
    When client fill information in application form on our distribution server,Do you have solution that Acrobat 10 Pro can send a notification to specific authorized
    prerson for his/her Digital Signature?
    example : Mr.A filled some information about Purchase Order. System require his supervisor's digital signature so, Acrobat send notification to his supervisor automatically.
    I have some idea about Active Directory work together with Acrobat but, I don't know how to use both of it together.
    Any advice will help me so much.
    Best Regards,
    Charles
    PS. sorry about my poor english

    Thank you so much about your suggestion.
    Do you know how i can integrate Acrobat X Pro with Active Directory?
    I look forwarding to hear from you.Thank you.
    Chompunoot
    Date: Thu, 2 Jun 2011 19:29:41 -0600
    From: [email protected]
    To: [email protected]
    Subject: How notification system work together with Acrobat X Pro?
    Hi Charles,
    You want to modify the signature field properties and set a script to execute when the field is signed.
    Here's how to get started in Acrobat X:
    Open the file that will eventually be uploaded to the server
    Click Tools on the top right to open the Tools panel
    Expand Forms (click on Forms so you can see the buttons underneath)
    Click the Edit button
    Right mouse click on the first signature field and then click Properties from the pop-up menu
    Select the Signed tab on the Digital Signature Properties dialog
    Select the This script executes when the field is signed radio button
    Click the Edit button
    Add the following in the JavaScript Editor dialog:
              var cMyMsg = "Please log on the server and sign the document";
              app.mailMsg ({
                  bUI: true,
                  cTo: "mailto:[email protected]",
                  cSubject: "A document requires your attention",
                  cMsg: cMyMsg
    Click the OK button on the JavaScript Editor dialog
    Click the Close button on the Digital Signature Properties dialog
    Click the Close Form Editing button in the Forms panel under Tools
    Save the PDF file
    It's going to look something like this:
    http://forums.adobe.com/servlet/JiveServlet/showImage/70913/SignScript.jpg
    Give that a try and from and see what you think. You can set the strings as necessary and repeat for each signature field (except for the last one )
    Steve
    >

  • How to rotate text

    I was told to restate my number's problem as I want to rotate text within a single cell. This is for grade book so the column label can be hidden along with other data.

    ohsster,
    I was also excited by iWorks, and I was planning to adopt it and try to wean myself from Office even before Numbers was announced. I figured I'd just use the Tables within Pages to do my spreadsheet functions, since all the same calculations are available there. After a month of working in iWork, it's obvious that it would be premature to un-install Office for Mac, but I'm still determined to make the switch and I believe that Apple will address the serious issues, like the speed problem, in short order. So, I'm still excited about being closer to shaking the Microsoft dependency.
    Regarding your application, I don't know how large and complicated your design is, but I encourage you to try my suggestion just to get a feel for working with references that span sheets and tables. This, to me, is much easier in Numbers than in Excel. I tried cross-sheet referencing in Excel years ago and found it too complicated, but in Numbers it is as simple as pie. You can build your second table in the same sheet as your first table if you want to keep things close together for that phase, and then just drag the new table to a new sheet when you're done with it. To make a cell in the destination table mirror the entry in the source table, simply type an = sign in the destination cell and then click on the source cell. To replicate the reference in the first destination cell across the first row, highlight that cell and drag the fill handle across the row. Then, with the filled row highlighted, drag the fill handle down the sheet to populate as many rows as you need. This whole process takes only a few seconds. Now you have a copy of the source table that can be independently formatted, labeled and printed after you move it to it's own sheet. This is the Numbers equivalent of setting a Print Area in Excel, except on steroids.
    I hope you don't give up!
    Jerry

  • How to print activities together with bar chart

    Hi,
    Anyone can advise how to print out an activities together with bar chart. When you try to print, an insufficient bar chart come out. Why?
    Thank you

    Another one to change might be the Gantt chart timescale
    File -> Page Setup -> Options -> timecale start and Timescale finish
    Best thing to do is cut out all the columns you dont need and print on A3 if you can
    Apply a filter if you're seeing more activities than you need, remove any bar labels if there's more info on the Gantt than you need
    Does take a bit of fiddling sometimes - but once you're done, don't forget to save the layout !

  • How to push Texts along with attributes to MDM

    Hi All! There are lot of information how to push data to MDM via OHD. But all of that is regarding Attributes(and it works fine). Anybody knows how to push Texts data along with attributes?

    Hi,
    Refer https://www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/b01e4269-f744-2b10-929b-fa7b49aac540
    Hope it helps.
    Thanks,
    Minaz

  • How to save expression together with animation preset?

    I am trying to understand expressions and animation presets.
    I have one single slider control, which controls the opacity of a layer, where the value is the slider value + slightly changed using an expression.
    I can save the slider control as an animation preset, but the expression gets lost.
    Yes, this is so basic that it can be, this is the way I like to learn. And as far as I know, expressions can be saved together with animation presets. I hope someone can tell me how!

    The reason that the expression is not removed when you delete the slider is that the expression is only reading the slider value, the slider doesn't know that the expression is there. There's no reverse link.
    You can build more professional effects but that involves editing the xml file that tells AE what effects are applied. This still would not generate a reverse link to an expression.
    Enabling or disabling an effect only changes the way things are rendered. If you have keyframes on a Lens Flair Brightness and you disable the effect the Lens Flair will not render but the keyframe values will still be available to an expression. Again, there's no reverse link. Since an expression slider does not make a change in the pixel values of a layer turning the FX switch on or off will have no effect on an expression reading the value.
    The "trick" in creating an Animation Preset that uses expressions and is removed with the "effect" is removed from the Effects Control Window is to only write expressions for properties that are available in the effects used. You could do this by applying the Transform Effect, or the Levels Individual Controls Effect, or the CC Composite Effect to the layer and writing the expression there instead of placing your expression in the Layer's opacity property. Take a look at this screenshot.

  • How to Rotate Text 90 Degree?

    I tried to rotate text so that it reads from bottom to
    top of the screen (vertically). How to do it?
    I tried w/ Graphics2D and AffineTransform class but fail.
    Here is my code:
    AffineTransform af = new AffineTransform(0.0, 1.0, 1.0,
    0.0, 0.0, 0.0);
    Graphics2D newg = (Graphics2D) g;
    g.setTransform(af);
    g.drawString("Rotated Text", 70.0f, 70.0f);
    Anybody do text rotation please post reply.
    Thanks!

    Turns out the bug still persists, and I post new Q on
    this forum. Please check it out.
    But here is the my entire code, if you would like to see
    and try:
    import javax.swing.DefaultCellEditor;
    import javax.swing.JScrollPane;
    import javax.swing.SwingConstants;
    import javax.swing.JPanel;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.util.*;
    import java.text.NumberFormat;
    import java.text.DecimalFormat;
    import java.awt.Graphics2D;
    import java.awt.geom.AffineTransform;
    public class CompJFC
    static JFrame frame1;
    static final int cWidth = 500;
    static final int cHeight = 500;
    Object[] ctable = {"Usage Graph for Users",
    "Usage Graph for Servers",
    "Usage Graph for Appliances",
    "Top 20 Users (Last 30 Days)",
    "Top 20 Users (Last 60 Days)",
    "Top 20 Users (Last 90 Days)"};
    JComboBox ccombo = new JComboBox(ctable);
    JPanel panel1, panel2, panel3;
    JCanvas canvas;
    public class JCanvas extends JComponent
    Insets insideBorder;
    JCanvas()
    super();
    JCanvas(int cWidth, int cHeight)
    insideBorder = new Insets(cHeight-150, 50, 50, cWidth-60);
    public void paintComponent(Graphics g)
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    AffineTransform af1 = g2.getTransform();
    int xp = insideBorder.left-35;
    int yp = insideBorder.top-100;
    AffineTransform af2 =
    AffineTransform.getRotateInstance(Math.toRadians(270), xp, yp);
    g2.setTransform(af2);
    g2.drawString("Number of Online Users", xp, yp);
    g2.setTransform(af1);
    public void AddComp()
    panel1 = new JPanel();
    panel1.add(ccombo);
    ccombo.addItemListener(new ItemListener()
    public void itemStateChanged(ItemEvent evt)
    String selected;
    panel2.remove(canvas);
    canvas = new JCanvas(cWidth, cHeight);
    panel2.add(canvas, BorderLayout.CENTER);
    panel2.repaint();
    frame1.setVisible(true);
    canvas = new JCanvas(cWidth, cHeight);
    panel2 = new JPanel(new BorderLayout());
    panel2.add(canvas, BorderLayout.CENTER);
    panel3 = new JPanel(new BorderLayout());
    panel3.add(panel1, BorderLayout.NORTH);
    panel3.add(panel2, BorderLayout.CENTER);
    JTabbedPane tpane = new JTabbedPane();
    tpane.addTab("Chart", panel3);
    frame1.getContentPane().add(tpane);
    public static void main(String args[])
    CompJFC jc = new CompJFC();
    frame1 = new JFrame("Swing GUI Exercise");
    frame1.setSize(cWidth, cHeight);
    frame1.setDefaultCloseOperation(frame1.EXIT_ON_CLOSE);
    frame1.getContentPane().setLayout(new BorderLayout());
    jc.AddComp();
    frame1.setVisible(true);

  • How to read text file with big5 into db

    hi,
    how can i use UTL_FILE package to
    read a text file with big5 characters and insert into db?
    my oracle charset is AL32UTF8.
    thx a lot!

    Thx for yr answer!!!
    I have followed and it works.
    However, I got another problem with HKSCS. When the text file contained HKSCS, the store procedure also treats it as Big5 and when I select it out, the character was not the orginal one.
    Please suggest if you have any ideas.
    Many Thanks!!!

  • How to rotate to landscape with accelerometer?

    Hi
    I didn't figure it out how I determine the orientation with the accelerometer. Because the autorotation is not good for my application.
    Could you help me with this code?
    - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    acceleration.y
    acceleration.z //Which of these three gets the rotation Landscape
    acceleration.x
    if(LandscapeOrientation) {
    [landscapeView setAlpha:1]; //How do I rotate the view??
    } else {
    [landscapeView setAlpha:0];

    Your best shot would be to make a copy, enable layout adjustment, and change the page dimensions, I think, but I wouldn't expect any miracles.

  • How does the texting work with iPod touch?

    Want to buy this for my daughter.  How do you text when out of your home wifi zone? Can you text anywhere? And how?

    What do you mean by a new wifi address?  You use the same texting address whenevery yu are connected to a wifi network.
    The Messages app that comes with iOS 5 will only text to other devices with iOS 5.  There are apps available in the App store like Text+ that alows testing to non-iDevices and iDevces without iOS 5.

  • How Select All Text Objects with Specific Contents and Move to Top-Center?

    Mavens,
    In a ~230 page InDesign CC Book (9 INDD files), on about ~35 pages, there is a small text block with the word "NOTES."
    Currently, the NOTES text block is in the Middle-Center of the page. I would like to find a way for InDesign to move all ~35 instances of the NOTES text block to the Top-Center (of the page each text block is on).
    Is there an easy way to do this with Edit --> Find/Change?
    Thanks!

    Probably not.
    That text block really belongs on a master page applied to those 35 pages, and if it is, all you have to do is move it on the master page. If it isn't, you've got some work to do. Probably easiest to fix one, then coy it and use Paste in Place on the other pages, and delete the frame that's in the wrong place.

  • Rotating text label with complex fonts (arabic)

    i got the next problem:
    rotating dynamically created TextField with any angle (using
    embedded fonts of course). if i use standard fonts, latin sybmols -
    everything works excellent. but if i use arabic fonts - text labels
    behave very strange - complex arabic symbols are not shown.
    for example, 2 symbols "lj" give 1 complex arabian symbol to
    show. but when using in rotating mode with embedded fonts those
    "lj" are just shown separately, not as one.
    did anyone have such experience? how this could be solved?
    maybe the same behavior with japan?
    thanks in advance
    p.s. i used different modes and arabic fonts. everything
    works fine in usual way until the text label starts being
    rotated...

    shimontornia,
    > I'm trying to rotate a dynamic text field that is using
    > system font.
    > Any ideas ?
    The only idea possible is to omit one of those
    characteristics: either
    the text field must not be rotated, or it must not use a
    system font.
    David Stiller
    Adobe Community Expert
    Dev blog,
    http://www.quip.net/blog/
    "Luck is the residue of good design."

  • How to populate text fields with data present in a table

    Hi,
    The page i'm building has got a select list for the primary key column and text fields corresponding to rest of the columns in the table.
    upon selecting some value from the list, the data corresponding to that row should get populated in the respective items. I don't want to add source in each item. can't i create a process or something else where this is done for each item.
    for eg there's a table with columns A(primary key) and B.
    there is a text fields on this page.
    this textfield should populate the data from the table whenever i submit the page such that teh value in B is select B from tablename where A = the selected value.
    Thanks
    Dhirendra

    So I assume page was not built using a wizard. Why on earth you would want to I dont know, but you could create an "After Header" pl/sql process to populate the relevant fields, assuming the id was know on entry to the page. If you want to select the id on the page and then populate the fields, guess you will need to use a "Text Field (always submits page when Enter pressed)" and then use an "On Submit" process to populate the items.
    If you are using an Automated Row Fetch, remember to select "Set memory Cache on Fetch" in that process.
    Hope this helps.

Maybe you are looking for