I use a JLabel and in front of it a JTextField so that I can represent a defense-like stat with a value. I use the following code:
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
JLabel jl = new JLabel();
ImageIcon ii = new ImageIcon("C:\\Users\\Max\\Desktop\\shield.png");
jl.setIcon(ii);
gbc.gridy = 0;
gbc.gridx = 0;
add(jl, gbc);
gbc.insets = new Insets(5, 10, 10, 10);
JTextField jtf = new JTextField(2);
jtf.setHorizontalAlignment(JTextField.CENTER);
gbc.ipadx = 10;
gbc.ipady = 10;
gbc.gridy = 0;
gbc.gridx = 0;
jtf.setFocusable(false);
add(jtf, gbc);
And get:
Everything is fine, however, if I try to resize the window, the JTextField disappears for ever and only the JLabel shows. Why is that so?
There is no relationship between the position of the label and the position of the text field, this means that the label and field are free to move independently of each other
There is a z-ordering issue, components lower in the container order are painted after those higher in the container order (reverse order), meaning that the label is actually getting painted before the shield when the whole container is updated. The reason that it might sometimes work is because components can actually be painted independently of each other, meaning that the textfield could actually get painted without need to notify either the parent container or the label
For example...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
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 TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 10, 10, 10);
JTextField jtf = new JTextField(2);
jtf.setHorizontalAlignment(JTextField.CENTER);
gbc.ipadx = 10;
gbc.ipady = 10;
gbc.gridy = 0;
gbc.gridx = 0;
jtf.setFocusable(false);
add(jtf, gbc);
gbc = new GridBagConstraints();
try {
JLabel jl = new JLabel();
ImageIcon ii = new ImageIcon(ImageIO.read(getClass().getResource("/shield01.png")));
jl.setIcon(ii);
gbc.gridy = 0;
gbc.gridx = 0;
add(jl, gbc);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
A possibly better solution would be to create a "background" component which took an image and painted it as the background of the component and then add your text field to it.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class TestBackground {
public static void main(String[] args) {
new TestBackground();
}
public TestBackground() {
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 TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
try {
BackgroundPane pane = new BackgroundPane(ImageIO.read(getClass().getResource("/shield02.png")));
pane.setLayout(new GridBagLayout());
pane.setBorder(new EmptyBorder(5, 5, 5, 5));
GridBagConstraints gbc = new GridBagConstraints();
JTextField jtf = new JTextField(2);
jtf.setHorizontalAlignment(JTextField.CENTER);
gbc.ipadx = 10;
gbc.ipady = 10;
gbc.gridy = 0;
gbc.gridx = 0;
jtf.setFocusable(false);
pane.add(jtf, gbc);
add(pane);
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
public class BackgroundPane extends JPanel {
private BufferedImage img;
public BackgroundPane(BufferedImage img) {
this.img = img;
}
#Override
public Dimension getPreferredSize() {
return img != null ? new Dimension(img.getWidth(), img.getHeight()) : super.getPreferredSize();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
int x = (getWidth() - img.getWidth()) / 2;
int y = (getHeight() - img.getHeight()) / 2;
g.drawImage(img, x, y, this);
}
}
}
}
Related
I've been trying to make a GUI like this:
However, the difficult I've run into is that I need to make the text of the buttons variable- each button should present a different option, which can vary in text length. While this itself is not difficult, I've tried countless different things but I can't get the buttons to center despite their text length. Whatever I try, I always have one of these problems:
The buttons don't center (there's space left at the left but they exceed the window at the right)
For some reason, the Question and the Goodratio change location based on the button size
I have no clue left how to do this. Does anyone have some useful intuitions on what's the best way to do this? It would be much appreciated.
EDIT: Code of the constructor function(which doesn't center correctly), which I use to set the components, as requested:
public ButtonPannel(Test test)
{
super();
op1Button = new JButton("Option 1");
op2Button = new JButton("Option 2");
op3Button = new JButton("Option 3");
questionText = new JLabel("Question");
rightAndWrongAmount = new JLabel("rightAndWrongAmount");
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[]{30, 331, 0};
gridBagLayout.rowHeights = new int[]{16, 0, 134, 35, 16, 0};
gridBagLayout.columnWeights = new double[]{0.0, 0.0, Double.MIN_VALUE};
gridBagLayout.rowWeights = new double[]{0.0, 0.0, 1.0, 0.0, 0.0, Double.MIN_VALUE};
setLayout(gridBagLayout);
JPanel panel = new JPanel();
FlowLayout flowLayout = (FlowLayout) panel.getLayout();
op1Button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
GridBagConstraints gbc_lblQuestion = new GridBagConstraints();
gbc_lblQuestion.insets = new Insets(0, 0, 5, 0);
gbc_lblQuestion.gridx = 1;
gbc_lblQuestion.gridy = 1;
add(questionText, gbc_lblQuestion);
panel.add(op1Button);
panel.add(op2Button);
panel.add(op3Button);
GridBagConstraints gbc_panel = new GridBagConstraints();
gbc_panel.insets = new Insets(0, 0, 5, 0);
gbc_panel.gridx = 1;
gbc_panel.gridy = 3;
add(panel, gbc_panel);
GridBagConstraints gbc_lblNewLabel_1 = new GridBagConstraints();
gbc_lblNewLabel_1.gridx = 1;
gbc_lblNewLabel_1.gridy = 4;
add(rightAndWrongAmount, gbc_lblNewLabel_1);
op1Button.addActionListener(new InputHandler(test));
op1Button.setActionCommand("1");
op2Button.addActionListener(new InputHandler(test));
op2Button.setActionCommand("2");
op3Button.addActionListener(new InputHandler(test));
op3Button.setActionCommand("3");
}
The code is generated using WindowBuilder. The problem isn't so much in the code, but more which Layout to use etc.
Layouts are a little bit of black magic and trial and error. Very rarely will a single layout achieve exactly what you want, so you often need to resort to compound layouts (using multiple containers and layouts) to get what you want...
So, basically, this is made of a panel, with another panel holding the buttons (and another panel acting as the "pseudo" content to add space)
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
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 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;
add(new JLabel("Question"), gbc);
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
// This is just to act as some psudo context
add(new FillerPane(), gbc);
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
gbc.weighty = 0;
add(makeButtonPane(), gbc);
add(new JLabel("Goodratio"), gbc);
}
public JPanel makeButtonPane() {
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
panel.add(new JButton("Short"));
panel.add(new JButton("Long, long, long and lobng"));
panel.add(new JButton("In the middle"));
return panel;
}
}
public class FillerPane extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
"But I want the buttons to be the same size" I hear you ask, sure, change layouts...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
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 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;
add(new JLabel("Question"), gbc);
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
// This is just to act as some psudo context
add(new FillerPane(), gbc);
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
gbc.weighty = 0;
add(makeButtonPane(), gbc);
add(new JLabel("Goodratio"), gbc);
}
public JPanel makeButtonPane() {
JPanel panel = new JPanel(new GridLayout(1, 0));
panel.add(new JButton("Short"));
panel.add(new JButton("Long, long, long and lobng"));
panel.add(new JButton("In the middle"));
return panel;
}
}
public class FillerPane extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
You have to look at the layout and think about how each element relates to the others, in terms of what you want them to do, then find the layout managers which are going to help you achieve the end results and combine them together
I have this code that creates a Jframe where I add a JLabel with a picture and a JpasswordField. I want the JpasswordField to be on top of the image but only depending on where I do the f.add I get one of them showed or not... I want the JpasswordField to be on top of the picture to allow the user to introduce a password but with the picture as background.
Here is the code:
package java;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
public class Java implements Runnable {
public static void main(String[] args) {
EventQueue.invokeLater(new Java());
}
#Override
public void run() {
JFrame f = new JFrame();
/*Keep on front*/
f.toFront();
f.repaint();
f.setAlwaysOnTop(true);
f.setExtendedState( f.getExtendedState()|JFrame.MAXIMIZED_BOTH );
f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
f.setUndecorated(true);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
f.setBounds(0,0,screenSize.width-5, screenSize.height-100);
double width = screenSize.getWidth();
double height = screenSize.getHeight();
System.out.println(width+" "+height);
BufferedImage myPicture = null;
try {
myPicture = ImageIO.read(new File("C:\\image.jpg"));
} catch (IOException e1) {
e1.printStackTrace();
}
Image dimg = myPicture.getScaledInstance((int)width, (int)height,Image.SCALE_SMOOTH);
JLabel picLabel = new JLabel(new ImageIcon(dimg));
JPasswordField myTextfield = new JPasswordField("Password");
myTextfield.setEchoChar('*'); // U+26AB
picLabel.setPreferredSize(screenSize);
picLabel.setVerticalAlignment(JLabel.BOTTOM);
/*Depending of who I add first the image or the JPasswordField is showed*/
f.add(myTextfield);
f.add(picLabel);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
First off, your code should be geared towards creating JPanels, and you should control the layout manager of this JPanel directly. Then you can place and display your JPanel in a JDialog not a JFrame, since much of your code appears to be trying to emulate a dialog's actions (such as keeping it on top and such).
That being sad, one of your big problems is that you're ignoring the layout manager that the JFrame's contentPane is using, the BorderLayout. By adding components to it in a default fashion, you will cover up anything that was added to the same position previously. Instead I suggest:
Create a JPanel
Draw your image as a background image in the JPanel's paintComponent methd.
Add your JLabel to your JPanel.
Display the JPanel in a JDialog not a JFrame.
For example:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class DialogExample extends JPanel {
private static final int COLUMN_COUNT = 10;
private static final int I_GAP = 3;
public static final String BKG_IMG_PATH = "http://upload.wikimedia.org/wikipedia/commons/"
+ "thumb/9/92/Camels_in_Jordan_valley_%284568207363%29.jpg/800px-Camels_in_Jordan_valley_"
+ "%284568207363%29.jpg";
private BufferedImage backgrndImage;
private JTextField userNameField = new JTextField();
private JPasswordField passwordField = new JPasswordField();
private JPanel mainPanel = new JPanel(new GridBagLayout());
private JButton okButton = new JButton("OK");
private JButton cancelButton = new JButton("Cancel");
public DialogExample(BufferedImage backgrndImage) {
this.backgrndImage = backgrndImage;
userNameField.setColumns(COLUMN_COUNT);
passwordField.setColumns(COLUMN_COUNT);
JPanel btnPanel = new JPanel(new GridLayout(1, 0, 5, 5));
btnPanel.setOpaque(false);
btnPanel.add(okButton);
btnPanel.add(cancelButton);
GridBagConstraints gbc = getGbc(0, 0, GridBagConstraints.BOTH);
mainPanel.add(createLabel("User Name", Color.white), gbc);
gbc = getGbc(1, 0, GridBagConstraints.HORIZONTAL);
mainPanel.add(userNameField, gbc);
gbc = getGbc(0, 1, GridBagConstraints.BOTH);
mainPanel.add(createLabel("Password:", Color.white), gbc);
gbc = getGbc(1, 1, GridBagConstraints.HORIZONTAL);
mainPanel.add(passwordField, gbc);
gbc = getGbc(0, 2, GridBagConstraints.BOTH, 2, 1);
mainPanel.add(btnPanel, gbc);
mainPanel.setOpaque(false);
add(mainPanel);
}
private JLabel createLabel(String text, Color color) {
JLabel label = new JLabel(text);
label.setForeground(color);
return label;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (backgrndImage != null) {
g.drawImage(backgrndImage, 0, 0, this);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet() || backgrndImage == null) {
return super.getPreferredSize();
}
int imgW = backgrndImage.getWidth();
int imgH = backgrndImage.getHeight();
return new Dimension(imgW, imgH);
}
public static GridBagConstraints getGbc(int x, int y, int fill) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.insets = new Insets(I_GAP, I_GAP, I_GAP, I_GAP);
gbc.fill = fill;
return gbc;
}
public static GridBagConstraints getGbc(int x, int y, int fill, int width,
int height) {
GridBagConstraints gbc = getGbc(x, y, fill);
gbc.gridwidth = width;
gbc.gridheight = height;
return gbc;
}
private static void createAndShowGui() throws IOException {
final JFrame frame = new JFrame("Frame");
final JDialog dialog = new JDialog(frame, "User Sign-In", ModalityType.APPLICATION_MODAL);
URL imgUrl = new URL(BKG_IMG_PATH);
BufferedImage img = ImageIO.read(imgUrl);
final DialogExample dlgExample = new DialogExample(img);
dialog.add(dlgExample);
dialog.pack();
JPanel mainPanel = new JPanel();
mainPanel.add(new JButton(new AbstractAction("Please Press Me!") {
#Override
public void actionPerformed(ActionEvent e) {
dialog.setVisible(true);
}
}));
mainPanel.setPreferredSize(new Dimension(800, 650));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
createAndShowGui();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
Just to give one example (amongst many other possibilities), here is a small snippet that shows how to handle this.
Btw, when you call f.pack(); f.setLocationRelativeTo(null);, then this call is useless: f.setBounds(0,0,screenSize.width-5, screenSize.height-100);
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.SwingUtilities;
public class BasicSwingTest2 {
private JFrame frame;
protected void initUI() throws MalformedURLException {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
askForPassword();
}
private void askForPassword() {
final JDialog dialog = new JDialog(frame);
dialog.setResizable(false);
BufferedImage myPicture = null;
try {
myPicture = ImageIO
.read(new URL("http://images.all-free-download.com/images/graphiclarge/blue_abstract_background_310971.jpg"));
} catch (IOException e1) {
e1.printStackTrace();
}
Image dimg = myPicture.getScaledInstance(Toolkit.getDefaultToolkit().getScreenSize().width * 2 / 3, Toolkit.getDefaultToolkit()
.getScreenSize().height * 2 / 3, Image.SCALE_SMOOTH);
JLabel picLabel = new JLabel(new ImageIcon(dimg));
picLabel.setLayout(new GridBagLayout());
final JPasswordField password = new JPasswordField(25);
password.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Password is " + new String(password.getPassword()));
dialog.setVisible(false);
}
});
picLabel.add(password);
dialog.add(picLabel);
dialog.setTitle("Enter your password");
dialog.pack();
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
new BasicSwingTest2().initUI();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
});
}
}
I have encountered a problem whilst working the JFrame's, and JButtons. I am trying to center my JButton, however when I do so, it covers almost the entire screen. Any idea's on what's causing this?
Here is a picture on how it looks :
And here is my code :
package character;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
/**
* Created by Niknea on 6/28/14.
*/
public class characterSelector{
JFrame cselectorButtons, clogo;
JLabel logo, characterName, label;
JButton male, female;
public characterSelector(){
this.createCharacterSelector();
}
public void createCharacterSelector() {
try {
label = new JLabel(new ImageIcon(ImageIO.read(getClass()
.getResource("/resources/Grass_Background.jpg"))));
cselectorButtons = new JFrame("SupremeSoccer");
logo = new JLabel(new ImageIcon(ImageIO.read(this.getClass().getResource("/resources/Character_Selector_Image.png"))));
characterName = new JLabel("<Character Name>");
characterName.setFont(new Font(characterName.getFont().getName(),
Font.HANGING_BASELINE, 50));
/*
Buttons
*/
male = new JButton("Male");
////******************////
//// END OF BUTTONS ////
////****************////
cselectorButtons.add(logo);
cselectorButtons.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cselectorButtons.setContentPane(label);
cselectorButtons.setLayout(new BorderLayout());
cselectorButtons.add(logo, BorderLayout.NORTH);
cselectorButtons.add(male, BorderLayout.CENTER);
cselectorButtons.pack();
cselectorButtons.setLocationRelativeTo(null);
cselectorButtons.setVisible(true);
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
Thanks again.
Any idea's on what's causing this?
This is the default behaviour of BorderLayout. The component at the CENTER position will occupy the maximum amount of space the is available from the parent component, when the other (NORTH, SOUTH, EAST, WEST) positions have been taken into account
Depending on what you are trying to achieve you might consider creating another JPanel (set it's opaque state to false so it's transparent) and use something like GridLayout or GridBagLayout instead.
Take a look at A Visual Guide to Layout Managers for some more ideas
Updated
So based on your linked code, I changed
part2 = new JPanel();
to
part2 = new JPanel(new java.awt.GridBagLayout());
And got...
Updated with additional example
Start by breaking down your requirements into individual containers and focus on the layout requirements for each individual, then build them all back into a single container.
This will make changing them later much easier and also make controlling them much easier...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ExampleLayout {
public static void main(String[] args) {
new ExampleLayout();
}
public ExampleLayout() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private HeaderPane header;
private ScorePane score;
private CharacterSelectionPane characterSelection;
public TestPane() {
setLayout(new BorderLayout());
JLabel background = new JLabel();
try {
BufferedImage img = ImageIO.read(getClass().getResource("/Grass.jpg"));
background.setIcon(new ImageIcon(img));
} catch (IOException ex) {
ex.printStackTrace();
}
add(background);
background.setLayout(new GridBagLayout());
header = new HeaderPane();
score = new ScorePane();
characterSelection = new CharacterSelectionPane();
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.BOTH;
background.add(header, gbc);
background.add(score, gbc);
gbc.weighty = 1;
background.add(characterSelection, gbc);
}
}
public class HeaderPane extends JPanel {
public HeaderPane() {
setLayout(new BorderLayout());
JLabel label = new JLabel("Character Selection");
label.setForeground(Color.WHITE);
label.setFont(label.getFont().deriveFont(Font.BOLD, 48f));
label.setHorizontalAlignment(JLabel.CENTER);
add(label);
setOpaque(false);
}
}
public class ScorePane extends JPanel {
public ScorePane() {
JLabel label = new JLabel("[-][-[]-][-]");
label.setForeground(Color.YELLOW);
add(label);
setOpaque(false);
}
}
public class CharacterSelectionPane extends JPanel {
private JButton btMale;
private JButton btFemale;
private JTextField tfName;
private JButton btContinue;
public CharacterSelectionPane() {
setOpaque(false);
setLayout(new GridBagLayout());
btMale = new JButton("Male");
btFemale = new JButton("Female");
btContinue = new JButton("Continue");
tfName = new JTextField(10);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(4, 4, 4, 4);
gbc.fill = GridBagConstraints.HORIZONTAL;
add(btMale, gbc);
gbc.gridx++;
add(btFemale, gbc);
gbc.gridx = 0;
gbc.gridy++;
add(new JLabel("Name:"), gbc);
gbc.gridx++;
add(tfName, gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(btContinue, gbc);
}
}
}
Use a BoxLayout or (easier) GridBagLayout for the bottom area, as seen in this answer.
I have 2 buttons, one named btnShort and one named btnLong. I'd like them to be of the same width, so what would be the best option?
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestCode2 {
public static void main(String[] args) {
JFrame window = new JFrame("Test2");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(400, 200);
// ---------------------------------------------------------------------
GridBagLayout layout = new GridBagLayout();
GridBagConstraints constraints = new GridBagConstraints();
JPanel container = new JPanel(layout);
window.add(container);
constraints.gridy = 0;
JButton btnShort = new JButton("Short");
layout.setConstraints(btnShort, constraints);
container.add(btnShort);
constraints.gridy = 1;
JButton btnLong = new JButton("That's a long button");
layout.setConstraints(btnLong, constraints);
container.add(btnLong);
//This one won't work because button dimension is not known yet...
//btnShort.setPreferredSize(new Dimension(btnLong.getWidth(), btnLong.getHeight()));
// ---------------------------------------------------------------------
window.setVisible(true);
}
}
Set the GridBagConstraints fill property to GridBagConstraints.HORIZONTAL so that both JButton components occupy equal width in the container
constraints.fill = GridBagConstraints.HORIZONTAL;
Make use of an appropriate layout manager, like GridBagLayout and it's constraints...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Buttons {
public static void main(String[] args) {
new Buttons();
}
public Buttons() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
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;
add(new JButton("I'm a very long button"), gbc);
add(new JButton("I'm not"), gbc);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
I have three radio buttons that I want to use to change the size of a JTextArea when I click the buttons.
if(rd_7inch.isSelected())
{
jScrollPane2.setSize(200,200);
txt_sysnp.setSize(5,20);
}if(rd_9inch.isSelected())
{
jScrollPane2.setSize(200,200);
txt_sysnp.setSize(5,25);
}if(rd_10inch.isSelected())
{
jScrollPane2.setSize(200,200);
txt_sysnp.setSize(5,30);
}
The important point is that whenever you update the UI you have to call revalidate() on that panel or container so that your changes get apply.
You can also do this by setSize() method.
public void showDialog(){
btnUp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dimSPane.setSize(new Dimension(400,50));
pane.revalidate();
}
});
btnUp.setSize(new Dimension(100,24));
btnDn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dimSPane.setSize(new Dimension(200,25));
pane.revalidate();
}
});
btnDn.setSize(new Dimension(100,24));
dimSPane.setSize(new Dimension(200,25));
Dimension dimtfield = new Dimension();
dimtfield.setSize(new Dimension(200,25));
spane.setMinimumSize(dimSPane);
spane.setMaximumSize(dimSPane);
spane.setPreferredSize(dimSPane);
tfield.setMinimumSize(dimtfield);
tfield.setMaximumSize(dimtfield);
tfield.setPreferredSize(dimtfield);
pane.add(spane);
pane.add(tfield);
pane.add(btnUp);
pane.add(btnDn);
JDialog dlg =new JDialog();dlg.add(pane);
dlg.pack();
dlg.show();
}
It is likely that you components are under the control of a layout manager.
The only means by which you can suggest changes to the size would be to use setColumns and setRows and use a layout manager that respects the preferred size of its components
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TextAreaSize {
public static void main(String[] args) {
new TextAreaSize();
}
public TextAreaSize() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTextArea ta;
public TestPane() {
setLayout(new GridBagLayout());
JRadioButton btnSmall = new JRadioButton(new SizeAction("Small", 2, 10));
JRadioButton btnMed = new JRadioButton(new SizeAction("Medium", 4, 15));
JRadioButton btnLarge = new JRadioButton(new SizeAction("Large", 12, 24));
ButtonGroup bg = new ButtonGroup();
bg.add(btnSmall);
bg.add(btnMed);
bg.add(btnLarge);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.NORTHWEST;
add(btnSmall, gbc);
gbc.gridy++;
add(btnMed, gbc);
gbc.gridy++;
add(btnLarge, gbc);
gbc.gridx++;
gbc.gridy = 0;
gbc.gridheight = GridBagConstraints.REMAINDER;
gbc.anchor = GridBagConstraints.CENTER;
ta = new JTextArea();
add(new JScrollPane(ta), gbc);
btnSmall.doClick();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public class SizeAction extends AbstractAction {
private int rows;
private int columns;
public SizeAction(String name, int rows, int columns) {
putValue(NAME, name);
this.rows = rows;
this.columns = columns;
}
#Override
public void actionPerformed(ActionEvent e) {
ta.setRows(rows);
ta.setColumns(columns);
revalidate();
}
}
}
}