GridBagLayout components in wrong position - java

My code is meant to but the JButton at the top but when I add a image it goes on top of the image which is good but instead of being at the top it is in the middle and you can't get a value for gridy so I don't know how to make it go to the top. I have got lots of buttons on the Container but I will just put the code for one to make it shorter but if you need full code I will provide it. Thank you Here is my code
public void add(Container pane){
setBackground(Color.black);
pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
URL resource = getClass().getResource("Graphitebackground.v2.jpg");
ImageIcon i2 = new ImageIcon(resource);
URL resource3 = getClass().getResource("Graphitebackground.v4.jpg");
ImageIcon i3 = new ImageIcon(resource3);
URL resource1 = getClass().getResource("Graphitebackground.v3.jpg");
ImageIcon i1 = new ImageIcon(resource1);
JLabel background = new JLabel(i2);
background.setSize(new Dimension(1000,1000));
background.setVisible(true);
background.setLayout(new GridBagLayout());
JButton button;
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//natural height, maximum width
c.fill = GridBagConstraints.HORIZONTAL;
JButton label2 = new JButton(i1);
c.weightx = 0.5;
label2.setText("Level1");
label2.setPreferredSize(new Dimension(100,100));
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
label2.setForeground(Color.RED);
label2.setFont(new Font("Arial", Font.BOLD,100));
label2.setHorizontalTextPosition(JButton.CENTER);
label2.setVerticalTextPosition(JButton.CENTER);
label2.setBorderPainted(false);
label2.addMouseListener(new java.awt.event.MouseAdapter(){
public void mouseEntered(java.awt.event.MouseEvent evt){
label2.setBorderPainted(true);
label2.setBorder(BorderFactory.createLineBorder(Color.red,3));
}
public void mouseExited(java.awt.event.MouseEvent evt){
label2.setBorderPainted(false);
}
});
background.add(label2,c);
pane.add(background);
}

Related

How to create an ImageIcon with the exact dimensions of a GridBagLayout cell

For a simple GUI I am currently making I want a design similar to this.
The blue and the green area are supposed to be just text and numbers.
The red area is supposed to be an image. Currently, I am creating scaled instances of an Image, create an ImageIcon out of this and then add this to a label to fit an image into different spaces.
The problem is, that without a width I can not create a scaled instance of the picture.
My current GridBagLayout code looks like this:
private static void createAndShowUI()
{
JFrame frame = new JFrame();
JLabel map = new javax.swing.JLabel();
JLabel data = new javax.swing.JLabel();
JLabel menu = new javax.swing.JLabel();
GridBagConstraints c;
frame = new JFrame("Risiko");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.getContentPane().setLayout(new GridBagLayout());
map.setText("MAP");
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.weightx = 0.75;
c.weighty = 0.75;
frame.getContentPane().add(map, c);
data.setText("DATA");
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 1;
c.weighty = 0.25;
frame.getContentPane().add(data, c);
menu.setText("MENU");
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 0;
c.gridheight = 2;
c.weightx = 0.25;
frame.getContentPane().add(menu, c);
frame.setVisible(true);
}
I create the three areas and now I want to create an image with the exact width and height of the red area.
So my question is, how can I get the width and height of the red area so I can create a scaled instance of the picture so that it fits into this area?
Test the dynamic layout of the following mre by resizing the frame.
The background image used as background for MapPane is resized to fill the JPanels width and height.
This is achieved by overriding paintComponent:
import java.awt.*;
import java.awt.image.*;
import java.net.URL;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class SwingTestPane extends JPanel {
public SwingTestPane() {
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.rowWeights = new double[]{0.75, .25};
gridBagLayout.columnWeights = new double[]{0.75, 0.25};
setLayout(gridBagLayout);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 0;
JPanel mapPane = new MapPane();
add(mapPane, c);
c.gridx = 0;
c.gridy = 1;
JLabel data = new javax.swing.JLabel("DATA");
JPanel dataPane = new JPanel();
dataPane.add(data);
dataPane.setBackground(Color.YELLOW);
dataPane.setOpaque(true);
add(dataPane, c);
c.gridx = 1;
c.gridy = 0;
c.gridheight = 2;
JLabel menu = new JLabel("MENU");
JPanel menuPane = new JPanel();
menuPane.add(menu);
menuPane.setBackground(Color.GREEN);
menuPane.setOpaque(true);
add(menuPane, c);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400,400);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.getContentPane().add(new SwingTestPane());
frame.pack();
frame.setVisible(true);
}
}
class MapPane extends JPanel {
String imageUrlString = "https://findicons.com/files/icons/345/summer/128/cake.png";
BufferedImage image = null;
MapPane() {
URL url;
try {
url = new URL(imageUrlString);
image = ImageIO.read(url);
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override //Override to paint image as the background
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
}
}

GridBagLayout formatting for JButtons

My partner and I are writing this program for a game. He used GridBagLayout for our grid and I'm trying to troubleshoot some problems with the grid.
Here's the code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
#SuppressWarnings("serial")
public class NewGame extends JFrame{
private int width = 500, height = 500, xSquares = 4, ySquares = 4;
Font buttonFont = new Font("Times New Roman", Font.PLAIN, 15);
endGame end = new endGame();
public NewGame() {
super("OnO");
// gridbaglayout is flexible but kinda complicated
GridBagLayout Griddy = new GridBagLayout();
this.setLayout(Griddy);
JPanel p = new JPanel();
p.setLayout(Griddy);
this.add(p);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 4;
c.gridheight = 4;
NewBoard board = new NewBoard(xSquares, ySquares);
// board at top left
c.gridx = 0;
c.gridy = 0;
this.add(board, c);
// find a way to make buttons smaller
JButton EndGame = new JButton("End");
EndGame.setBackground(Color.black);
EndGame.setForeground(Color.white);
EndGame.setFont(buttonFont);
EndGame.addActionListener(end);
JButton Undo = new JButton("Undo");
Undo.setBackground(Color.black);
Undo.setForeground(Color.white);
Undo.setFont(buttonFont);
JButton NewGame = new JButton("New Game");
NewGame.setBackground(Color.black);
NewGame.setForeground(Color.white);
NewGame.setFont(buttonFont);
// fit 3
c.gridwidth = 1;
c.gridheight = 1;
c.gridy = 3;
c.fill = GridBagConstraints.HORIZONTAL;
p.add(EndGame, c);
c.gridx = 2;
c.fill = GridBagConstraints.HORIZONTAL;
p.add(Undo, c);
c.gridx = 3;
c.fill = GridBagConstraints.HORIZONTAL;
p.add(NewGame, c);
this.setPreferredSize(new Dimension(width, height));
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.pack();
this.setLocation(450, 30);
this.setVisible(true);
}
public class endGame implements ActionListener {
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
}
public class newGame implements ActionListener {
public void actionPerformed(ActionEvent event) {
}
}
}
When this code is run with the other classes in our program, the endGame, Undo, and NewGame buttons overlap with the board:
I want to find a way to display the 3 buttons either above or below the board in its individual space, but I've tinkered with the code for a long time and can't find the solution yet. I'm not sure what I should be doing here.
First of all, variable names should NOT start with an upper case character. Learn and follow Java naming conventions.
I want to find a way to display the 3 buttons either above or below the board
Simplest solution is to not use a GridBagLayout for the frame.
Just use the default BorderLayout of the frame. Then you can use a JPanel with the FlowLayout for your buttons, and a GridLayout for your board panel.
The basic logic would be:
JPanel buttons = new JPanel();
buttons.add(endGame);
buttons.add(undo);
buttons.add(newGame);
this.add(button, BorderLayout.PAGE_START);
NewBoard board = new NewBoard(xSquares, ySquares);
this.add(board, BorderLayout.CENTER);
By default a JPanel uses a FlowLayout so the buttons will be displayed on a single row.
Read the Swing tutorial on Layout Managers for more information and working examples to better understand how this suggestion works.

how to put components in the center in a CardLayout panel

I have a frame that has couple of panels and they change by CardLayout.
Inside each panel i will have different components. To design the GUI of the panel I used GridBagLayout. But the problem is any component or Layout I use for these paneles, they all stay at the top of the page. So basically the panel size of the CardLayout is some small amount of the frame. I want to make the sub panel size as large as the main CardLayout size.
Code for main CardLayout:
public class MainPanel extends JPanel {
private CardLayout cl = new CardLayout();
private JPanel panelHolder = new JPanel(cl);
public MainPanel() {
NewSession session = new NewSession(this);
ChooseSource chooseSource = new ChooseSource(this);
panelHolder.add(session, "1");
panelHolder.add(chooseSource, "2");
cl.show(panelHolder, "dan");
add(panelHolder);
}
public void showPanel(String panelIdentifier){
cl.show(panelHolder, panelIdentifier);
}
}
A sub panel:
public class ChooseSource extends JPanel {
MainPanel ob2;
JButton btn;
JLabel label;
JTextField field;
public ChooseSource(MainPanel mainPanel){
this.ob2 = mainPanel;
btn = new JButton("Browse");
label = new JLabel("Folder ");
field = new JTextField();
btn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
ob2.showPanel("1");
}
});
GridBagLayout layout = new GridBagLayout();
setLayout(layout);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
c.ipady = 20;
c.gridheight = 2;
add(btn, c);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
c.gridy = 0;
c.ipady = 10;
c.gridheight = 1;
c.insets = new Insets(0,10,0,0);
add(label, c);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
c.gridy = 1;
c.ipady = 0;
c.gridheight = 1;
c.insets = new Insets(0,10,0,0);
add(field, c);
}
}
The left image shows how it is not, and right one is the one I am trying to make. basically I want to have access to all the available space of the panel.
Any idea?
Change the layout manager of MainPanel to something like BorderLayout or GridBagLayout

GridBagLayout alignment and Button style

I am trying to align a button using the GridBagLayout but it look I just can't achieve that. Also I want to remove the JButton's texture from my custom button, but I can not.. This is what it looks like:
I want the buttons to be at the top( but using GridBagLayout) and also on the left and right margin of the green button there is the remains of the JButton style and I can't remove it completely.
Also, this is my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TestPanel{
public TestPanel(){
JFrame frame = new JFrame();
frame.add(new Panel1());
frame.setVisible(true);
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestPanel();
}
public class Panel1 extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
public Panel1(){
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
ImageIcon im = new ImageIcon("Start.png");
ImageIcon i = new ImageIcon("Start-Pressed.png");
JButton button = new JButton(im);
JButton but = new JButton("BUT");
button.setRolloverEnabled(true);
Insets margin = new Insets(-15,-10,-10,-10);
button.setBorderPainted(false);
button.setMargin(margin);
button.setRolloverIcon(i);
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx=0.5;
c.gridx=0;
c.gridy=0;
add(button, c);
c.gridx=2;
c.gridy=1;
add(but,c);
}
}
}
Edit:
c.gridy++;
c.fill = GridBagConstraints.VERTICAL;
c.weighty = 1;
c.add(new JLabel(" "),c);
c.gridy++;
c.weighty = 1;
c.fill = GridBagConstraints.NONE;
add(eButton, c);
You can achive it with help of dummy JLabel at bottom, like next(add to the end of constructor):
c.gridy++;
c.fill = GridBagConstraints.VERTICAL;
c.weighty = 1;
add(new JLabel(" "), c);
To remove margin you can try setContentAreaFilled() method
Instead of ImageIcon im = new ImageIcon("Start.png"); use ImageIcon im = new ImageIcon(Panel1.class.getResource("Start.png"));
Also see that answer.

Is it possible to make the elements inside a JPanel with GridBagLayout to start from the top left?

I have a Swing Form that contains a JScrollPane(activityScrollPane) for a JPanel(activityPanel). The panel contains a JTextField and a JButton (that is used to add more fields to the Panel). Now the problem is that the elements start from the center of the panel as in the image below (with the borders marking the activityScrollPane boundary)
Following is the code I am currently using to make the scroll pane and associated components.
//part of the code for creating the ScrollPane
final JPanel activityPanel = new JPanel(new GridBagLayout());
gbc.gridx=0;
gbc.gridy=0;
JScrollPane activityScrollPane = new JScrollPane(activityPanel);
//adding activity fields
activityFields = new ArrayList<JTextField>();
fieldIndex = 0;
activityFields.add(new JTextField(30));
final GridBagConstraints activityGBC = new GridBagConstraints();
activityGBC.gridx=0;
activityGBC.gridy=0;
activityGBC.anchor = GridBagConstraints.FIRST_LINE_START;
activityPanel.add(activityFields.get(fieldIndex),activityGBC);
fieldIndex++;
JButton btn_more = (new JButton("more"));
activityGBC.gridx=1;
activityPanel.add(btn_more,activityGBC);
How can I make the JTextField and the JButton or for that matter any component to appear on the top left corner of the JScrollPane. I have already tried using
activityConstraints.anchor = GridBagConstraints.NORTHWEST;
as pointed in the SO post, but it does not at all seem to work.
You simply forgot to provide any weightx/weighty values, atleast one having a non-zero value will do. have a look at this code example :
import java.awt.*;
import javax.swing.*;
public class GridBagLayoutDemo
{
private JTextField tfield1;
private JButton button1;
private void displayGUI()
{
JFrame frame = new JFrame("GridBagLayout Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new GridBagLayout());
tfield1 = new JTextField(10);
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
contentPane.add(tfield1, gbc);
button1 = new JButton("More");
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.NONE;
contentPane.add(button1, gbc);
frame.setContentPane(contentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new GridBagLayoutDemo().displayGUI();
}
});
}
}
Latest EDIT : No spacing along Y-Axis
import java.awt.*;
import javax.swing.*;
public class GridBagLayoutDemo
{
private JTextField tfield1;
private JButton button1;
private JTextField tfield2;
private JButton button2;
private void displayGUI()
{
JFrame frame = new JFrame("GridBagLayout Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new GridBagLayout());
tfield1 = new JTextField(10);
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.weightx = 1.0;
//gbc.weighty = 0.2;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
contentPane.add(tfield1, gbc);
button1 = new JButton("More");
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.NONE;
contentPane.add(button1, gbc);
tfield2 = new JTextField(10);
gbc.weightx = 1.0;
gbc.weighty = 0.2;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
contentPane.add(tfield2, gbc);
button2 = new JButton("More");
gbc.gridx = 1;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.NONE;
contentPane.add(button2, gbc);
JScrollPane scroller = new JScrollPane(contentPane);
frame.add(scroller);
frame.pack();
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new GridBagLayoutDemo().displayGUI();
}
});
}
}
Sorry as my answer me be on the off-side of what you have asked, but why dont you use GroupLayout instead of GridBag Layout, thats much more easier to handle
try it with BorderLayout: controls.setLayout(new BorderLayout()); and then apply it for your JPanel controls.add(yourPanel, BorderLayout.PAGE_START);
I also have problems with GridBagLayout so i solved it with BorderLayout and it works so fine.
So i wrote for your little example:
private void initComponents() {
controls = new Container();
controls = getContentPane();
controls.setLayout(new BorderLayout());
panel = new JPanel();
panel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
field = new JTextField(20);
c.gridx = 0;
c.gridy = 0;
panel.add(field, c);
one = new JButton("Go!");
c.gridx = 1;
c.gridy = 0;
panel.add(one, c);
controls.add(panel, BorderLayout.PAGE_START);
}
Hope it helps!
I think this could be simple and possible, you can
put Nested JPanel to the JScrollPane
to this JPanel
put JPanels contains JComponent to the GridLayout (notice about scrolling, you have to change scrolling increment)
or use most complex JComponents as
put JPanels contains JComponent as Item to the JList
put JPanels contains JComponent as row to the JTable (with only one Column, with or without TableHeader)
Add one panel at the right and one at the bottom.
Right Panel:
Set Weight X to 1.0.
Set Fill to horizontal.
Bottom Panel:
Set Weight Y to 1.0.
Set Fill to vertical
There may be better ways to that, but this one worked for me.

Categories