Trying to put buttons on the bottom of the screen - java

So after a day of studying layout managers and reading some swing refrences, this is what i come up with...
import java.awt.*;
import javax.swing.*;
public class Flags {
public static void startup() {
GridLayout Layout = new GridLayout(6,4);
JFrame menu = new JFrame("Flag Menu");
menu.setResizable(false);
menu.setSize(600,400);
JButton tailand = new JButton("Tailand");
JButton norway = new JButton("Norway");
JPanel panel = new JPanel();
panel.setLayout(Layout);
panel.add(norway);
panel.add(tailand);
menu.add(panel);
panel.setBackground(Color.LIGHT_GRAY);
tailand.setBackground(Color.WHITE);
norway.setBackground(Color.WHITE);
menu.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
menu.setLocationRelativeTo(null);
;
menu.setVisible(true);
}
}
The problem is that i want my buttons to start at the bottom left and be equally spaced between the 4 other buttons i want to make.

There's a number of ways you "might" achieve this and the solution will ultimately depend on what you are trying to achieve.
Personally, I'd start with GridBagLayout - while not the friendliness of layout managers, it is by far the most flexible.
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Flags {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Flags().startup();
}
});
}
public static void startup() {
GridLayout Layout = new GridLayout(6, 4);
JFrame menu = new JFrame("Flag Menu");
// menu.setResizable(false);
// menu.setSize(600, 400);
menu.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton tailand = new JButton("Tailand");
JButton norway = new JButton("Norway");
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weighty = 1;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.anchor = GridBagConstraints.SOUTH;
panel.add(norway, gbc);
gbc.weighty = 0;
panel.add(tailand, gbc);
menu.add(panel);
panel.setBackground(Color.LIGHT_GRAY);
tailand.setBackground(Color.WHITE);
norway.setBackground(Color.WHITE);
menu.pack();
menu.setLocationRelativeTo(null);
menu.setVisible(true);
}
}
Another choice might be to use compound layouts, so that the "button" panel is placed at the SOUTH position of a BorderLayout and the "content" placed in the CENTER

Related

unable to add buttons vertically

I am writing a program where JButtons are added dynamically to a JPanel in a vertical fashion. (the buttons are stored in an arraylist)I have tried the following code by setting the JPanel to gridbaglayout.
for(int i = 0; i<listOfButtons.size();i++) {
c.gridx=0;
c.gridy=i;
leftButtonPanel.add(listOfButtons.get(i));
}
the result is the following
and after adding the buttons
I have also tried setting the JPanel to a gridlayout
leftButtonPanel.setLayout(new GridLayout(listOfButtons.size(),1));
for(int i = 0; i<listOfButtons.size();i++) {
leftButtonPanel.add(listOfButtons.get(i));
}
The buttons "see all" and "add" are all in the same listOfButtons arraylist. and the only way to add buttons into the panel is through that forloop. for some reasons the buttons still start off horizontally.
For GridBagLayout, don't forget, you need to supply the GridBagConstraints as well, otherwise it act a lot like a FlowLayout
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SoTest {
public static void main(String[] args) {
new SoTest();
}
public SoTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
List<JButton> listOfButtons = new ArrayList<>(5);
for (int i = 0; i < 10; i++) {
listOfButtons.add(new JButton(Integer.toString(i)));
}
for (int i = 0; i < listOfButtons.size(); i++) {
add(listOfButtons.get(i), gbc);
}
}
}
}
At this point, I'm curious as to if you should be considering a JList instead

GridBagLayout with glue : no fixed row height

I would like to create a panel, to which I can dynamically add sub-panels with fixed height. I tried using a glue component, but it does not work. I would like to achieve that the sub-panels are visible at the top of the gridbaglayout. Side problem is that when I keep adding sub-panels, they start to overlap because the JScrollPane isn't adjusting. However, when I resize the frame, both problems are solved.
At this moment I don't see where I went wrong. Why does the glue component not take up the vertical space to push the side panels to the top?
This is my SSCCE code:
import javax.swing.*;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import jrdb.data.ProcessingCommand;
public class ProcessingPipelineBuilderSSCCE extends JFrame {
/**
*
*/
private static final long serialVersionUID = 2413084448601918744L;
private JPanel interiorPanel = null;
private GridBagConstraints gbc = null;
private Component glue = null;
public ProcessingPipelineBuilderSSCCE() {
super("SSCCE");
this.getContentPane().setLayout(new BorderLayout());
gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 0, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.anchor = GridBagConstraints.PAGE_START;
JPanel pipelineBuilder = new JPanel();
pipelineBuilder.setLayout(new GridLayout(0, 1, 0, 0));
interiorPanel = new JPanel(new GridBagLayout());
interiorPanel.setBorder(BorderFactory.createLineBorder(Color.red));
JScrollPane scrollPane = new JScrollPane(interiorPanel);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setPreferredSize(new Dimension(500,300));
pipelineBuilder.add(scrollPane);
JButton btnNew = new JButton("Add new panel");
btnNew.setPreferredSize(new Dimension(500, 30));
btnNew.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (glue!=null) {
interiorPanel.remove(glue);
} else {
glue = Box.createGlue();
}
gbc.gridy = gbc.gridy + 1;
interiorPanel.add(new PipelineStep(gbc.gridy),gbc);
interiorPanel.add(glue,gbc);
interiorPanel.validate();
interiorPanel.repaint();
}
});
this.getContentPane().add(btnNew, BorderLayout.PAGE_START);
this.getContentPane().add(pipelineBuilder,BorderLayout.CENTER);
}
public class PipelineStep extends JPanel {
int number;
public PipelineStep (int n) {
super();
JOptionPane.showMessageDialog(interiorPanel, "adding new panel");
this.number = n;
this.setLayout(new FlowLayout());
JLabel lbl = new JLabel(new Integer(this.number).toString());
lbl.setPreferredSize(new Dimension(45,45));
lbl.setFont(lbl.getFont().deriveFont(26));
this.add(lbl);
this.setPreferredSize(new Dimension(450, 50));
this.setBorder(BorderFactory.createLineBorder(Color.green));
}
}
public static void main (String args[]) {
ProcessingPipelineBuilderSSCCE frame = new ProcessingPipelineBuilderSSCCE();
frame.pack();
frame.setVisible(true);
}
}
Why does the glue component not take up the vertical space to push the side panels to the top?
The "glue" component only has meaning when used with the BoxLayout. It has no effect with the GridBagLayout.
So my suggestion is to forget about the GridBagLayout and use the BoxLayout.
The easiest way to do this is to convert "interiorPanel" to use a vertical Box and just add your PipelineStep instances to this panel.
Try this. However, you will notice that the panels will still increase in size until the scroll pane is full, at which time you will see scrollbars appear. This is because the BoxLayout will resize components up to the maximum size of the component. So to prevent this resizing you could override the getMaximumSize() method of your PipelineStep class:
#Override
public Dimension getMaximumSize()
{
return getPreferredSize();
}
Or, another option is to use a "wrapper" panel for your "interiorPanel". Something like:
JPanel wrapper = new JPanel( new BorderLayout() );
wrapper.add(interiorPanel, BorderLayout.PAGE_START);
//JScrollPane scrollPane = new JScrollPane(interiorPanel);
JScrollPane scrollPane = new JScrollPane(wrapper);
BorderLayout.PAGE_START respects the preferred height of the component added to it so the "interiorPanel" will always be displayed at it preferred height and scrollbars will appear when the viewport of the scroll pane is full.
I modified you code using the "wrapper" approach.
import javax.swing.*;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
//import jrdb.data.ProcessingCommand;
public class SSCCE1 extends JFrame {
/**
*
*/
private static final long serialVersionUID = 2413084448601918744L;
// private JPanel interiorPanel = null;
private Box interiorPanel = null;
private GridBagConstraints gbc = null;
private Component glue = null;
public SSCCE1() {
super("SSCCE");
this.getContentPane().setLayout(new BorderLayout());
gbc = new GridBagConstraints();
//gbc.insets = new Insets(5, 5, 0, 5);
//gbc.fill = GridBagConstraints.HORIZONTAL;
//gbc.gridx = 0;
//gbc.gridy = 0;
//gbc.weightx = 1.0;
//gbc.weighty = 1.0;
//gbc.anchor = GridBagConstraints.PAGE_START;
JPanel pipelineBuilder = new JPanel();
pipelineBuilder.setLayout(new GridLayout(0, 1, 0, 0));
// interiorPanel = new JPanel(new GridBagLayout());
interiorPanel = Box.createVerticalBox();
interiorPanel.setBorder(BorderFactory.createLineBorder(Color.red));
JPanel wrapper = new JPanel( new BorderLayout() );
wrapper.add(interiorPanel, BorderLayout.PAGE_START);
// JScrollPane scrollPane = new JScrollPane(interiorPanel);
JScrollPane scrollPane = new JScrollPane(wrapper);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setPreferredSize(new Dimension(500,300));
pipelineBuilder.add(scrollPane);
JButton btnNew = new JButton("Add new panel");
btnNew.setPreferredSize(new Dimension(500, 30));
btnNew.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// if (glue!=null) {
// interiorPanel.remove(glue);
// } else {
// glue = Box.createGlue();
// }
gbc.gridy = gbc.gridy + 1;
// interiorPanel.add(new PipelineStep(gbc.gridy),gbc);
interiorPanel.add(new PipelineStep(gbc.gridy),gbc);
// interiorPanel.add(glue,gbc);
// interiorPanel.validate();
interiorPanel.revalidate();
interiorPanel.repaint();
}
});
this.getContentPane().add(btnNew, BorderLayout.PAGE_START);
this.getContentPane().add(pipelineBuilder,BorderLayout.CENTER);
}
public class PipelineStep extends JPanel {
int number;
public PipelineStep (int n) {
super();
JOptionPane.showMessageDialog(interiorPanel, "adding new panel");
this.number = n;
this.setLayout(new FlowLayout());
JLabel lbl = new JLabel(new Integer(this.number).toString());
lbl.setPreferredSize(new Dimension(45,45));
lbl.setFont(lbl.getFont().deriveFont(26));
this.add(lbl);
this.setPreferredSize(new Dimension(450, 50));
this.setBorder(BorderFactory.createLineBorder(Color.green));
}
}
public static void main (String args[]) {
SSCCE1 frame = new SSCCE1();
frame.pack();
frame.setVisible(true);
}
}

How to change JButton size in JPanel which is "spread" at whole JFrame

So I have a problem,because mine JButtons are just too bige, I need to change their size to be for eg small rectangles or squares. Right now they look like piano keys.
This is my paste.Could you guys help? :)
I tried SetSize or SetDimension or all the methods available but it did not work out. And I haven't found relevant topic here at overflow. What do you think?
package sg;
import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SG extends JFrame {
JPanel pn1;
JPanel pn2;
JPanel pn3;
JPanel pn4;
JButton[] buttony = new JButton[12];
JButton start;
SG() {
super();
setSize(1000, 900);
setResizable(false);
pn1 = new JPanel();
pn2 = new JPanel();
pn1.setLayout(new GridBagLayout());
pn2.setLayout(new GridLayout(2,6));
start = new JButton("Start");
start.addActionListener(new B1());
pn1.add(start);
for (int i = 0; i < 12; i++) {
buttony[i] = new JButton(Integer.toString(i + 1));
buttony[i].setSize(10, 10);
pn2.add(buttony[i]);
}
add(pn1,BorderLayout.NORTH);
add(pn2,BorderLayout.CENTER);
}
public static void main(String[] args) {
SG adam = new SG();
adam.setVisible(true);
}
private class B1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
Random s = new Random();
int a = s.nextInt(5);
System.out.println(a);
}
}
}
Add pn2 to another JPanel and then set that panel to the JFrame using setContentPane.
The complete code is as follows:
import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SG extends JFrame {
JPanel pn1;
JPanel pn2;
JPanel pn3;
JPanel pn4;
JButton[] buttony = new JButton[12];
JButton start;
SG() {
super();
setSize(1000, 900);
setResizable(false);
pn1 = new JPanel();
pn2 = new JPanel();
JPanel contentPane = new JPanel();
pn1.setLayout(new GridBagLayout());
pn2.setLayout(new GridLayout(2, 6));
start = new JButton("Start");
start.addActionListener(new B1());
pn1.add(start);
for (int i = 0; i < 12; i++) {
buttony[i] = new JButton(Integer.toString(i + 1));
buttony[i].setSize(10, 10);
pn2.add(buttony[i]);
}
contentPane.add(pn2);
setContentPane(contentPane);
add(pn1, BorderLayout.NORTH);
add(pn2, BorderLayout.CENTER);
}
public static void main(String[] args) {
SG adam = new SG();
adam.setVisible(true);
}
private class B1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
Random s = new Random();
int a = s.nextInt(5);
System.out.println(a);
}
}
}
If you want to use GridBagLayout, be sure to read this page:
https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
which suggests defining constraints before adding elements.
My choice is MigLayout. Google it and check 5+ versions.
The default size of a component, is barely defined by setSize(), because layout managers often use it to define the dimensions of each components to resize them, so your effort will almost always be overwritten. If you want, try setPreferedSize(), setMinimumSize() and setMaximumSize().
About the topic of Swing, StackOverFlow has plenty of questions related. Try searching tag swing. Also, the Oracle guide is a must-read: https://docs.oracle.com/javase/tutorial/uiswing/TOC.html. And each layout manager has its own documentation. Like Miglayout. http://www.miglayout.com/
Be patient. Several month of time is required to get an rough idea of all this.
GUI components such as JButton need to be placed in a container. JPanel is a container. Containers have an associated layout manager. The layout manager determines the size and location of the components within the container. The GridLayout divides the container into a grid of equal sized cells and places exactly one component in each cell. In the code you posted, each cell contains exactly one JButton, hence each button has the same size. Explicitly setting the JButton size will not help because GridLayout ignores it.
Therefore you need to use a layout manager that is appropriate for your needs. You want to lay out your JButtons in a grid but have each JButton displayed with its preferred size. An appropriate layout manger for this is GridBagLayout. It lays out the components in a grid but sizes each component according to its preferred size.
The following code is a rewrite of the code you posted, because I felt that starting from scratch would be more beneficial to you than patching the code you posted. In the below code, I am using GridBagLayout to lay out the grid of JButtons.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class SG1 implements ActionListener, Runnable {
private static final int NUMBER_OF_BUTTONS = 12;
private static final String START = "Start";
private JButton[] buttons;
private JFrame frame;
private JTextField textField;
public SG1() {
buttons = new JButton[NUMBER_OF_BUTTONS];
}
#Override // java.awt.event.ActionListener
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
switch (actionCommand) {
case START:
Random s = new Random();
int a = s.nextInt(5);
textField.setText(String.valueOf(a));
break;
default:
JOptionPane.showMessageDialog(frame,
actionCommand,
"Unhandled",
JOptionPane.WARNING_MESSAGE);
}
}
#Override // java.lang.Runnable
public void run() {
createAndShowGui();
}
private void createAndShowGui() {
frame = new JFrame("SG1");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createTextFieldPanel(), BorderLayout.PAGE_START);
frame.add(createButtonsPanel(), BorderLayout.CENTER);
frame.add(createStartButtonPanel(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets.top = 3;
gbc.insets.right = 3;
gbc.insets.left = 3;
gbc.insets.bottom = 3;
for (int i = 0; i < NUMBER_OF_BUTTONS; i++) {
buttons[i] = new JButton(String.format("%02d", (i + 1)));
buttonsPanel.add(buttons[i], gbc);
gbc.gridx++;
if (gbc.gridx > (NUMBER_OF_BUTTONS / 2) - 1) {
gbc.gridx = 0;
gbc.gridy++;
}
}
return buttonsPanel;
}
private JPanel createStartButtonPanel() {
JPanel startButtonPanel = new JPanel();
JButton startButton = new JButton(START);
System.out.println(startButton.getFont());
startButton.addActionListener(this);
startButtonPanel.add(startButton);
return startButtonPanel;
}
private JPanel createTextFieldPanel() {
JPanel textFieldPanel = new JPanel();
textField = new JTextField(10);
textFieldPanel.add(textField);
return textFieldPanel;
}
public static void main(String[] args) {
EventQueue.invokeLater(new SG1());
}
}
I suggest you thoroughly study the above code and if there are parts you don't understand, then search the Internet for explanations. You will find many examples for each part of it.
For learning Swing in general, I recommend the online tutorial Creating a GUI With JFC/Swing. I also recommend the book Core JFC (2nd Edition) by Kim Topley

Java: Overlay an Image with Transparent JButton

So I'm creating a GUI that represents a vending machine. I'm just running into some problems trying to get the layout to work the way I want it. My thought was to insert an image into a JLabel, and then overlay that image with transparent JButtons in specific locations so that when you click on the image in certain locations, it will trigger the JButton. I haven't gotten to the transparency yet as I'm currently stuck on how to get the JButtons precisely where they need to be.
I've tried setLocation and setBounds with no luck. Any help on how to exactly position the jbuttons over the possible vending machine choices would be great.
import javax.swing.*;
import javax.imageio.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
public class vendMachine extends JFrame
{
//Frame Dimensions
private static final int FRAME_HEIGHT = 800;
private static final int FRAME_WIDTH = 800;
private JPanel totalGUI, imagePanel, coinPanel;
public vendMachine()
{
createComponents();
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setTitle("Vending Machine");
}
private void createComponents()
{
try
{
BufferedImage machineImg = ImageIO.read(new File("images/pepsivend.jpg"));
JLabel machineImgLabel = new JLabel(new ImageIcon(machineImg));
machineImgLabel.setLayout(new FlowLayout());
JButton test = new JButton("TEST BUTTON");
machineImgLabel.add(test);
//test.setBounds(0,0,0,0);
ImageIcon pennyIcon = new ImageIcon("images/coins/penny.jpg");
JButton pennyButton = new JButton(pennyIcon);
ImageIcon nickelIcon = new ImageIcon("images/coins/nickel.jpg");
JButton nickelButton = new JButton(nickelIcon);
ImageIcon dimeIcon = new ImageIcon("images/coins/dime.jpg");
JButton dimeButton = new JButton(dimeIcon);
ImageIcon quarterIcon = new ImageIcon("images/coins/quarter.jpg");
JButton quarterButton = new JButton(quarterIcon);
coinPanel = new JPanel();
coinPanel.setLayout(new GridLayout(4,1));
coinPanel.add(pennyButton);
coinPanel.add(nickelButton);
coinPanel.add(dimeButton);
coinPanel.add(quarterButton);
totalGUI = new JPanel();
totalGUI.setLayout(new BorderLayout());
totalGUI.add(machineImgLabel, BorderLayout.CENTER);
totalGUI.add(coinPanel, BorderLayout.EAST);
}
catch (IOException e)
{
e.printStackTrace();
}
add(totalGUI);
}
}
In the above Image I would like some help on how to get the test button, to overlay on top of the pepsi selection. From there I can go about making it transparent and removing the borders and text.
Edited to add: none of the buttons do anything yet. Simply trying to get the layout going before adding in anything else
It's unclear as to what your actually problem, however, I'll start with the layout...
No single layout will ever do everything you want, some times, you'll need to use multiple layouts and compound them. This example uses a BorderLayout and a GridBagLayout to set up the basic layout...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new VendingMachinePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class VendingMachinePane extends JPanel {
public VendingMachinePane() {
setLayout(new BorderLayout());
JLabel label = new JLabel("Cover");
// Demonstration purpose only
label.setPreferredSize(new Dimension(200, 400));
label.setOpaque(true);
label.setBackground(Color.BLUE);
add(label);
JPanel optionsPane = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.anchor = GridBagConstraints.NORTH;
optionsPane.setBackground(Color.DARK_GRAY);
optionsPane.add(new JLabel("Coin Slot"), gbc);
optionsPane.add(makeButton("Pepsi"), gbc);
optionsPane.add(makeButton("Diet Pepsi"), gbc);
optionsPane.add(makeButton("Slice"), gbc);
optionsPane.add(makeButton("Dr Pepper"), gbc);
optionsPane.add(makeButton("Lipton"), gbc);
optionsPane.add(makeButton("Mountain Dew"), gbc);
optionsPane.add(makeButton("Schweppes"), gbc);
gbc.weighty = 1;
optionsPane.add(makeButton("Pepsi"), gbc);
add(optionsPane, BorderLayout.LINE_END);
}
protected JButton makeButton(String text) {
JButton btn = new JButton(text);
btn.setBorderPainted(false);
btn.setContentAreaFilled(false);
btn.setMargin(new Insets(4, 4, 4, 4));
btn.setOpaque(false);
return btn;
}
}
}
As to your "overlay buttons" issue, to me, that doesn't make sense, since a JButton has a icon property, why not just use a JButton to start with?
You make buttons transparent simply by changing their borderPainted contentAreaFilled and opaque properties
// You can pass a `Icon` instead of a `String` to the constructor
JButton btn = new JButton(text);
btn.setBorderPainted(false);
btn.setContentAreaFilled(false);
btn.setMargin(new Insets(4, 4, 4, 4));
btn.setOpaque(false);
Don't forget to setup an ActionListener ;)
Updated, based on the updated requirements...
You Could...
Break the image down in segments, making each element it's own image and simply applying those to the buttons, using a similar approach above
You Could...
Map hot spots on the image, and using a MouseListener monitor where the mouseClicked events occur - you do lose the advantage of keyboard input though
You Could...
Map out the hot spots of the image and using a GridBagLayout or custom layout manager, map the buttons onto the image.

Align components on the page top right with GridBagLayout Manager

i am trying to make a login page just like facebook, but the code i have written is not showing it on the top left side instead it is showing at the centre of page, i am using GridBagLayout and anchore for setting text at the FIRST_LINE_END.
final JFrame f2=new JFrame("Admin Main");
f2.setSize(1350,730);
f2.setVisible(true);
f1.setVisible(false);
f2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);![enter image description here][2]
GridBagLayout gbl=new GridBagLayout();
final JPanel p2=new JPanel(gbl){
private Image img = ImageIO.read(new File("F:\\Untitled Folder\\Rohan\\football2.jpg"));
#Override
protected void paintComponent( Graphics g ) {
super.paintComponent(g);
g.drawImage(img, 0,0,1366,730, null);
}
};;
GridBagConstraints g2=new GridBagConstraints();
g2.insets=new Insets(3,3,3,3);
JLabel l2=new JLabel("Admin ID",JLabel.LEFT);
JLabel l3=new JLabel("Password",JLabel.LEFT);
l2.setFont(new Font("TimesRoman",Font.BOLD,16));
l2.setForeground(Color.BLUE);
l2.setBackground(Color.WHITE);
l3.setFont(new Font("TimesRoman",Font.BOLD,16));
l3.setForeground(Color.BLUE);
l3.setBackground(Color.WHITE);
final JTextField t1=new JTextField(15);
final JPasswordField pw1=new JPasswordField(15);
JButton b3=new JButton("Back");
JButton b4=new JButton("Sign in");
f2.add(p2);
g2.anchor=GridBagConstraints.FIRST_LINE_END;
g2.gridx=1;
g2.gridy=1;
p2.add(l2,g2);
g2.gridx=2;
g2.gridy=1;
p2.add(t1,g2);
g2.gridx=1;
g2.gridy=2;
p2.add(l3,g2);
g2.gridx=2;
g2.gridy=2;
p2.add(pw1,g2);
g2.gridx=1;
g2.gridy=3;
p2.add(b3,g2);
g2.gridx=2;
g2.gridy=3;
p2.add(b4,g2);
I see two problems in your current layout:
You put your login panel in the center of the parent BorderLayout (so your panel gets stretched to the size of its container)
You have nothing in your GridBagLayout that will "push" your components to the top and to the left.
There are several options here:
You nest your login panel into several panels (for example using BorderLayout, once with the constraint NORTH and the second time with the constraint WEST).
Add your loginPanel to the WEST and you add a "filler" component to the bottom of the GridBagLayout in order to push the other components to the top.
Here is a demo of the second solution:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class TestLoginGridBagLayout {
protected void initUI() throws MalformedURLException {
JFrame frame = new JFrame("Admin Main");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel background = new JLabel(new ImageIcon(new URL(
"http://media1.santabanta.com/full1/Football/Football%20Abstract/football-abstract-6a.jpg"))) {
#Override
public Dimension getPreferredSize() {
Dimension preferredSize = super.getPreferredSize();
Dimension layoutPreferredSize = super.preferredSize();
preferredSize.width = Math.max(preferredSize.width, layoutPreferredSize.width);
preferredSize.height = Math.max(preferredSize.height, layoutPreferredSize.height);
return preferredSize;
}
};
background.setLayout(new BorderLayout());
frame.add(background);
GridBagLayout gbl = new GridBagLayout();
final JPanel loginPanel = new JPanel(gbl);
loginPanel.setOpaque(false);
background.add(loginPanel, BorderLayout.WEST);
JLabel adminIDLabel = new JLabel("Admin ID", JLabel.LEFT);
JLabel passwordLabel = new JLabel("Password", JLabel.LEFT);
adminIDLabel.setFont(new Font("TimesRoman", Font.BOLD, 16));
adminIDLabel.setForeground(Color.BLUE);
adminIDLabel.setBackground(Color.WHITE);
passwordLabel.setFont(new Font("TimesRoman", Font.BOLD, 16));
passwordLabel.setForeground(Color.BLUE);
passwordLabel.setBackground(Color.WHITE);
final JTextField adminID = new JTextField(15);
final JPasswordField password = new JPasswordField(15);
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
buttonPanel.setOpaque(false);
JButton back = new JButton("Back");
JButton signIn = new JButton("Sign in");
buttonPanel.add(back);
buttonPanel.add(signIn);
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(3, 3, 3, 3);
gbc.anchor = GridBagConstraints.FIRST_LINE_END;
loginPanel.add(adminIDLabel, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
loginPanel.add(adminID, gbc);
gbc.gridwidth = 1;
loginPanel.add(passwordLabel, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
loginPanel.add(password, gbc);
loginPanel.add(buttonPanel, gbc);
GridBagConstraints gbcFiller = new GridBagConstraints();
gbcFiller.weightx = 1.0;
gbcFiller.weighty = 1.0;
gbcFiller.fill = GridBagConstraints.BOTH;
loginPanel.add(Box.createGlue(), gbcFiller);
frame.pack();
frame.setVisible(true);
}
/**
* #param args
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
new TestLoginGridBagLayout().initUI();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
});
}
}
I also took the liberty of:
Rename your variables to meaningful names (it makes your code easier to read for others)
Replace your custom background image panel with a JLabel
Move your buttons to a nested panel with another LayoutManager
Take another background image since I don't have yours.
If you want it explicitly to be in the top left I'd rather use the NORTHWEST anchor. FIRST_LINE_END for text flowing left to right would also put the text on the right corner and the other way around for right to left.
Also, switch gridx and gridy to start at 0 instead of 1. And increment from as needed from there.
So for example:
g2.anchor=GridBagConstraints.NORTHWEST;
g2.gridx=0;
g2.gridy=0;
p2.add(l2,g2);
g2.gridx=1;
g2.gridy=0;
p2.add(t1,g2);
/*And so on for the rest of the block*/
Use FIRST_LINE_START as anchor value.
g2.anchor=GridBagConstraints.FIRST_LINE_START;

Categories

Resources