Results 1 to 10 of 10
Like Tree1Likes
  • 1 Post By JosAH

Thread: GridBagLayout vs me: 1 - 0

  1. #1
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,662
    Blog Entries
    7
    Rep Power
    21

    Default GridBagLayout vs me: 1 - 0

    Greetings,

    I'm fighting against a GridBagLayout object; suppose I want to create a panel with two rows of buttons; their widths proportional to 1 - 5 - 1 - 5 and a second row of buttons with their widths proportional to 1 - 10 - 1. (seven buttons in total). See my feeble attempts below:

    Java Code:
    import java.awt.BorderLayout;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class T {
    
    	private static void add(JPanel panel, int x, int y, int w, int h) {
    		
    		JButton button= new JButton("button");
    		GridBagConstraints gbc= new GridBagConstraints();
    		
    		gbc.gridx= x;
    		gbc.gridy= y;
    		gbc.gridwidth= w;
    		gbc.gridheight= h;
    		gbc.fill= GridBagConstraints.BOTH;
    		
    		panel.add(button, gbc);
    	}
    	
    	private static void decorate(JPanel panel) {
    		
    		add(panel,  0, 0, 1, 1);
    		add(panel,  1, 0, 5, 1);
    		add(panel,  6, 0, 1, 1);
    		add(panel,  7, 0, 5, 1);
    
    		add(panel,  0, 1, 1, 1);
    		add(panel,  1, 1, 10, 1);
    		add(panel, 11, 1, 1, 1);
    
    	}
    	public static void main(String[] args) {
    		
    		JFrame frame= new JFrame();
    		JPanel panel= new JPanel(new GridBagLayout());
    		
    		decorate(panel);
    		frame.getContentPane().add(panel, BorderLayout.CENTER);
    		frame.pack();
    		frame.setVisible(true);
    	}
    }
    As you can see the decorate( ... ) method fills the panel with the seven buttons; it's an SSCCE so you can run it: the top row has four buttons (as expected) but they all have equal widths. I didn't expect that. Can anyone show me how I could do what I had in mind? b.t.w. I want to create a virtual keyboard and everything works fine except for this *grmbl* layout issue, i.e. my keyboard looks crappy and deformed at best ;-)

    kind regards,

    Jos

    p.s. I'm sure this was a stupid question but I just can't figure it out; eternal gratitude to the one who helps me out.
    cenosillicaphobia: the fear for an empty beer glass

  2. #2
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,423
    Rep Power
    20

    Default

    It's a common enough problem with GridBagLayout. The short explanation is that GBL doesn't compute column widths for columns that don't have at least one component exclusively occupying that column (and similarly for rows).

    The only solution I know is to give the GBL what it wants.
    Java Code:
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    
    import javax.swing.*;
    
    public class T {
    
      private static void add(JPanel panel, int x, int y, int w, int h) {
    
        JButton button = new JButton("button");
        GridBagConstraints gbc = new GridBagConstraints();
    
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.gridwidth = w;
        gbc.gridheight = h;
        gbc.fill = GridBagConstraints.BOTH;
    
        panel.add(button, gbc);
      }
    
      private static void decorate(JPanel panel) {
        add(panel, 0, 0, 1, 1);
        add(panel, 1, 0, 5, 1);
        add(panel, 6, 0, 1, 1);
        add(panel, 7, 0, 5, 1);
    
        add(panel, 0, 1, 1, 1);
        add(panel, 1, 1, 10, 1);
        add(panel, 11, 1, 1, 1);
      }
    
      private static void prepare(JPanel panel) {
        GridBagConstraints gbc = new GridBagConstraints();
        for (int i = 0; i < 12; i++) {
          gbc.gridx = i;
          panel.add(new JComponent() {
    
            JButton button = new JButton("button");
    
            @Override
            public Dimension getPreferredSize() {
              return button.getPreferredSize();
            }
          }, gbc);
        }
      }
    
      public static void main(String[] args) {
    
        JFrame frame = new JFrame();
        JPanel panel = new JPanel(new GridBagLayout());
    
        prepare(panel);
        decorate(panel);
        frame.getContentPane().add(panel, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
      }
    }
    This could get even more messy when you have a whole keyboard of buttons to deal with. If you want to stagger the rows, you'll need twice the number of keys in a row +1 dummy components in an invisible row. On the plus side, you get one place where you can set a preferred size for everything else.

    db

  3. #3
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,662
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by DarrylBurke View Post
    It's a common enough problem with GridBagLayout. The short explanation is that GBL doesn't compute column widths for columns that don't have at least one component exclusively occupying that column (and similarly for rows).

    [ code snipped ...]

    The only solution I know is to give the GBL what it wants.This could get even more messy when you have a whole keyboard of buttons to deal with. If you want to stagger the rows, you'll need twice the number of keys in a row +1 dummy components in an invisible row. On the plus side, you get one place where you can set a preferred size for everything else.
    Thanks a bunch; that seems to work. So if I understand you (and your code) correctly: you fill one row and every column with a JComponent that has the size of a JButton and you'll overwrite some of those columns with the real buttons later. This seems to satisfy that darn GridBagLayout ... who'd have thought it ... it must've been a twisted mind to come up with that trick ;-)

    Thanks again and

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  4. #4
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,423
    Rep Power
    20

    Default

    Quote Originally Posted by JosAH View Post
    t must've been a twisted mind to come up with that trick ;-)
    Why thank you Jos! or not ;-)

    The buttons added later may occupy the row/column cells of the layout, but the invisible JComponents are still there -- a sysout for panel.getComponents().length prints 19.

    Getting GBL to play nice is even more fun when you start setting weightx/weighty (the gotcha is that they determine the allocation of extra space). But by far the most fun you can have with GBL is retrieving child components' constraints and changing the values of their fields at runtime, while visible ... may need to call revalidate() and/or repaint() to update the display.

    db

  5. #5
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,662
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by DarrylBurke View Post
    Why thank you Jos! or not ;-)

    The buttons added later may occupy the row/column cells of the layout, but the invisible JComponents are still there -- a sysout for panel.getComponents().length prints 19.

    Getting GBL to play nice is even more fun when you start setting weightx/weighty (the gotcha is that they determine the allocation of extra space). But by far the most fun you can have with GBL is retrieving child components' constraints and changing the values of their fields at runtime, while visible ... may need to call revalidate() and/or repaint() to update the display.
    Brrr, not for me thank you ;-) Look below what I finally managed to do; thanks again for the valuable trick; I was totally stuck with that darn GridBagLayout; it's not my cup of tea.

    kind regards,

    Jos
    Attached Thumbnails Attached Thumbnails GridBagLayout vs me: 1 - 0-keyboard.jpg  
    DarrylBurke likes this.
    cenosillicaphobia: the fear for an empty beer glass

  6. #6
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,423
    Rep Power
    20

    Default

    Hmm, what does the OK button do? And how did you do the number and other two-character buttons?

    db

  7. #7
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,662
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by DarrylBurke View Post
    Hmm, what does the OK button do? And how did you do the number and other two-character buttons?
    The OK button just dismisses the entire keyboard dialog (as the X button in the top right does). Those double character labels are just a bit of html code, e.g. the label for the '2' button is <html>2<sup>&nbsp;@</sup></html>. At the moment I'm fighting the Robot class: it doesn't like different keyboard locales, nor does it like the VK_CONTROL event. The VK_ALT event works as is ... It seems that my code needs some 'intelligence' that belongs in the keyboard driver of the application receiving the events.

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  8. #8
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,662
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by JosAH View Post
    nor does it like the VK_CONTROL event. The VK_ALT event works as is ... It seems that my code needs some 'intelligence' that belongs in the keyboard driver of the application receiving the events.
    I take that last remark back; I take the parameters for each button from a .properties file but some moron (<--- me) decided to type VK_CONROL for a 'control' key event in that file. Of course the compiler doesn't see that file and that moron (<--- me) decided to ignore the error stream where the initialization error was shown; so it to took me a couple of hours to figure it all out. Except for the localization everything works fine now.

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  9. #9
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,423
    Rep Power
    20

    Default

    Those double character labels are just a bit of html code, e.g. the label for the '2' button is <html>2<sup>&nbsp;@</sup></html>.
    I thought that might be it, but the superscripted characters looked about the same size as the others.

    If you want to place them vertically (as seen on a normal keyboard) you might find camickrs's Text Icon « Java Tips Weblog useful.

    Except for the localization everything works fine now.


    db

  10. #10
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,662
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by DarrylBurke View Post
    I thought that might be it, but the superscripted characters looked about the same size as the others.
    Don't look at me, I'm innocent; that's how my html renderer displays it; I didn't do anything ;-)

    Quote Originally Posted by DarrylBurke View Post
    If you want to place them vertically (as seen on a normal keyboard) you might find camickrs's Text Icon « Java Tips Weblog useful.
    Yep, I know about that code a.a.m.o.f. I have his site bookmarked and check it now and then; great stuff in there.

    Quote Originally Posted by DarrylBurke View Post
    I have to know a way of checking whether or not a certain keycode is valid; if not I have to post another keycode event. The robot class throws an Exception for an invalid keycode event, so maybe that's the way to go; I'll check it out tomorrow, now I have to pay attention to my genever and tobacco ;-)

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

Similar Threads

  1. [AWT] GridBagLayout Help.
    By Sandia_man in forum AWT / Swing
    Replies: 2
    Last Post: 05-23-2010, 08:54 PM
  2. help with gridbaglayout
    By robertbob in forum AWT / Swing
    Replies: 5
    Last Post: 05-18-2010, 04:14 AM
  3. GridBagLayout
    By Moncleared in forum New To Java
    Replies: 1
    Last Post: 10-18-2009, 10:12 PM
  4. GridBagLayout
    By carderne in forum New To Java
    Replies: 8
    Last Post: 01-25-2009, 02:06 PM
  5. GridBagLayout
    By MuslimCoder in forum New To Java
    Replies: 1
    Last Post: 01-15-2009, 08:54 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •