Bounds of Selection

Hi,
   I need to get the geometric Bounds for selected Images.  My document contains multiple items(path, text and group items). I want to get the height and width of the over all selection of the images.  How do i get tat??
Regards,
Sudha K

It depends on whether the images are placed or embeded. If placed then make a temporary group of the placedItems and get it's geometric bounds. If embeded then do the same for rasterItems.

Similar Messages

  • Selection without selection bounds

    I'm using CS2 so I can't call on selection bounds (which seems to be the preferred method of working with selections)
    var sb = activeDocument.selection.bounds;
    var sbWidth = sb[2]-sb[0];
    var sbHeight = sb[3]-sb[1];
    alert(sbWidth + " , " + sbHeight)
    So the above code won't work for me
    How can I find out (1) if a selection is set (selection width & height = 0?) and (2) find the width and height of said selection assuming that only the rectangular marquee is used (not ellipse or lasso).
    Cheers

    I had to find out bounds of selection that could be any shape for my Photoshop Photo Collage Toolkit the selections are image size and shaped alpha channels in the Photo Collage Template PSD file with the names "Image 1", "Image 2", ..., "Image n".  I had a heck of a time to come up with a way that worked in CS2, CS3, Cs4 and CS5. After consulting with my good friend Rube Goldberg we can up with a contraption that seems to work. This is not a thing of beauty. Some local functions are not shown for the function name states what it does.
    // Get Alpha Channel's width and height Selection Bounds did not work???
    makeLayer(); // Make Temp Work Layer
    loadAlpha("Image " + imageNumber ); // Load Image Alpha Channel
    fillBlack();
    activeDocument.selection.invert(); // Inverse
    // If image size equals canvas size no pixels will be selected clear will fail
    try{
    activeDocument.selection.clear(); // One clear did not work
    activeDocument.selection.clear(); // Two did the trick
    }catch(e){}
    activeDocument.selection.deselect(); // Deselect
    var SB = activeDocument.activeLayer.bounds; // Get the bounds of the work layer
    var SWidth = (SB[2].value) - (SB[0].value); // Area width
    var SHeight = (SB[3].value) - (SB[1].value); // Area height
    activeDocument.activeLayer.remove(); // Remove Work layer
    Where there is a will there is a way. Layer bounds does work...
    I needed these selections bounds so I could resize and align placed images to these mapping Alpha Channels and mask any Image overflow.
    Link to my Photo Collage Toolkit

  • Using radio button selection in multiple tables

    Hello All,
    I've got a bit of a design issue and it being a Friday my brain is a bit foggy and I can't seem to figure out a solution.
    what I want to do is have 3 tables. The user should only be able to select one line from any of the three tables.
    I can do this by having events that clear down selection on the two other tables on any selection of the third, but the select buttons of tables don't really give the UI impression that only one row can be selected. To do this I'd like to use the radio button element.
    so
    table A
    choice - name
    (o) - Anne
    (o) - Bob
    (o) - Charlie
    Table B
    choice - name
    (x) - David
    (o) - Ellen
    (o) - Fran
    Table C
    choice - name
    (o) - George
    Here the entry in table B for David is selected. But any selection of any of the other options should deselected.
    My thoughts are to use a radio button ui element, bind the "selected" value to a unique id for each row/table (an attribute of the node element for each table) and the value to a common shared attribute (not table specific).
    Any better ideas - and certainly any which would mean I'm not going to have to maintain a lookup table of my unique ids and node elements to find out which one is selected?
    Cheers,
    Chris

    Ok - here's how I did it.
    I created another lookup table which had a guid and reference to the element.
    in the each elements I had a guid which I bound to the key for selection property of the radio button in the table.
    I then bound the selected key property to an attribute that was common to all elements.
    in my "processing" logic I read the selected key, read the lookup table - and therefore got the reference to the selected element.
    Would have been an awful lot easier if I could have used a reference to the element itself as the "key" - but that was required to be a character field.
    [image showing radio button selection working across multiple tables|http://i51.tinypic.com/bi79dx.jpg]
    End result works quite nicely.
    Cheers,
    Chris

  • Is there a way to tighten a text bounding box?

    Hey all,
    I've looked before but never found a definitive answer to this question:
    Is there a way to tighten the text bounding box without converting it to outlines?
    I work for a screen printer, and want to figure out a way to tighten the bounding box without changing the leading and without converting it to outlines in order to be able to edit said text. We deal with a lot of clients who send us names, that are often misspelled, and after an initial proof need to be corrected. Sometimes we need to center this text to an object.
    Illustrator's bounding box, unlike that of Corel (which is our primary program, and won't open AI files) includes the leading below the type, so when you center it, it's not visually centered:
    So I guess my real question is is there a way to get the text centered (as seen below) without converting the text to outlines, or messing with the leading, or is there a way to tighten the bounding box?
    Thanks in advance!
    -K

    Combat and Dandreu,
    You may use this silly way:
    1) Tick Edit>Preferences>General>Use Preview Bounds;
    2) Select the Type and Effect>Path>Outline Object.
    That will reduce the Bounding Box to the actual bounds of the letters so you can centre as you wish.
    Remember to untick Edit>Preferences>General>Use Preview Bounds before you get a reverse issue.

  • Problem rotating rectangle (selecting corners) after creating with rectangle tool in illustrator

    I'm using the latest CC version of Illustrator. When I draw a rectangle using the rectangle tool, I no longer seem to be able to select the corners to resize the rectangle nor does the cursor turn to a rotate icon when I put the mouse just outside the corner. I know that Ai CC treats rectangles differently now, with the live rectangles and the rounded corner options, and the transform box opening automatically. What I'm wondering, and hoping isn't the case, is whether this is this at the expense of being able to go right in and resize using the just the mouse? I know that there is the  "Object > Shape > Expand" option, but having to do that for every time I draw a rectangle is time-consuming and adds and extra step that was unnecessary before. I saw a tutorial on Lynda where the instructor drew a live rectangle in CC AND was still able to resize it by grabbing the corner "handle". Anyone know if this is just a setting I need to turn on or something similarly easy, or is it a case of Adobe inadvertently making the workflow longer when trying to make it easier? And yes, I have "show bounding box" selected under VIEW.

    MOD indi-go girl,
    I am afraid you have come across the Live Rectangle bug which is limited to the MAC versions starting with 10.7 and 10.8, but not 10.9 (Mavericks) or 10.10 (Yosemite). Hopefully, the bug will be fixed soon.
    So a switch to Mavericks or Yosemite with a reinstallation might be the way to solve it here and now.
    To get round it in each case, it is possible to Expand the Live Rectangles to get normal old fashioned rectangles, or to Pathfinder>Unite, or to use the Scale Tool or the Free Transform Tool.
    A more permanent way round that is to create normal old fashioned rectangles, after running the free script created by Pawel, see this thread with download link:
    https://forums.adobe.com/thread/1587587

  • Select multiple boxes at time of Outbound Delivery processing with scanner

    Hi all,
    I am facing a problem at time of processing outbound delivery. I am bound to select 1 box and its corresponding HU. This reduces productivity of end users. I want to know if there is any possibility to select multiple boxes at one go using a scanner, so as to attach all HU at same time.
    Regards,
    Ajay

    Hi,
    This is because plant 2 is processing delivery -2 with reference to sales order.
    So when you want to process deliver -1 then same already created with reference to sales order. it means both delivery cant be accessed one time because reference is sales order, so it lock
    If you want to pick both at same time,
    Then assign one shipping point to both plants, so when you create delivery both item will copy in delivery,then pick both at same time.
    kapil

  • Export portion of an Image using Lyr "Bounds"

    Hello,
    I extract PNG export code using listner and it has following basic steps.
    Enumerated PNG filter for an action descriptor.
    Put class PNG format
    Give image path and alpha channels
    Play 'eventSave' over the action descriptor.
    Now, this will export entire layer as a PNG. I wanted to export just a part of an image.
    Therefore, I have modify above steps as below.
    Get layer bounds.
    Select are rect using top, left, right, and bottom.
    Crop image.
    Enumerated PNG filter for an action descriptor.
    Put class PNG format
    Give image path and alpha channels
    Play 'eventSave' over the action descriptor.
    Do event playback
    But unfortunately above additional steps get huge execution time.
    Is there a better way to implement same requirement without playing extra events ?
    Since I have image bounds, width and height, should I be able to do this without cropping and play back history?

    you have to cut out the yellow rectangle and include transparent areas because the java 2d system, jframe, jpanel, paintcomponent only allows square rectangles as far as i know. it looks like you have some manual editing to do with the eraser tool in your favorite paint program.
    -Nathan Nelson

  • Multi-part identifier dtss.DocumentID could not be bound

    Below is my query
    Getting error
    The multi-part identifier "dtss.DocumentID" could not be bound.
    SELECT sb.BoxID,sbls.Locationcode,sbl.LocationName,sbls.DateEntered
    From data_document.dbo.StorageBox sb
    inner join data_document.dbo.StorageBoxLocations sbls
    on sb.storageBoxID
    = sbls.storageBoxID
    inner join data_document.dbo.StorageBoxLocation sbl
    ON sbls.LocationCode
    = sbl.LocationCode
    Inner Join CVDocuments cvds
    on dtss.DocumentID
    = cvds.DocumentID
    INNER JOIN CVFact cvf
    ON cvf.CVID
    = cvds.CVID
    INNER JOIN Employee e
    ON e.Employeeid
    = cvf.EmployeeID
    inner join data_document.dbo.DocumentStorageBox dsb
    ON dsb.StorageBoxID
    = sb.StorageBoxID
    Can anybody help me. 
    Mary Sunish

    Where is this dtss object defined -> dtss.DocumentID?
    Can you check the dtss alias which is not defined on of the objects?
    --Prashanth

  • The multi-part identifier could not be bound.

    Hi!
    Somebody can tell me what I'm doing wrong on this code (see below) because I'm getting this message
    (Msg 4104, Level 16, State 1, Line 1. The multi-part identifier "dbo.tdbComments.cmsComments" could not be bound.)
    SELECT [to].odsProduct, tsd.sndInvoice, tsd.sndSerialID, tsd.sndTicketNo, tsd.sndStationID, ps.psName, CONVERT(varchar(8),tsd.sndDate,1) AS [Scanned Date], 
    CONVERT(varchar(8),tsd.sndLaborDay,1) AS [Labor day], tsd.sndEmployeeID, u.EmpName, tc.cmsComments AS [Comentarios]
    FROM dbo.tdbScanDetail tsd
    INNER JOIN dbo.proStation ps ON ps.psID = tsd.sndStationID
    INNER JOIN UserPlenimex.dbo.Users u ON u.EmpID = tsd.sndEmployeeID
    INNER JOIN dbo.tdbOrders [to] ON tsd.sndSerialID = odsSerial
    INNER JOIN dbo.tdbComments tc ON odsInvoice = sndInvoice
    WHERE tsd.sndInvoice = '55370.0870'
    GROUP BY [to].odsProduct, tsd.sndInvoice, tsd.sndTicketNo, tsd.sndSerialID, tsd.sndStationID, ps.psName, tsd.sndDate, tsd.sndLaborDay, tsd.sndEmployeeID, u.EmpName, dbo.tdbComments.cmsComments
    ORDER BY tsd.sndStationID

    try
    SELECT [to].odsProduct
    ,tsd.sndInvoice
    ,tsd.sndSerialID
    ,tsd.sndTicketNo
    ,tsd.sndStationID
    ,ps.psName
    ,CONVERT(VARCHAR(8), tsd.sndDate, 1) AS [Scanned Date]
    ,CONVERT(VARCHAR(8), tsd.sndLaborDay, 1) AS [Labor day]
    ,tsd.sndEmployeeID
    ,u.EmpName
    ,tc.cmsComments AS [Comentarios]
    FROM dbo.tdbScanDetail tsd
    INNER JOIN dbo.proStation ps ON ps.psID = tsd.sndStationID
    INNER JOIN UserPlenimex.dbo.Users u ON u.EmpID = tsd.sndEmployeeID
    INNER JOIN dbo.tdbOrders [to] ON tsd.sndSerialID = odsSerial
    INNER JOIN dbo.tdbComments tc ON odsInvoice = sndInvoice
    WHERE tsd.sndInvoice = '55370.0870'
    GROUP BY [to].odsProduct
    ,tsd.sndInvoice
    ,tsd.sndTicketNo
    ,tsd.sndSerialID
    ,tsd.sndStationID
    ,ps.psName
    ,tsd.sndDate
    ,tsd.sndLaborDay
    ,tsd.sndEmployeeID
    ,u.EmpName
    ,dbo.tdbComments
    ,tc.cmsComments
    ORDER BY tsd.sndStationID
    Thanks
    Manish
    Please click Mark as Answer if my post solved your problem and click
    Vote as Helpful if this post was useful.

  • Proportional Scaling with bounding box does not work

    Problem:
    When I attempt to proportionately scale  objects with the bounding box, by selecting a corner / handle and  holding Shift as I drag, it doesn't work.
    I'm not doing it wrong  or in the wrong order of selection, etc., I've done it this way for  years.
    Also, Illustrator is persnickity. It HAS  occasionally worked, but more often does not.
    Restarting  Illustrator, my computer, closing Entourage, nothing works.
    I read this thread and none of the suggestions work.
    http://forums.adobe.com/message/1258725#1258725
    Just for reference, these are the instructions from Illustrator manual that I am having issues with.
    Scale objects with the bounding box
    Select one or more objects.
    Select the Selection tool or the Free  Transform tool .
    Drag a bounding box handle until the object  is the desired size.Objects scale relative to the opposite  handle of the bounding box.
    Do any of the following to control the   scaling behavior:
    To maintain the object’s proportions, hold down Shift as you drag.
    To scale relative to the object’s center point, hold down Alt (Windows) or Option (Mac OS) as you drag.

    ask,
    You can see an updated list of applications reported in this forum to interfere with Illy here (item 7):
    Other options
    I am afraid there is not much to do, apart from disabling whatever causes the trouble. There have been quite a few threads about this recently.

  • Checkbox group selected property binding not working

    Hi,
    I've been through all the threads and tutorials relating to this problem and none of them help.
    The Situation
    I have a checkbox group which I have bound the items items property to a MySQL database (value field = int, display field = String). I have bound the Selected property to a sessionbean field which is an int[] array.
    I have a processValueChange event for my checkbox group which grabs the selected boxes values (ie the int value of the checkbox id). Based on these values it does some other processing.
    The Problem
    When the page loads everything is displayed ok. When I select a checkbox within the checkbox group the getSelected() method returns the int value of the selected checkbox and perform other processing as necessary... so far so good.
    However, when the page finishes processing and reloads the selected checkboxes are not ticked. I'm sure it has something to do with the Selected property of the checkboxgroup but I can't for the life of me work out why. For multiselect objects the Selected property must be bound to an array which I have done with my int[] array. I've tried preloading the array with default values (1, 2, etc) to mimic the int values from the database. I've tried changing the array to a boolean array but this throws exceptions. So basically i'm stuck.
    The Source
    Session Bean
        private int[] extras;
        public int[] getExtras() {
            return this.extras;
        public void setExtras(int[] extras) {
            this.extras = extras;
    Page JSP
    <ui:checkboxGroup binding="#{book_package.extras}"
                                                                                    converter="#{book_package.extrasConverter}" id="extras"
                                                                                    items="#{book_package.extrasDataProvider.options['extras.ExtrasID,extras.Name']}"
                                                                                    onClick="common_timeoutSubmitForm(this.form, 'table:tr:td:table:tr:td:table:tr:td:div:div:table:tr:td:extras');"
                                                                                    selected="#{SessionBean1.extras}" valueChangeListener="#{book_package.extras_processValueChange}"/>
    Page Java
        public void extras_processValueChange(ValueChangeEvent event) {
            // TODO: Replace with your code
            getSessionBean1().setExtrasTotal(0);
            try {
                int[] extra = (int[])extras.getSelected();
                int extrasId = 0;
                int extraPrice = 0;
                if (extra.length != 0) {
                    for (int i=0; i < extra.length; i++) {
                        extrasDataProvider.cursorFirst();
                        do {
                            extrasId = new Integer(extrasDataProvider.getValue("ExtrasId").toString()).intValue();
                            if (extrasId == extra) {
    extraPrice = getSessionBean1().getExtrasTotal() + new Integer(extrasDataProvider.getValue("Price").toString()).intValue();
    getSessionBean1().setExtrasTotal(extraPrice);
    break;
    } while (extrasDataProvider.cursorNext());
    } catch (Exception e) {
    log("Exception occurred!!", e);
    error("Error: "+e.getMessage());
    getSessionBean1().setTotalPrice(getSessionBean1().getPackagePrice() + getSessionBean1().getExtrasTotal());
    Any help appreciated.
    Thanks.

    ok, i found the problem. MySQL int value is treated as an Integer in Creator. I changed my SessionBean array from int[] to Integer[] and now it works properly... phew!!!

  • Text box Vertical Justification greyed out in CS4

    Does anyone know why the ability to vertically justify my text boxes is disabled?  It is only in this one document (although, I think I remember this occurring in another).  The option is greyed out in the Text Frame Options window and will not allow me to click on the options in the tool bar.  This is rather frustrating and can't for the life of me figure out how to fix it.  Anyone else experience this or know how to fix it?
    Thanks,
    Mel

    Prior to CS5 you can't vertically justify any frame in which the text area is not rectangular. Not only can text wrap change the shape of a text area, but so can corner effects  (adding enough inset will get past this), and of course the use of non-rectangular frames.
    Thanks, Peter.  I had already adjusted the top inset enough to achieve the look I was looking for.  That's good to know about the corner effects.  That is actually when I experienced this before and used insets to achieve my desired look then, too. 
    Peter's pointing out that you could inadvertently move just one of the corners with the direct selection tool and have a frame that isn't a rectangle and then you loose the text box vertical justification option. If you are on OSX you can use this script to square up a selected skewed box:
    tell application "Adobe InDesign CS3"
    set {a, b, c, d} to geometric bounds of selection
    set entire path of path 1 of selection to {{b, a}, {d, a}, {d, c}, {b, c}}
    end tell

  • Help, experiencing minor bugs in program

    this is supposed to use rectangles and you should be able to load and save and they have colors and do a few more things with them, the loading is where it doesn't work.
    *-------------------------------------------------------------- 80 columns ---|
    * This is the main class for the application. It is built along the same
    * lines as the Editor class of project 1. It has a constructor, two instance
    * methods, and a static main()  that kicks the whole thing off.
    * The two instance methods are a menu creation method, and a menuItems
    * initialisation method.  The constructor instantiates the window
    * and sets up its internals by creating and installing the drawing canvas,
    * toolbar, and menus. All of the code works correctly as is and should
    * require no changes.
    * @version      1.1 15/04/01
    * @author       Julie Zelenski
    * @author       Restructured by Ian A. Mason
    * @see       javax.swing.JFrame
    * @see       javax.swing.JMenuBar
    * @see       javax.swing.JMenuItem
    * @see       javax.swing.JMenu
    import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
    public class JavaDraw extends JFrame {
        final Toolbar toolbar = new Toolbar();
        final DrawingCanvas canvas = new DrawingCanvas(toolbar, 350, 350);
        final int menuMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
        final JMenuBar mb = new JMenuBar();
        final String[]
             fileMenuItems = {"Clear all", "Load file", "Save to file", "Quit"};
        final int[] fileKeyCodes = {KeyEvent.VK_N, KeyEvent.VK_O, KeyEvent.VK_S, KeyEvent.VK_Q};
        final ActionListener[] fileActionListeners = {
         new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                  canvas.clearAll();}},
         new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                  canvas.loadFile();}},
         new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                  canvas.saveToFile();}},
         new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                  System.exit(0);}}
        final String[] editMenuItems = {"Cut", "Copy", "Paste", "Delete"};
        final int[] editKeyCodes = {KeyEvent.VK_X, KeyEvent.VK_C, KeyEvent.VK_V, KeyEvent.VK_BACK_SPACE};
        final int[] editMenuMasks = {menuMask, menuMask, menuMask, 0};
        final ActionListener[] editActionListeners = {
         new ActionListener() {
              public void actionPerformed(ActionEvent e) { canvas.cut();}},
         new ActionListener() {
              public void actionPerformed(ActionEvent e) { canvas.copy();}},
         new ActionListener() {
              public void actionPerformed(ActionEvent e) { canvas.paste();}},
         new ActionListener() {
              public void actionPerformed(ActionEvent e) { canvas.delete();}}
        final String[] layeringMenuItems = {"Bring to front", "Send to back"};
        final int[]    layeringKeyCodes = {KeyEvent.VK_F, KeyEvent.VK_B};
        final ActionListener[] layeringActionListeners = {
         new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                  canvas.bringToFront();}},
         new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                  canvas.sendToBack();}}
        private JavaDraw(){
         super("JavaDraw!");
         toolbar.setCanvas(canvas);
         getContentPane().add(toolbar, BorderLayout.SOUTH);
         getContentPane().add(canvas, BorderLayout.CENTER);
         createMenus();
         setJMenuBar(mb);
         setLocation(100, 20);
         pack();
         setVisible(true);
        static public void main(String[] args){
         JavaDraw javaDraw = new JavaDraw();
        private void initMenus(JMenu m,
                      String  miLabel,
                      int keyCode,
                      int menuMask,
                      ActionListener al){
         JMenuItem mi = new JMenuItem(miLabel);
         m.add(mi);
         mi.addActionListener(al);
         mi.setAccelerator(KeyStroke.getKeyStroke(keyCode, menuMask));
        private void createMenus(){
         JMenu m;
         m = new JMenu("File");
         for(int i = 0; i < fileMenuItems.length; i++)
             initMenus(m,
                    fileMenuItems,
              fileKeyCodes[i],
              menuMask,
              fileActionListeners[i]);
         mb.add(m);
         m = new JMenu("Edit");
         for(int i = 0; i < editMenuItems.length; i++)
         initMenus(m,
              editMenuItems[i],
              editKeyCodes[i],
              editMenuMasks[i],
              editActionListeners[i]);
         mb.add(m);
         m = new JMenu("Layering");
         for(int i = 0; i < layeringMenuItems.length; i++)
         initMenus(m,
              layeringMenuItems[i],
              layeringKeyCodes[i],
              menuMask,
              layeringActionListeners[i]);
         mb.add(m);
    *-------------------------------------------------------------- 80 columns ---|
    * The DrawingCanvas class a small extension of JComponent
    * @version 1.1 15/04/01
    * @author Julie Zelenski
    * @author (touched up by Ian A. Mason)
    * @see javax.swing.JComponent
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import java.util.*;
    public class DrawingCanvas extends JComponent{
    static final int DRAG_NONE = 0;
    static final int DRAG_CREATE = 1;
    static final int DRAG_RESIZE = 2;
    static final int DRAG_MOVE = 3;
    // list of all shapes on canvas
    protected Vector allShapes;          
    // currently selected shape (can be null at times)
    protected Rect selectedShape;
    // reference to toolbar to message for tool&color settings
    protected Toolbar toolbar;
    protected Rect clipboard=null;          
    /* These are the unimplemented menu commands. The menus are already
    * set up to send the correct messages to the canvas, but the
    * method bodies themselves are currently completely empty. It will
    * be your job to fill them in!
    public void cut() {
         copy();
         delete();
    public void copy() {
         int x=(int)selectedShape.getBounds().getX();
         int y=(int)selectedShape.getBounds().getY();
         Point p=new Point(x,y);
         clipboard=new Rect(p,this);
         clipboard.setBounds(selectedShape.getBounds());
    public void paste() {
         if(clipboard==null)
              return;
         allShapes.add(clipboard);
         setSelectedShape(clipboard);
         copy();
         this.repaint();
    public void delete() {
         if(selectedShape==null)
              return;
         else{
         int num=allShapes.indexOf(selectedShape);
         allShapes.remove(num);
         selectedShape=null;
         this.repaint();
    public void clearAll() {
         allShapes.removeAllElements();
         this.repaint();
    public void loadFile() {
         Load load=new Load(this);
         load.setSize(250,200);
         load.validate();
         load.setVisible(true);
    public void done(Vector vect){
         allShapes.removeAllElements();
         for(int i=0;i<vect.size();i++){
              allShapes.add(vect.elementAt(i));
         this.repaint();
    public void saveToFile() {
         Save save=new Save(allShapes);
         save.setSize(250,200);
         save.validate();
         save.setVisible(true);
    public void bringToFront() {
         if(selectedShape==null)
              return;
         int size=allShapes.size();
         int index=allShapes.indexOf(selectedShape);
         for(int i=index+1;i<=size-1;i++){
              allShapes.set(i-1,allShapes.elementAt(i));
         allShapes.set(size-1,selectedShape);
         this.repaint();
    public void sendToBack() {
         if(selectedShape==null)
              return;
         int index=allShapes.indexOf(selectedShape);
         for(int i=index-1;i>=0;i--){
              allShapes.remove(allShapes.elementAt(i+1));
              allShapes.add(i+1,allShapes.elementAt(i));
         allShapes.remove(allShapes.elementAt(0));
         allShapes.add(0,selectedShape);
         this.repaint();
    * Constructor for creating a new empty DrawingCanvas. We set up
    * our size and background colors, instantiate an empty vector of shapes,
    * and install a listener for mouse events using our inner class
    * CanvasMouseHandler
    public DrawingCanvas(Toolbar tb, int width, int height){
         setPreferredSize(new Dimension(width, height));
         setBackground(Color.white);
         toolbar = tb;
         allShapes = new Vector();
         selectedShape = null;
         CanvasMouseHandler handler = new CanvasMouseHandler();
         addMouseListener(handler);
         addMouseMotionListener(handler);
    * All components are responsible for drawing themselves in
    * response to repaint() requests. The standard method a component
    * overrides is paint(Graphics g), but for Swing components, the default
    * paint() handler calls paintBorder(), paintComponent() and paintChildren()
    * For a Swing component, you override paintComponent and do your
    * drawing in that method. For the drawing canvas, we want to
    * clear the background, then iterate through our shapes asking each
    * to draw. The Graphics object is clipped to the region to update
    * and we use to that avoid needlessly redrawing shapes outside the
    * update region.
    public void paintComponent(Graphics g){
         Rectangle regionToRedraw = g.getClipBounds();
         g.setColor(getBackground());
         g.fillRect(regionToRedraw.x, regionToRedraw.y,
              regionToRedraw.width, regionToRedraw.height);
         Iterator iter = allShapes.iterator();
         while (iter.hasNext())
         ((Rect)iter.next()).draw(g, regionToRedraw);
    * Changes the currently selected shape. There is at most
    * one shape selected at a time on the canvas. It is possible
    * for the selected shape to be null. Messages the shape to
    * change its selected state which will in turn refresh the
    * shape with the knobs active.
    protected void setSelectedShape(Rect shapeToSelect) {
         // if change in selection
         if (selectedShape != shapeToSelect) {
         // deselect previous selection
         if (selectedShape != null)
              selectedShape.setSelected(false);
         // set selection to new shape
         selectedShape = shapeToSelect;
         if (selectedShape != null) {
              shapeToSelect.setSelected(true);
    * A hit-test routine which finds the topmost shape underneath a
    * given point.We search Vector of shapes in back-to-front order
    * since shapes created later are added to end and drawn last, thus
    * appearing to be "on top" of the earlier ones. When a click comes
    * in, we want to select the top-most shape.
    protected Rect shapeContainingPoint(Point pt){
         for (int i = allShapes.size()-1; i >= 0; i--) {
         Rect r = (Rect)allShapes.elementAt(i);
         if (r.inside(pt)) return r;
         return null;
    * The inner class CanvasMouseHandler is the object that handles the
    * mouse actions (press, drag, release) over the canvas. Since there is
    * a bit of state to drag during the various operations (which shape,
    * where we started from, etc.) it is convenient to encapsulate all that
    * state with this little convenience object and register it as the
    * handler for mouse events on the canvas.
    protected class CanvasMouseHandler
         extends MouseAdapter implements MouseMotionListener {
         Point dragAnchor;          
         // variables using to track state during drag operations
         int dragStatus;
         /** When the mouse is pressed we need to figure out what
         * action to take. If the tool mode is arrow, the click might
         * be a select, move or reisze. If the tool mode is one of the
         * shapes, the click initiates creation of a new shape.
         public void mousePressed(MouseEvent event){
         Rect clicked = null;
         Point curPt = event.getPoint();
         // first, determine if click was on resize knob of selected shape
         if (toolbar.getCurrentTool() == Toolbar.SELECT) {
              if (selectedShape != null &&
              (dragAnchor = selectedShape.getAnchorForResize(curPt))
              != null) {
              // drag will resize this shape
              dragStatus = DRAG_RESIZE;     
              } else if ((clicked = shapeContainingPoint(curPt)) != null) {
              // if not, check if any shape was clicked
              setSelectedShape(clicked);
              // drag will move this shape      
              dragStatus = DRAG_MOVE;
              dragAnchor = curPt;
              } else {     
              // else this was a click in empty area,
              // deselect selected shape,
              setSelectedShape(null);
              // drag does nothing in this case
              dragStatus = DRAG_NONE;
         } else {
              Rect newShape = new Rect(curPt, DrawingCanvas.this);
              // create rect here
              allShapes.add(newShape);
              setSelectedShape(newShape);
              dragStatus = DRAG_CREATE;          
              // drag will create (resize) this shape
              dragAnchor = curPt;
         /** As the mouse is dragged, our listener will receive periodic
         * updates as mouseDragged events. When we get an update position,
         * we update the move/resize event that is in progress.
         public void mouseDragged(MouseEvent event){
         Point curPt = event.getPoint();
         switch (dragStatus) {
         case DRAG_MOVE:
              selectedShape.translate(curPt.x - dragAnchor.x,
                             curPt.y - dragAnchor.y);
              // update for next dragged event
              dragAnchor = curPt;
              break;
         case DRAG_CREATE: case DRAG_RESIZE:
              selectedShape.resize(dragAnchor, curPt);
              break;
         public void mouseMoved(MouseEvent e) {}
    /** A little helper routine that will be useful for the load & save
    * operations. It brings up the standard JFileChooser dialog and
    * allows the user to specify a file to open or save. The return
    * value is the full path to the chosen file or null if no file was
    * selected.
    protected String filenameChosenByUser(boolean forOpen){
         JFileChooser fc = new JFileChooser(System.getProperty("user.dir") +
                             java.io.File.separator + "Documents");
         int result = (forOpen? (fc.showOpenDialog(this)) :
              fc.showSaveDialog(this));
         java.io.File chosenFile = fc.getSelectedFile();
         if (result == JFileChooser.APPROVE_OPTION && chosenFile != null)
         return chosenFile.getPath();
         return null;
         // return null if no file chosen or dialog cancelled
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.Vector;
    import java.io.*;
    class Load extends JFrame implements ActionListener, Serializable{
         Container contentPane;
         JTextField jtf;
         JButton jb;
         Object obj=null;
         Load load;
         Thread thread;
         DrawingCanvas draw;
         public Load(DrawingCanvas dc){
              draw=dc;
              contentPane=getContentPane();
              contentPane.setLayout(new FlowLayout());
              jtf=new JTextField(20);
              jb=new JButton("Load");
              jb.addActionListener(this);
              contentPane.add(jtf);
              contentPane.add(jb);
         public void actionPerformed(ActionEvent e){
              String text=jtf.getText();
              SimpleObjectReader reader=SimpleObjectReader.openFileForReading(text+".shp");
              if(reader==null){
                   System.out.println("Couldn't open file!");
                   return;
              obj=reader.readObject();
              reader.close();
              draw.done((Vector)obj);
              this.setVisible(false);
    import javax.swing.*;
    import java.awt.event.*;
    import java.awt.*;
    import java.util.Vector;
    import java.io.*;
    class Save extends JFrame implements ActionListener, Serializable{
         Container contentPane;
         JTextField jtf;
         Vector shapes;
         JButton jb;
         public Save(Vector shapeVector){
              shapes=shapeVector;
              contentPane=getContentPane();
              contentPane.setLayout(new FlowLayout());
              jtf=new JTextField(20);
              jb=new JButton("Save");
              jb.addActionListener(this);
              contentPane.add(jtf);
              contentPane.add(jb);
         public void actionPerformed(ActionEvent e){
              String text=jtf.getText();
              SimpleObjectWriter writer=SimpleObjectWriter.openFileForWriting(text+".shp");
              if(writer==null){
                   System.out.println("Couldn't open file!");
                   return;
              writer.writeObject(shapes);
              writer.close();
              this.setVisible(false);
    *-------------------------------------------------------------- 80 columns ---|
    * The RectShape class defines a simple rectangular shape object.
    * It tracks its bounding box, selected state, and the canvas it is being
    * drawn in. It has some basic methods to select, move, and resize the
    * rectangle. It has methods that draw the shape in the selected or unselected
    * states and updates the canvas whenever the state or bounds of the rectangle
    * change. The code that is there works properly, but you will need to extend
    * and change the code to support additional features.
    * @version 1.1 15/04/01
    * @author Julie Zelenski
    * @author (touched up by Ian A. Mason)
    import java.awt.*;
    import java.io.*;
    public class Rect implements Serializable{     
    protected Rectangle bounds;
    protected boolean isSelected;
    public Color color;
    public DrawingCanvas canvas;
    protected static final int KNOB_SIZE = 6;
    protected static final int NONE = -1;
    protected static final int NW = 0;
    protected static final int SW = 1;
    protected static final int SE = 2;
    protected static final int NE = 3;
    /** The constructor that creates a new zero width and height rectangle
    * at the given position in the canvas.
    public Rect(Point start, DrawingCanvas dcanvas){
         canvas = dcanvas;
         bounds = new Rectangle(start);
         color=canvas.toolbar.getCurrentColor();
    /** The "primitive" for all resizing/moving/creating operations that
    * affect the rect bounding box. The current implementation just resets
    * the bounds variable and triggers a re-draw of the union of the old &
    * new rectangles. This will redraw the shape in new size and place and
    * also "erase" if bounds are now smaller than before. It is a good
    * design to have all changes to a critical variable bottleneck through
    * one method so that you can be sure that all the updating that goes
    * with it only needs to be implemented in this one place. If any of your
    * subclasses have additional work to do when the bounds change, this is
    * the method to override. Make sure that any methods that change the
    * bounds call this method instead of directly manipulating the variable.
    protected void setBounds(Rectangle newBounds){
         Rectangle oldBounds = bounds;
         bounds = newBounds;
         updateCanvas(oldBounds.union(bounds));
    /** The resize operation is called when first creating a rect, as well as
    * when later resizing by dragging one of its knobs. The two parameters
    * are the points that define the new bounding box. The anchor point
    * is the location of the mouse-down event during a creation operation
    * or the opposite corner of the knob being dragged during a resize
    * operation. The end is the current location of the mouse. If you
    * create the smallest rectangle which encloses these two points, you
    * will have the new bounding box. Use the setBounds() primitive which
    * is the bottleneck we are using for all geometry changes, it handles
    * updating and redrawing.
    public void resize(Point anchor, Point end){
         Rectangle newRect = new Rectangle(anchor);
         // creates smallest rectange which
         // includes both anchor & end
         newRect.add(end);
         // reset bounds & redraw affected areas
         setBounds(newRect);      
    public Rectangle getBounds(){
         return bounds;
    /** The translate operation is called when moving a shape by dragging in
    * the canvas. The two parameters are the delta-x and delta-y to move
    * by. Note that either or both can be negative. Create a new rectangle
    * from our bounds and translate and then go through the setBounds()
    * primitive to change it.
    public void translate(int dx, int dy){
         Rectangle newRect = new Rectangle(bounds);
         newRect.translate(dx, dy);
         setBounds(newRect);
    /** Used to change the selected state of the shape which will require
    * updating the affected area of the canvas to add/remove knobs.
    public void setSelected(boolean newState){
         isSelected = newState;
         // need to erase/add knobs
         // including extent of extended bounds
         updateCanvas(bounds, true);
    /** The updateCanvas() methods are used when the state has changed
    * in such a way that it needs to be refreshed in the canvas to properly
    * reflect the new settings. The shape should take responsibility for
    * messaging the canvas to properly update itself. The appropriate AWT/JFC
    * way to re-draw a component is to send it the repaint() method with the
    * rectangle that needs refreshing. This will cause an update() event to
    * be sent to the component which in turn will call paint(), where the
    * real drawing implementation goes. See the paint() method in
    * DrawingCanvas to see how it is implemented.
    protected void updateCanvas(Rectangle areaOfChange, boolean enlargeForKnobs){
         Rectangle toRedraw = new Rectangle(areaOfChange);
         if (enlargeForKnobs)
         toRedraw.grow(KNOB_SIZE/2, KNOB_SIZE/2);
         canvas.repaint(toRedraw);
    protected void updateCanvas(Rectangle areaOfChange){
         updateCanvas(areaOfChange, isSelected);
    /** When the DrawingCanvas needs a shape to draw itself, it sends a draw
    * message, passing the graphics context and the current region being
    * redrawn. If the shape intersects with that region, it must draw itself
    * doing whatever it takes to properly represent itself in the canvas
    * (colors, location, size, knobs, etc.) by messaging the Graphics object.
    public void draw(Graphics g, Rectangle regionToDraw){
         if (!bounds.intersects(regionToDraw))
         return;
         g.setColor(color);
         g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
         if (isSelected) { // if selected, draw the resizing knobs
         // along the 4 corners
         Rectangle[] knobs = getKnobRects();
         for (int i = 0; i < knobs.length; i++)
              g.fillRect(knobs[i].x, knobs[i].y,
                   knobs[i].width, knobs[i].height);
    /** When the DrawingCanvas needs to determine which shape is under
    * the mouse, it asks the shape to determine if a point is "inside".
    * This method should returns true if the given point is inside the
    * region for this shape. For a rectangle, any point within the
    * bounding box is inside the shape.
    public boolean inside(Point pt){
         return bounds.contains(pt);
    /** When needed, we create the array of knob rectangles on demand. This
    * does mean we create and discard the array and rectangles repeatedly.
    * These are small objects, so perhaps it is not a big deal, but
    * a valid alternative would be to store the array of knobs as an
    * instance variable of the Shape and and update the knobs as the bounds
    * change. This means a little more memory overhead for each Shape
    * (since it is always storing the knobs, even when not being used) and
    * having that redundant data opens up the possibility of bugs from
    * getting out of synch (bounds move but knobs didn't, etc.) but you may
    * find that a more appealing way to go. Either way is fine with us.
    * Note this method provides a nice unified place for one override from
    * a shape subclass to substitute fewer or different knobs.
    protected Rectangle[] getKnobRects(){
         Rectangle[] knobs = new Rectangle[4];
         knobs[NW] = new Rectangle(bounds.x - KNOB_SIZE/2,
                        bounds.y - KNOB_SIZE/2, KNOB_SIZE, KNOB_SIZE);
         knobs[SW] = new Rectangle(bounds.x - KNOB_SIZE/2,
                        bounds.y + bounds.height - KNOB_SIZE/2,
                        KNOB_SIZE, KNOB_SIZE);
         knobs[SE] = new Rectangle(bounds.x + bounds.width - KNOB_SIZE/2,
                        bounds.y + bounds.height - KNOB_SIZE/2,
                        KNOB_SIZE, KNOB_SIZE);
         knobs[NE] = new Rectangle(bounds.x + bounds.width - KNOB_SIZE/2,
                        bounds.y - KNOB_SIZE/2,
                        KNOB_SIZE, KNOB_SIZE);
         return knobs;
    /** Helper method to determine if a point is within one of the resize
    * corner knobs. If not selected, we have no resize knobs, so it can't
    * have been a click on one. Otherwise, we calculate the knob rects and
    * then check whether the point falls in one of them. The return value
    * is one of NW, NE, SW, SE constants depending on which knob is found,
    * or NONE if the click doesn't fall within any knob.
    protected int getKnobContainingPoint(Point pt){
         // if we aren't selected, the knobs
         // aren't showing and thus there are no knobs to check
         if (!isSelected) return NONE;
         Rectangle[] knobs = getKnobRects();
         for (int i = 0; i < knobs.length; i++)
         if (knobs[i].contains(pt))
              return i;
         return NONE;
    /** Method used by DrawingCanvas to determine if a mouse click is starting
    * a resize event. In order for it to be a resize, the click must have
    * been within one of the knob rects (checked by the helper method
    * getKnobContainingPoint) and if so, we return the "anchor" ie the knob
    * opposite this corner that will remain fixed as the user drags the
    * resizing knob of the other corner around. During the drag actions of a
    * resize, that fixed anchor point and the current mouse point will be
    * passed to the resize method, which will reset the bounds in response
    * to the movement. If the mouseLocation wasn't a click in a knob and
    * thus not the beginning of a resize event, null is returned.
    public Point getAnchorForResize(Point mouseLocation){
         int whichKnob = getKnobContainingPoint(mouseLocation);
         // no resize knob is at this location
         if (whichKnob == NONE)
         return null;
         switch (whichKnob) {
         case NW: return new Point(bounds.x + bounds.width,
                        bounds.y + bounds.height);
         case NE: return new Point(bounds.x, bounds.y + bounds.height);
         case SW: return new Point(bounds.x + bounds.width, bounds.y);
         case SE: return new Point(bounds.x, bounds.y);
         return null;
    import java.io.*;
    * SimpleObjectReader is a small class to wrap around the usual ObjectStream
    * to shield you from the exception handling which we haven't yet gotten
    * to in class.
    * <P>It has just three methods of note: one to open a new file for reading,
    * one to read an object from an open file, and one to close the file when done.
    * <P>Any object that you attempt to read must properly implement the Serializable
    * interface. Here is a simple example that shows using the SimpleFileReader to
    * to rehydrate objects from a file and print them:
    * <PRE>
    * SimpleObjectReader reader = SimpleObjectReader.openFileForReading("shapes");
    * if (reader == null) {
    * System.out.println("Couldn't open file!");
    * return;
    * Object obj;
    * while ((obj = reader.readObject()) != null)
    * System.out.println(obj);
    * reader.close();
    * </PRE>
    * <P>You are free to edit or extend this class, but we don't expect that
    * you should need to make any changes.
    * @version 1.1 15/04/01
    * @author Julie Zelenski
    * @author (touched up by Ian A. Mason)
    public class SimpleObjectReader {
    private ObjectInputStream ois;
    * Opens a new file for reading. The filename can either be a relative
    * path, which will be relative to the working directory of the program
    * when started, or an absolute path. If the file exists and can be
    * opened, a new SimpleObjectReader is returned. If the file cannot be
    * opened (for any reason: wrong name, wrong path, lack of permissions, etc.)
    * null is returned.
    public static SimpleObjectReader openFileForReading(String filename){
         try {
         return new SimpleObjectReader(new ObjectInputStream(new FileInputStream(filename)));
         } catch(IOException e) {     
         return null;
    * Reads a single object from the file and returns it. If there are
    * no more objects in the file (i.e, we have reached the end of file),
    * null is returned null is returned. null is also
    * returned on any I/O error.
    public Object readObject (){
         try {
         return ois.readObject();
         } catch (IOException e) {
         e.printStackTrace();
         return null;
         } catch (ClassNotFoundException e) {
         e.printStackTrace();
         return null;
    * Closes the file when done reading. You should close a reader when
    * you are finished to release the OS resources for use by others.
    public void close (){
         try {
         ois.close();
         catch (IOException e) {}
    * Constructor is private so that only means to create a new reader
    * is through the static method which does error checking.
    private SimpleObjectReader(ObjectInputStream ois){
         this.ois = ois;
    import java.io.*;
    * SimpleObjectWriter is a small class to wrap around the usual
    * ObjectOutputStream to shield you from the exception handling
    * which we haven't yet gotten to in class.
    * <P>It has just three methods of note: one to open a new file for writing,
    * one to write an object to the file, and one to close the
    * the file when done.
    * <P>Here is a simple example that shows using the SimpleObjectWriter
    * to create a new file and write some objects into it:
    * <PRE>
    * SimpleObjectWriter writer =
    * SimpleObjectWriter.openFileForWriting("objects");
    * if (writer == null) {
    * System.out.println("Couldn't open file!");
    * return;
    * writer.writeObject("Here is a string");
    * writer.writeObject("And another one.");
    * writer.writeObject(new Date());
    * writer.close();
    * </PRE>
    * <P>You are free to edit or extend this class, but we don't expect that
    * you should need to make any changes.
    * @version 1.1 15/04/01
    * @author Julie Zelenski
    * @author (touched up by Ian A. Mason)
    public class SimpleObjectWriter {
    private ObjectOutputStream oos;
    * Opens a new file for writing. The filename can either be a relative
    * path, which will be relative to the working directory of the program
    * when started, or an absolute path. If the file can be created, a
    * new SimpleObjectWriter is returned. If the file already exists, this
    * will overwrite its content

    I'm not reading that either, but to help you for next time:
    - use more than 1 sentence to describe your problem
    - only post the RELEVANT code, or a small test program with the same problem if possible.
    At least you formatted it, I'll give you that.
    Cheers,
    Radish21
    PS. I think in this case, posting another (better worded) thread might be a good idea, because no one is going to read this one. In general though, don't :)

  • Still having navigation problems and need help with how to debug

    Hi,
    I've been porting over a servlet project to JSF and I'm still having navigation problems. I thought the problem might have been because the original project used HTML frames and so the "from-view-id" JSP defined the frame/framesets and the specific JSP that does the submit (and so is named in the "from-view-id" is never defined in a "to-view-id" attribute). I've now switched to using an IFRAME, and that resolves that problem. So now the JSP is defined in a "to-view-id" attribute and it includes an named IFRAME that can be used as a target. I press the submit button and I get not the JSP expected butinstead the same JSP displayed inside its own IFRAME.
    Here is the code for the submit. I've simplified it as much as possible with a static action (originally it was a call to a method) just to try and get things to work. This is the current version:
    <h:commandButton value="View Alias" action="foo" styleClass="select" type="submit" />Here is the navigation rule in faces-config.xml. Again, the problem is that SelectManager get redisplayed in the IFRAME instead of display.jsp.
    <navigation-rule>
       <from-view-id>/SelectManager.jsp</from-view-id>
       <navigation-case>
          <from-outcome>foo</from-outcome>
          <to-view-id>/display.jsp</to-view-id>
       </navigation-case>
    </navigation-rule>I have also tried it without the "from-outcome-value" which I presume means that the "to-view-id" gets displayed unconditionally and it still fails. Any ideas on how I can debug this? (I'm using GlassFish if that's important to know)
    Rob Tanner
    Linfield College

    Raymond, The real trick is avoid doing technical things when coming down with the flu (I should also add that I'm a JSF newbie). Reading your original message this time I see what you're suggesting and found a conversion error although I don't understand it. Here's the code (including the <h:message/>):
                <h:selectOneMenu value="#{members.dcodes}"
                  style="color: #7f0000" id="selector">
                  <f:selectItems value="#{members.departmentList}" />
                </h:selectOneMenu> 
                <h:message for="selector" style="color:white"/>And here's a snippet of the generated HTML:
    <select id="j_id_id26:selector" name="j_id_id26:selector" size="1" style="color: #7f0000">
             <option value="aad" selected="selected">Academic Advising</option>
         <option value="aaf">Academic Affairs</option>
         <option value="adm">Admission</option>
         <option value="up">Upward Bound</option>
    </select>If I select "Admission" for example, the error I get is:
    Conversion Error setting value 'adm' for 'null Converter'.Since everything is a String value, I don't get the error. Could someone please enlighten me.
    Thanks.

  • Adding a Text Frame to an Existing Group

    I have belatedly discovered another difference between CS4 and CS2 -- I don't know whether this started with CS3 or not; I think perhaps it did.
    When you want to add a text frame to an existing group (which means create a new one within group), it's fairly straightforward unless the group is inline to a story. Then the new item gets added at the wrong place (I suspect what actually happens is that it always used to get added at the wrong place and then moved to the specified coordinates; but in CS2 and earlier, there was no automatic updating of the screen so the coordinates worked, but in CS4, the addition of the new frame moves the inline and so the coordinates you're aiming for are no longer correct). I worked around this in the following script by changing the anchoring and then changing it back -- I'm not entirely sure that this is foolproof, but it works on the job we're using it for.
    //DESCRIPTION: Add New TF to Parent Group of Selected TF
    (function() {
         if (app.documents.length > 0 &&
                   app.selection.length === 1 &&
                   app.selection[0].parent instanceof Group &&
                   app.selection[0] instanceof TextFrame) {
         var group = app.selection[0].parent;
         if (group.parent instanceof Character) {
              // we have an anchored group. Make sure it is custom while processing
              var origAncState = group.anchoredObjectSettings.anchoredPosition;
              group.anchoredObjectSettings.anchoredPosition = AnchorPosition.anchored;
         var bounds = app.selection[0].geometricBounds;
         var newTF = group.textFrames.add({geometricBounds:bounds});
         newTF.move(undefined, [0, -1]); // offset a pica -- or whatever the units are
         if (origAncState !== undefined) {
              group.anchoredObjectSettings.anchoredPosition = origAncState;
         app.select(newTF);
         } else {
              alert("Please select a text frame in a group.");
    Dave

    Open the PDF in Acrobat (not Reader).
    Use the "Draw Rectangle" tool (Comment :: Drawing Markups)
    Go into the Rectangle Properties to configure appearance for border line style, thickness and color; fill color and opacity.
    Be well...

Maybe you are looking for