Search code examples
javaswinglayoutnull-layout-manager

How to move button to exact location?


I want the buttons and textfield to go in the spaces marked red in the same layout as they are in. look at the picture to understand what I mean.

update: the buttons are in the place now, but the image wont appear on the second panel

enter image description here

how can I move them to there? heres my code so far

package gasindicator;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.basic.*;
import java.io.*;
import javax.imageio.*;
import java.net.*;

public class GasIndicator extends JPanel
 {
private Image image;


GasIndicator()
{
    try
    {
        image = ImageIO.read(new URL("http://i68.tinypic.com/2ceja8i.png"));

    }
    catch (IOException ioe)
    {
        System.out.println("Unable to fetch image.");
        ioe.printStackTrace();
    }

    setLayout( new BorderLayout() );

    JLabel background = new JLabel( new ImageIcon(image) );
    background.setLayout( new FlowLayout(FlowLayout.LEFT) );
    add( background );

    JPanel buttonPanel = new JPanel( new GridLayout(0, 3, 6, 5) );
    buttonPanel.setBorder( new EmptyBorder(338, 233, 0, 0) );

    buttonPanel.setOpaque( false );


    //for (int i = 0; i < 7; i++)
    {
        JButton button = new JButton("Button");
        JButton button1 = new JButton("Button");
        JButton button2 = new JButton("Button");
        JButton button3 = new JButton("Button");
        JButton button4 = new JButton("Button");
        JButton button5 = new JButton("Button");

        button.setPreferredSize( new Dimension(160, 45) );
        buttonPanel.add(button);
        buttonPanel.add(button1);
        buttonPanel.add(button2);
        buttonPanel.add(button3);
        buttonPanel.add(button4);
        buttonPanel.add(button5);

         button.addActionListener(new Action());
    }

    background.add( buttonPanel );
}

static class Action implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            JFrame frame2 = new JFrame("Museums in London");
            frame2.setVisible(true);
            frame2.setSize(550, 650);
            JPanel panel = new JPanel();
            frame2.add(panel);
            Custom contentPane;

            // JFrame frame = new JFrame("JTextField");
            contentPane = new Custom();
            frame2.setContentPane(contentPane);

        }
    }

private static void ShowGUI()
{
    JFrame frame = new JFrame("SSCCE");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(new GasIndicator());
    frame.pack();
    frame.setLocationByPlatform( true );
    frame.setVisible( true );
}

public static void main(String[] args)
{
    EventQueue.invokeLater( () -> ShowGUI() );
/*
    EventQueue.invokeLater(new Runnable()
    {
        public void run()
        {
            createAndShowGUI();
        }
    });
*/
}

class Custom extends JPanel {

public BufferedImage image;

public Custom() {
    try {

        image = ImageIO.read(new URL 
("http://www.destination360.com/europe/uk/images/s/museums.jpg"));
    } catch (IOException ioe) {
        System.out.println("Unable to fetch image.");
        ioe.printStackTrace();
    }
}

public Dimension getPreferredSize() {
    return (new Dimension(image.getWidth(), image.getHeight()));
}

public void paintComponent(Graphics x) {
    super.paintComponent(x);
    x.drawImage(image, 10, 10, this);
}
  }
}

Solution

  • Simple example to demonstrate the concept of using a layout manager with a Border. The size of the buttons has also been tweaked to the size of the buttons in the image:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.plaf.basic.*;
    import java.io.*;
    import javax.imageio.*;
    import java.net.*;
    
    public class SSCCE extends JPanel
    {
        private Image image;
    
        SSCCE()
        {
            try
            {
                image = ImageIO.read(new URL("http://i68.tinypic.com/2ceja8i.png"));
    
            }
            catch (IOException ioe)
            {
                System.out.println("Unable to fetch image.");
                ioe.printStackTrace();
            }
    
            setLayout( new BorderLayout() );
    
            JLabel background = new JLabel( new ImageIcon(image) );
            background.setLayout( new FlowLayout(FlowLayout.LEFT) );
            add( background );
    
            JPanel buttonPanel = new JPanel( new GridLayout(0, 3, 6, 5) );
            buttonPanel.setBorder( new EmptyBorder(338, 233, 0, 0) );
    
            buttonPanel.setOpaque( false );
    
            for (int i = 0; i < 6; i++)
            {
                JButton button = new JButton("Button " + i);
                button.setPreferredSize( new Dimension(160, 45) );
                buttonPanel.add(button);
            }
    
            background.add( buttonPanel );
        }
    
        private static void createAndShowGUI()
        {
            JFrame frame = new JFrame("SSCCE");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new SSCCE());
            frame.pack();
            frame.setLocationByPlatform( true );
            frame.setVisible( true );
        }
    
        public static void main(String[] args)
        {
            EventQueue.invokeLater( () -> createAndShowGUI() );
    /*
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    createAndShowGUI();
                }
            });
    */
        }
    }
    

    Yes, there is still some tweaking of the values. But it is easier to adjust the location of the entire panel with one EmptyBorder and all the buttons move at the same time than it is to adjust the location of each button individually.

    Note: Don't use the JLabel to display the image as the components will shift if the frame is resized. Instead use your custom panel to paint the image.