Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

Get JToolBar position in BorderLayout

843806Aug 24 2009 — edited Aug 25 2009
Greetings:

I've a JToolBar put in a JPanel with BorderLayout. I would like to capture where the user last left the JToolBar, based in the 4 possible corners (+borders+); I've tried BorderLayout.getLayoutComponent (Container target, Object constraints) with not much luck (it always throws me an exception, not matter if I do it before or after the JtoolBar instantiation).

Do anyone knows what can I do besides getting the raw x,y position? (or the propper use of BorderLayout.getLayoutComponent)

Thanks a lot in advanced

Comments

843806
I don't know the canonical way of doing something like this, but perhaps a property change listener may help.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Point;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.*;

public class FuSwing1 {
   private static void createAndShowUI() {
      JPanel panel = new JPanel();
      panel.setPreferredSize(new Dimension(400, 400));
      panel.setLayout(new BorderLayout());

      final JToolBar toolbar = new JToolBar("Tool Bar", JToolBar.HORIZONTAL);
      toolbar.add(new JButton("Foo"));
      panel.add(toolbar, BorderLayout.NORTH);

      toolbar.addPropertyChangeListener(new PropertyChangeListener() {

         @Override
         public void propertyChange(PropertyChangeEvent evt) {
            SwingUtilities.invokeLater(new Runnable() {
               public void run() {
                  String orientation = toolbar.getOrientation() == SwingConstants.HORIZONTAL ? 
                           "Horizontal" : "Vertical";
                  Point p = toolbar.getLocation();
                  System.out.println(orientation + ", [" + p.x + ", " + p.y + "]");
               }
            });
         }

      });

      JFrame frame = new JFrame("FuSwing1");
      frame.getContentPane().add(panel);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}
darrylburke
Aw, c'mon. Have you even tried plugging the position detection code into the HierarchyListener from your previous thread?
      toolBar.addHierarchyListener(new HierarchyListener() {
 
         public void hierarchyChanged(HierarchyEvent e) {
            Window window = SwingUtilities.getWindowAncestor(toolBar);
            if (window == MainWin.this) {
               // getLayoutComponent code here
            } else if (window != null) {
               toolBar.setOrientation(JToolBar.HORIZONTAL);
            }
         }
      });
Note: untested addition. Try it and post back.

db

Edited by: DarrylBurke -- shortened the code
843806
Greetings:

Thanks a lot for your reply!, really :)

I've used this code:
 public BorderLayout toolBarPanelLayout = new BorderLayout();
      public JPanel toolBarPanel = new JPanel(toolBarPanelLayout);
      public JToolBar toolBar = new JToolBar(JToolBar.VERTICAL);
      public JButton buttonOpen = new JButton("Open"),
                     buttonSave = new JButton("Save"),
                     buttonPrint = new JButton(" Print");
      public JToolBar.Separator separator = new JToolBar.Separator();

           .
           .
           .           

      // Identify if our toolBar is docked; for that, we check if it is dependant of our frame or
      // of the current L&F manager; when it is docked, it will be part of our frame's hierarchy,
      // else, it will be part of javax.swing.plaf.basic.BasicToolBarUI.ToolBarDialog 
      // (controled by the current L&F manager).

     toolBar.addHierarchyListener(new HierarchyListener() {
         public void hierarchyChanged(HierarchyEvent e) {
            Window window = SwingUtilities.getWindowAncestor(toolBar);
            if (window == MainWin.this) {
              // getLayoutComponent code here
              System.out.println("ToolBarConstraints = " + toolBarPanelLayout.getLayoutComponent(toolBar));
              System.out.println("ToolBarConstraints = " + toolBarPanelLayout.getConstraints(toolBar));
            } else if (window != null) { toolBar.setOrientation(JToolBar.HORIZONTAL); }
         }
      });
Yet, I get the next exception:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: cannot get component: unknown constraint: javax.swing.JToolBar[,0,0,0x0,invalid,layout=javax.swing.JToolBar$DefaultToolBarLayout,alignmentX=0.0,alignmentY=0.0,border=com.sun.java.swing.plaf.windows.WindowsBorders$ToolBarBorder@136228,
flags=328,maximumSize=,minimumSize=,preferredSize=,floatable=true,margin=,orientation=VERTICAL,paintBorder=true]

It's quite weird, as it is actually showing me the constraints but it says that it is illegal.. any idea about it?

By the othe hand, please tell me if what I've put in comments actually expresses the situation: your aproach is so pro that I want to understand the idea (not as deeply as you of course, but at least to understand what your magic trick does ;)).

Thanks again for the great help; I'm amazed that with a single listener I can solve both issues: this are really the answers I was looking for.

Later

p.s I was thinking in using the "setName()" command, so If I could figure it out it's current name, I can know where it was at the Border the last time the user undocked the toolBar; yet, I cannot get the constraints :/ ( that is, getConstraints() ) to work either, as you can see in the code I've put.
camickr
I've used this code:
That code doesn't compile so I'm not sure how you used it. We can't understand the problem if we don't understand the context of how it is being used.

If you need further help then you need to create a [Short, Self Contained, Compilable and Executable, Example Program (SSCCE)|http://homepage1.nifty.com/algafield/sscce.html], that demonstrates the incorrect behaviour.
843806
Greetings:

You are right, DarrylBurke and I were assuming incorrectly the context. Here I put the full code: my sincere appologies about this.
// java scope
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public abstract class ToolBarTest {
   public static void main(String[] args) {
      try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); }
      catch (Exception e) { }
      
      SwingUtilities.invokeLater(new Runnable() {
         public void run() { MainWin myWindow = new MainWin(" ToolBar Test");
                             myWindow.pack();
                             myWindow.setVisible(true);
                           }
      });
  }
}

class MainWin extends JFrame {
      public BorderLayout toolBarPanelLayout = new BorderLayout();
      public JPanel toolBarPanel = new JPanel(toolBarPanelLayout);
      public JToolBar toolBar = new JToolBar(JToolBar.VERTICAL);
      public JButton buttonOpen = new JButton("Open"),
                     buttonSave = new JButton("Save"),
                     buttonPrint = new JButton(" Print");
      public JToolBar.Separator separator = new JToolBar.Separator();

public MainWin (String mainWin_title) {
      Container framePanel = this.getContentPane();
      Insets buttons_Insets = new Insets(1, 1, 1, 1);

      this.setTitle(mainWin_title);
      this.setLocationRelativeTo(null);
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      // init.components
      toolBar.setRollover(true);

      // Identify if our toolBar is docked; for that, we check if it is dependant of our frame or
      // of the current L&F manager; when it is docked, it will be part of our frame's hierarchy,
      // else, it will be part of javax.swing.plaf.basic.BasicToolBarUI.ToolBarDialog 
      // (controled by the current L&F manager).

     toolBar.addHierarchyListener(new HierarchyListener() {
         public void hierarchyChanged(HierarchyEvent e) {
            Window window = SwingUtilities.getWindowAncestor(toolBar);
            if (window == MainWin.this) {
              // getLayoutComponent code here
              System.out.println("ToolBarConstraints = " + toolBarPanelLayout.getLayoutComponent(toolBar));
              System.out.println("ToolBarConstraints = " + toolBarPanelLayout.getConstraints(toolBar));
           
            } else if (window != null) { toolBar.setOrientation(JToolBar.HORIZONTAL); }
         }
      });

      buttonOpen.setMargin(buttons_Insets);
         buttonOpen.setBorder(BorderFactory.createTitledBorder(""));
      buttonSave.setMargin(buttons_Insets);
         buttonSave.setBorder(BorderFactory.createTitledBorder(""));
      buttonPrint.setMargin(buttons_Insets);
         buttonPrint.setBorder(BorderFactory.createTitledBorder(""));

      // set.components
      toolBar.add(buttonOpen);
         toolBar.add(buttonSave);
         toolBar.add(separator);
         toolBar.add(buttonPrint);
      framePanel.add(toolBar,BorderLayout.WEST);
   }
}
darrylburke
Right method (almost!), wrong objects.
import java.awt.*;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import javax.swing.*;

public abstract class ToolBarTest {

   public static void main(String[] args) {
      try {
         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      } catch (Exception e) {
      }

      SwingUtilities.invokeLater(new Runnable() {

         public void run() {
            MainWin myWindow = new MainWin(" ToolBar Test");

            myWindow.pack();
            myWindow.setVisible(true);
         }
      });
   }
}

class MainWin extends JFrame {

   BorderLayout layout;
   private JToolBar toolBar = new JToolBar(JToolBar.VERTICAL);
   private JButton buttonOpen = new JButton("Open");
   private JButton buttonSave = new JButton("Save");
   private JButton buttonPrint = new JButton(" Print");
   private JToolBar.Separator separator = new JToolBar.Separator();

   public MainWin(String mainWin_title) {
      Container framePanel = this.getContentPane();
      Insets buttons_Insets = new Insets(1, 1, 1, 1);

      this.setTitle(mainWin_title);
      this.setLocationRelativeTo(null);
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      layout = (BorderLayout) framePanel.getLayout();

      toolBar.setRollover(true);
      buttonOpen.setMargin(buttons_Insets);
      buttonOpen.setBorder(BorderFactory.createTitledBorder(""));
      buttonSave.setMargin(buttons_Insets);
      buttonSave.setBorder(BorderFactory.createTitledBorder(""));
      buttonPrint.setMargin(buttons_Insets);
      buttonPrint.setBorder(BorderFactory.createTitledBorder(""));

      toolBar.add(this.buttonOpen);
      toolBar.add(this.buttonSave);
      toolBar.add(separator);
      toolBar.add(this.buttonPrint);
      toolBar.addHierarchyListener(new HierarchyListener() {

         public void hierarchyChanged(HierarchyEvent e) {
            Window window = SwingUtilities.getWindowAncestor(toolBar);
            if (window == MainWin.this) {
               if (toolBar == layout.getLayoutComponent(BorderLayout.NORTH)) {
                  System.out.println("NORTH");
               }
               if (toolBar == layout.getLayoutComponent(BorderLayout.SOUTH)) {
                  System.out.println("SOUTH");
               }
               if (toolBar == layout.getLayoutComponent(BorderLayout.EAST)) {
                  System.out.println("EAST");
               }
               if (toolBar == layout.getLayoutComponent(BorderLayout.WEST)) {
                  System.out.println("WEST");
               }
            } else {
               System.out.println("UNDOCKED");
               if (window != null) {
                  toolBar.setOrientation(JToolBar.HORIZONTAL);
               }
            }
         }
      });
      framePanel.add(toolBar, BorderLayout.WEST);
   }
}
db
843806
Hello:

I'm glad to hear from you :) .. we are almost there. The listener:
    toolBar.addHierarchyListener(new HierarchyListener() {
       public void hierarchyChanged(HierarchyEvent e) {
            Window window = SwingUtilities.getWindowAncestor(toolBar);
            if (window == MainWin.this) {
               if (toolBar == toolBarPanelLayout.getLayoutComponent(BorderLayout.NORTH)) {
                  System.out.println("NORTH");
               }
               if (toolBar == toolBarPanelLayout.getLayoutComponent(BorderLayout.SOUTH)) {
                  System.out.println("SOUTH");
               }
               if (toolBar == toolBarPanelLayout.getLayoutComponent(BorderLayout.EAST)) {
                  System.out.println("EAST");
               }
               if (toolBar == toolBarPanelLayout.getLayoutComponent(BorderLayout.WEST)) {
                  System.out.println("WEST");
               }
            } else {
               System.out.println("UNDOCKED");
               if (window != null) {
                  toolBar.setOrientation(JToolBar.HORIZONTAL);
               }
            }
         }
    });
... almost works; the issue I find here is that the conditions "toolBar == layout.getLayoutComponent(BorderLayout.NORTH))" never happens, so it never prints any of them at the console; but now, it compiles and all :).

Thanks again for al lthe help and concern: this is prety valuable in the Java world.

Regards,
darrylburke
it never prints any of them at the console
Prints all of them for me.

db

edit You're querying the wrong BorderLayout

Edited by: DarrylBurke
843806
Hello!

Yes, you are right, my mistake was in my concept of the Panel over which the JToolBar should be; I was with the idea that it should have it's own panel, but it can go directly over the Frame's Panel. So, all what was missing is:
 Container framePanel = this.getContentPane();
  toolBarPanelLayout = (BorderLayout) framePanel.getLayout();
Thanks a lot! Your answer was just perfect :)

Regards,
1 - 9
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Sep 22 2009
Added on Aug 24 2009
9 comments
397 views