0
package swingtraining;

import static java.awt.Color.BLACK;
import java.awt.GridBagConstraints;
import static java.awt.GridBagConstraints.CENTER;
import static java.awt.GridBagConstraints.NORTH;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class JFrameTest extends JFrame {

    public JFrameTest() {
        setSize(500, 500);
        setTitle("Hello :D");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(true);
    }

    public static class JPanelTest extends JPanel {

        public JPanelTest() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.ipadx = 100;
            gbc.ipady = 0;
            gbc.anchor = GridBagConstraints.WEST;
            gbc.weightx = 1.0;
            gbc.weighty = 1.0;
            setBackground(BLACK);
            setOpaque(true);
            add(new JButton("Hello"), gbc);
        }
    }

    public static class JButtonTest extends JButton {

        JButtonTest() {
        }
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                JFrameTest T = new JFrameTest();
                JPanelTest Jp1 = new JPanelTest();
                T.add(Jp1);
            }
        });
    }
}

This code works fine, but I don't like how my Button is just placed exactly to the LEFT, with only the ability to change the size (width, height) of the bButton. So I was wondering if there was a more precise way to place things, like maybe just telling Java to place it on the Panel using X Y coordinates or something, like;

JButton.setLocation(200,200);

Any suggestions?

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
Codster
  • 25
  • 6
  • 1
    *"I was wondering if there was a more precise way to place things"* Not that works across platforms and PLAFs. Use layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). – Andrew Thompson Mar 27 '16 at 00:56
  • So like, but padding out and bordering the component, I can force it into a certain place? Will that effect any other component i wanna add? Or will I get to do that with any component? – Codster Mar 27 '16 at 01:03
  • *"I can force it into a certain place?"* What happened when you *tried it?* – Andrew Thompson Mar 27 '16 at 01:10
  • I'm not sure I understand how Padding and Bordering would place my JButton at a certain point on the Panel. Am I putting the borders and padding on the Panel, or the Button? – Codster Mar 27 '16 at 01:22
  • *"Am I putting the borders and padding on the Panel, or the Button?"* Ah, good question. For a border - normally I'd say "The component you want to nudge", but in this case, that is the button. Since buttons already have there own borders (which might change on focus, press etc.), it is necessary to add the button to a panel, set the border to the panel, then add that panel to the main panel with grid bag layout. For layout padding it is simpler to do. For GBL, see [`GridBagConstraints.insets`](http://docs.oracle.com/javase/8/docs/api/java/awt/GridBagConstraints.html#insets). – Andrew Thompson Mar 27 '16 at 01:30
  • ..look through the other answers of that link in my first comment. They have a number of self contained examples of adding layout padding. – Andrew Thompson Mar 27 '16 at 01:33
  • So I found that GBC actually has more values than just the ones I toss in, they're all just set to defaults. Could I maybe get the effect I want playing with those for a bit? – Codster Mar 27 '16 at 02:20
  • *"like maybe just telling Java to place it on the Panel using X Y coordinates or something, like"* - There's a really good reason why this is generally discouraged, mostly because there are a lot of considerations that need to be taken into account when determining the size of component – MadProgrammer Mar 27 '16 at 04:06

2 Answers2

3

So I was wondering if there was a more precise way to place things, like maybe just telling Java to place it on the Panel using X Y coordinates or something, like;

You might not appreciate it, but the layout managers are very powerful and very good at their jobs, which mostly reduces your work load and makes your live much, much easier

GridBagConstraints#insets

So all I really did was change the anchor constraint to GridBagConstraints.NORTHWEST and added gbc.insets = new Insets(200, 200, 0, 0);

Example

The red is coming from the custom glassPane which is painting a dot which is centered at 200x200, but because the JButton doesn't fill its entire area, so I added a ComponentListener to it and it printed out the location when the componentMoved event occurred, which printed out 200x20

import java.awt.Color;
import static java.awt.Color.BLACK;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JPanel;

public class JFrameTest extends JFrame {

    public JFrameTest() {
        setSize(500, 500);
        setTitle("Hello :D");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setResizable(false);
        JPanel pane = new JPanel() {
            @Override
            public boolean isOpaque() {
                return false;
            }

            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setColor(Color.RED);
                g2d.fillOval(195, 195, 10, 10);
                g2d.dispose();
            }

        };
        setGlassPane(pane);
        pane.setVisible(true);
        setVisible(true);
    }

    public static class JPanelTest extends JPanel {

        public JPanelTest() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.ipadx = 100;
            gbc.ipady = 0;
            gbc.anchor = GridBagConstraints.NORTHWEST;
            gbc.insets = new Insets(200, 200, 0, 0);
            gbc.weightx = 1.0;
            gbc.weighty = 1.0;
            setBackground(BLACK);
            setOpaque(true);
            JButton btn = new JButton("Hello");
            btn.addComponentListener(new ComponentAdapter() {
                @Override
                public void componentMoved(ComponentEvent e) {
                    System.out.println(btn.getLocation());
                }
            });
            add(btn, gbc);
        }
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                JFrameTest T = new JFrameTest();
                JPanelTest Jp1 = new JPanelTest();
                T.add(Jp1);
            }
        });
    }
}
Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
-2
import javax.swing.*;
import java.awt.*;


public class JFrameTest extends JFrame{

   JPanel pnl = new JPanel();

 public static void main(String[] args){
      SwingUtilities.invokeLater(new Runnable(){
        public void run(){                  
             JFrameTest myFrame = new JFrameTest();
                   myFrame.setTitle("Hello :D");                 
                   myFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
                   myFrame.pack();
                   myFrame.setLocationRelativeTo(null);
                   myFrame.setResizable(false);
                   myFrame.setVisible(true);
                }});
           }

public JFrameTest(){

MyCustomLayout customLayout = new MyCustomLayout();
Container c = getContentPane();
          c.setLayout(customLayout);
          pnl.setBackground(Color.BLACK);
          c.add(pnl);
          c.add(new JButton("Hello"));
}

}

class MyCustomLayout implements LayoutManager {

public MyCustomLayout() {}
public void addLayoutComponent(String name, Component comp) {}
public void removeLayoutComponent(Component comp) {}

public Dimension preferredLayoutSize(Container parent) {

    Dimension dim = new Dimension(0, 0);

    Insets insets = parent.getInsets();                
    dim.width = 500;
    dim.height = 500;
    return dim;

}

   public Dimension minimumLayoutSize(Container parent) {
    Dimension dim = new Dimension(0, 0);
    return dim;
}

   public void layoutContainer(Container parent) {

    Insets insets = parent.getInsets();
    Component c;

      c = parent.getComponent(0);
    if (c.isVisible())
       {c.setBounds(insets.left+1,insets.top+8,930,720);}
      c = parent.getComponent(1);
    if (c.isVisible())
       {c.setBounds(insets.left+250,insets.top+250,80,25);} 
//Here just set left value and top value for xy positions
         }
}
Dogrock
  • 1
  • 2
  • 1
    (1-) this is not how to write a layout manager. You don't hard code the location of components. That defaults the purpose of using a layout manager. – camickr Mar 27 '16 at 02:53
  • My code works fine and does what is asking. This is one way I do it. – Dogrock Mar 27 '16 at 04:10
  • 2
    Just because something works does not mean it should be recommended or used. There is much more to layout management then positioning a button randomly on a form. Typically you might want to "center" the button horizontally/vertically or both. The JDK layout managers handle this without hard coding numbers. Maybe you need to add a `Border` to get more a different location. What if the text on the button changes. A layout manager handles this automatically There are so many reason this approach should be avoided. – camickr Mar 27 '16 at 04:48
  • Well that's the beauty of programming everybody got their ways. I like to customize my own layouts and I choose use fixed locations for my components if it's a fixed form. In some situations I won't use it but in some I do. My choice. – Dogrock Mar 27 '16 at 14:20
  • Most code written will ultimately need maintenance done on it by someone other than the person who wrote the code. So you should always write code to be maintainable. Your approach is not maintainable and should not be promoted. What you do at home is up to you but answers on the forum should be about promoting best practices. – camickr Mar 27 '16 at 17:42
  • *"Well that's the beauty of programming everybody got their ways"* - Not when you're working in a company/team, this would fail our review process – MadProgrammer Mar 27 '16 at 20:53
  • Cool... thanks for advice MadP and camickr. Ill keep that in mind. As ya can see im a newbie. – Dogrock Mar 28 '16 at 01:51