Can't position Buttons or JLabels - java

I am new to working with GUI's in Java and I am having a problem moving my text and buttons around. No matter what coordinates I give my button or any of the other JLabel it doesn't move, I was wondering how I could fix it this in such a way that I can place my components where ever I want on the JPanel
public class IntroPage extends JFrame {
public static void main(String[] args) {
IntroPage main = new IntroPage();
main.setVisible(true);
}
private JPanel contentPane;
public IntroPage (){
//make sure the program exits when the frame closes
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Welcome");
contentPane = new JPanel();
setSize(400,700);
//This will center the JFrame in the middle of the screen
setLocationRelativeTo(null);
//Welcome Page stuff :D
JLabel ApplauseLabel = new JLabel("Welcome to U.X.Dot.X");
ApplauseLabel.setFont(new Font("Gill Sans MT", Font.PLAIN, 30));
ApplauseLabel.setLocation(100, 50);
contentPane.add(ApplauseLabel);
JLabel slogan = new JLabel("Register below");
slogan.setFont(new Font("Gill Sans MT", Font.PLAIN, 15));
slogan.setLocation(100, 400);
contentPane.add(slogan);
//FacebookSignUp.
JButton FBbutton = new JButton("Login With FaceBook");
FBbutton.setBackground(Color.BLUE);
FBbutton.setSize(50,50);
FBbutton.setLocation(20, 40);
FBbutton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//Add JPanel to go to FB API. Much later
}
});
contentPane.add(FBbutton);
add(contentPane);
//make sure the JFrame is visible
setVisible(true);
}
}

You're ignoring the layout managers of your contentPane JPanel. Understand that it uses FlowLayout by default, and will ignore your setLocation and setBounds statements. Ror the JPanel to accept absolute positioning, you would have to give it a null layout via contentPane.setLayout(null).
Having said that, I do not advise you to do this! While null layouts, setLocation(...) and setBounds(...) might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
For example the following GUI
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagLayout;
import javax.swing.*;
public class IntroPage2 extends JPanel {
public static final String TITLE = "Welcome to U.X.Dot.X";
private JLabel welcomeLabel = new JLabel(TITLE, SwingConstants.CENTER);
private JButton fbButton = new JButton("Login With Facebook");
public IntroPage2() {
fbButton.setBackground(Color.BLUE);
fbButton.setForeground(Color.CYAN);
welcomeLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 30));
int wlGap = 20;
welcomeLabel.setBorder(BorderFactory.createEmptyBorder(wlGap, wlGap, wlGap, wlGap));
JLabel registerBelowLabel = new JLabel("Register Below");
registerBelowLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 15));
JPanel centralPanel = new JPanel(new GridBagLayout());
centralPanel.setPreferredSize(new Dimension(300, 600));
centralPanel.add(registerBelowLabel);
JPanel topPanel = new JPanel(new BorderLayout());
topPanel.add(fbButton, BorderLayout.LINE_START);
topPanel.add(welcomeLabel, BorderLayout.CENTER);
setLayout(new BorderLayout());
int ebGap = 8;
setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
add(topPanel, BorderLayout.PAGE_START);
add(centralPanel, BorderLayout.CENTER);
}
private static void createAndShowGui() {
IntroPage2 mainPanel = new IntroPage2();
JFrame frame = new JFrame("Welcome");
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(() -> createAndShowGui());
}
}
would create something like:

Related

How can I properly adjust the size and location of a button in JFrame?

I am attempting to make a PC Application using Java and JFrame. I'm trying to format 2 transparent buttons, each sized half of the full screen shown (vertically). The top half of the screen will hold to option to debate someone and the bottom half of the screen will hold the option to spectate a debate if clicked on. Here is what I have so far:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class BackgroundImageJFrame extends JFrame {
JButton b1;
JButton b2;
JPanel j1;
JPanel j2;
public BackgroundImageJFrame() {
setTitle("Background Color for JFrame");
setSize(340,563);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
setLayout(null);
/*
One way
-----------------
setLayout(new BorderLayout());
JLabel background=new JLabel(new ImageIcon("C:\\Users\\Computer\\Downloads\\colorful design.png"));
add(background);
background.setLayout(new FlowLayout());
l1=new JLabel("Here is a button");
b1=new JButton("I am a button");
background.add(l1);
background.add(b1);
*/
// Another way
setLayout(new BorderLayout());
setContentPane(new JLabel(new ImageIcon("C:\\Users\\MLH-User\\Downloads\\Front.jpg")));
setLayout(new FlowLayout());
j1 = new JPanel();
j1.setLayout(null);
b1 = new JButton("Spectate");
//b1.setBounds(0,0,50,50);
b1.setOpaque(false);
b1.setContentAreaFilled(false);
b1.setBorderPainted(false);
j1.add(b1);
b2 = new JButton("Debate");
b2.setLocation(0,0);
b2.setOpaque(false);
b2.setContentAreaFilled(false);
b2.setBorderPainted(false);
j1.add(b2);
add(j1);
// Just for refresh :) Not optional!
setSize(339,562);
setSize(340,563);
}
public static void main(String args[]) {
new BackgroundImageJFrame();
}
}
This is some stuff I experimented with so far, can anyone help me out about where I went wrong?
You should use a layout manager. Here is an example with GridLayout:
public class Example extends JFrame {
private static final int SIZE = 300;
public Example() {
setLayout(new GridLayout(2, 1, 0, 5));
getContentPane().setBackground(Color.WHITE);
JButton debate = new JButton("DEBATE") {
public Dimension getPreferredSize() {
return new Dimension(SIZE, SIZE);
}
};
Font font = debate.getFont().deriveFont(30f);
debate.setFont(font);
// debate.setBorderPainted(false);
debate.setBackground(Color.BLUE.brighter());
debate.setForeground(Color.WHITE);
JButton spectate = new JButton("SPECTATE") {
public Dimension getPreferredSize() {
return new Dimension(SIZE, SIZE);
}
};
spectate.setFont(font);
// spectate.setBorderPainted(false);
spectate.setBackground(Color.RED.brighter());
spectate.setForeground(Color.WHITE);
add(debate);
add(spectate);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(() -> new Example());
}
}
Notes:
You have to realize that screen sizes vary. Setting SIZE to 300 was an arbitrary choice for presentation, screens might not have the required size. You can also set the insets or an empty border instead of specifying the size of the component directly.
You can consider creating a class for these buttons if you have more of them.
This is an example of setting the sizes. I don't know about the location part though.
JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridLayout(4,4,4,4));
for(int i=0 ; i<16 ; i++){
JButton btn = new JButton(String.valueOf(i));
btn.setPreferredSize(new Dimension(40, 40));
panel.add(btn);
}
frame.setContentPane(panel);
frame.pack();
frame.setVisible(true);

PictureCount does not change

the code is used to create an application which shows picture and if your anwser is correct your supposed to see the next picture but the pictureCount does not go up. all of the variables ar declared after the main class and i created an Actionlistener to check if the awnser is correct.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Main {
public static void main(String[] args) {new Main().test();}
public int pictureCount = 1;
JFrame frame = new JFrame();
JButton button1 = new JButton("Submit");
JTextField text = new JTextField();
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
JPanel panel3 = new JPanel();
JLabel label = new JLabel(new ImageIcon("C:\\Users\\Admin\\Desktop\\practicum 3\\" + pictureCount + ".jpg"));
void test(){
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
if(text.getText().equals("5")){
pictureCount++;
new Main().test();
}
}
});
panel1.add(button1);
panel2.add(text);
panel3.add(label);
text.setPreferredSize(new Dimension(100,50));
panel1.setPreferredSize(new Dimension(1000, 200));
panel2.setPreferredSize(new Dimension(1000, 100));
panel3.setPreferredSize(new Dimension(1000, 450));
frame.getContentPane().add(BorderLayout.SOUTH, panel1);
frame.getContentPane().add(BorderLayout.CENTER, panel2);
frame.getContentPane().add(BorderLayout.NORTH, panel3);
frame.setSize(1000,750);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Operation Screen");
frame.setLocationRelativeTo(null);
}
}
You need to read in all the pictures as ImageIcons into an array or ArrayList, say called imageIconArray and then display imageIconArray[0] in your JLabel when you start.
When the button is pressed, increment pictureCount, and then reset the JLabel's icon via its setIcon(...) method:
// in the ActionListener code:
pictureCount++;
label.setIcon(imageIconArray[pictureCount];
Whatever you do, don't create a new Main object, despite what others might say. Why create a new GUI when all you need to do is swap displayed images?

Getting Labels a name with a label

This panel class is suppose to print out "Course Info" Yet when I do try to print it out on the GUI, the gui frame shows up but not the Panel. So I feel the panel code is the problem, how to get the "Course Info" to appear? And if the label is working correctly, why when I post the label to the gui, it just shows another blank Frame?
Panel:
import javax.swing.*;
import java.awt.*;
public class TopPanel extends JPanel {
public TopPanel(){
JPanel panel = new JPanel();
JLabel Crse = new JLabel("Course Info");
Crse.setFont(new Font("Serif", Font.PLAIN, 14));
panel.add(Crse);
}
}
GUI code:
import javax.swing.*;
import java.awt.*;
public class CourseGUI extends JFrame {
public CourseGUI()
{
super("CourseGUI Frame");
JPanel topPanel = new JPanel();
topPanel.setBackground(java.awt.Color.WHITE);
Dimension d = new Dimension(800,600);
topPanel.setPreferredSize(d);
this.setLayout(new BorderLayout());
this.add(topPanel, BorderLayout.NORTH);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(800,600);
//JPanel tp = new TopPanel();
//this.add(tp.BorderLayout.North);
JPanel panel = new TopPanel();
this.add(panel, BorderLayout.SOUTH);
this.setVisible(true);
}
public static void main(String[] args)
{
new CourseGUI();
}
}
Try like this
public TopPanel(){
JLabel Crse = new JLabel("Course Info");
Crse.setFont(new Font("Serif", Font.PLAIN, 14));
add(Crse);
}
You are creating new JPanel which will not going to get added in JFrame.
As you are doing this.
this.add(topPanel, BorderLayout.NORTH);
for JFrame but topPanel don't have anything to display because you didn't add anything.

JButtons not appearing on my JFrame

I am making a program that includes a GUI. For some reason, the JButton objects that I have created are not showing up onto my JFrame when I run the program. Here is the code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ReverseAStringMain extends JPanel {
private JButton enterButton, exitButton;
private JTextField textField;
private JPanel buttonPanel;
private JTextArea textArea;
public ReverseAStringMain(){
JButton enterButton = new JButton("Enter");
JButton exitButton = new JButton("Exit");
enterButton.setPreferredSize(new Dimension(60,60));
exitButton.setPreferredSize(new Dimension(60,60));
ButtonListener listener = new ButtonListener();
enterButton.addActionListener(listener);
exitButton.addActionListener(listener);
buttonPanel = new JPanel();
buttonPanel.setPreferredSize(new Dimension(200,50));
buttonPanel.setBackground(Color.black);
buttonPanel.add(enterButton);
buttonPanel.add(exitButton);
textField = new JTextField();
textField.setSize(200, 100);
textArea = new JTextArea();
textArea.add(textField);
add(buttonPanel);
add(textField);
}
//Creating a ButtonListener class that implements the ActionListener interface
private class ButtonListener implements ActionListener{
#Override
//Overriding the ActionPerformed method of ActionListener
public void actionPerformed(ActionEvent action) {
if(action.getSource()== enterButton)
enterButton();
if(action.getSource()== exitButton)
System.exit(0);
}
}
private void enterButton() {
// TODO Auto-generated method stub
}
public static void main (String[] args){
JFrame frame = new JFrame("Raj's Reverse a String Program");
frame.setBackground(Color.white);
frame.setVisible(true);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setSize(new Dimension(600,600));
//frame.pack();
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ReverseAStringMain());
}
}
If there are any problems or improvements I can make in my code, please let me know!
You're adding the components to your JFrame after it's visible. You should either add them to the JFrame before it's visible, or revalidate the JFrame after you add the components.
When I load your code (after making it a lot shorter in height), this is what I see:
I suspect this is more along the lines of what you expect to see.
Here is how I did it. Look carefully at:
The numbers provided to the BorderLayout constructor for white space between the panels.
The EmptyBorder for white space around the controls.
The use of pack() to shrink the GUI to the natural size.
The use of size hints in the construction of the text field and text area.
The use of a second layout - commonly known as a combined, or nested, layout.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class ReverseAStringMain extends JPanel {
private JButton enterButton, exitButton;
private JTextField textField;
private JPanel pageTopPanel;
private JTextArea textArea;
public ReverseAStringMain(){
super(new BorderLayout(10,10));
setBorder(new EmptyBorder(5,15,5,15));
JButton enterButton = new JButton("Enter");
JButton exitButton = new JButton("Exit");
pageTopPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
pageTopPanel.setBackground(Color.black);
pageTopPanel.add(enterButton);
pageTopPanel.add(exitButton);
textField = new JTextField(5);
pageTopPanel.add(textField);
textArea = new JTextArea(4,40);
add(pageTopPanel, BorderLayout.PAGE_START);
add(textArea); // defaults to CENTER
}
public static void main (String[] args){
Runnable r = new Runnable() {
public void run() {
JFrame frame = new JFrame("XXX's Laid out Program");
frame.setBackground(Color.white);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ReverseAStringMain());
frame.pack();
frame.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
General Tips
Java GUIs might have to work on a number of platforms, on different screen resolutions & using different PLAFs. As such they are not conducive to exact placement of components. To organize the components for a robust GUI, instead use layout managers, or combinations of them1, along with layout padding & borders for white space2.
Generally, you want to set the frame visible After adding components
JFrame frame = new JFrame("Raj's Reverse a String Program");
frame.setBackground(Color.white);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setSize(new Dimension(600,600));
//frame.pack();
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ReverseAStringMain());
frame.setVisible(true); <<------
Also, it is better practice to use .pack() insteack of .setSize(), so you had it right in the commented out //.pack()
If you wanted to set a size to the panel, you would override the getPreferredSize() like this
public Dimension getPreferredSize() {
return new Dimension(300, 300); // or whatever size you want
}
When you .pack(), this preferred size will be respected by the frame.
Also, not, setting the size of the JTextField won't work. What you want to do is pass it an integer value for the number of character spaces, like this
textField = new JTextField(20);
See an edited version of your program, with all the above mentioned points. One thing I also did was get rid of all your .setPreferredSizes. You will see the difference
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ReverseAStringMain extends JPanel {
private JButton enterButton, exitButton;
private JTextField textField;
private JPanel buttonPanel;
private JTextArea textArea;
public ReverseAStringMain() {
JButton enterButton = new JButton("Enter");
JButton exitButton = new JButton("Exit");
//enterButton.setPreferredSize(new Dimension(60, 60));
//exitButton.setPreferredSize(new Dimension(60, 60));
ButtonListener listener = new ButtonListener();
enterButton.addActionListener(listener);
exitButton.addActionListener(listener);
buttonPanel = new JPanel();
//buttonPanel.setPreferredSize(new Dimension(200, 50));
buttonPanel.setBackground(Color.black);
buttonPanel.add(enterButton);
buttonPanel.add(exitButton);
textField = new JTextField(20);
//textField.setSize(200, 100); /// <<-----------
textArea = new JTextArea();
textArea.add(textField);
add(buttonPanel);
add(textField);
}
public Dimension getPreferredSize() {
return new Dimension(600, 600);
}
// Creating a ButtonListener class that implements the ActionListener
// interface
private class ButtonListener implements ActionListener {
#Override
// Overriding the ActionPerformed method of ActionListener
public void actionPerformed(ActionEvent action) {
if (action.getSource() == enterButton)
enterButton();
if (action.getSource() == exitButton)
System.exit(0);
}
}
private void enterButton() {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
JFrame frame = new JFrame("Raj's Reverse a String Program");
frame.setBackground(Color.white);
frame.getContentPane().add(new ReverseAStringMain());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Have a look at the Swing tutorial trail for more information on creating GUIs with Swing.
Try to add the buttonPanel to a Container, like this. And extend JFrame instead
Container contentpane = getContentPane();
contentPane.add(buttonPanel);

Why isn't this JLabel in the center of this Java application?

newbie Java programmer here:
I hate asking questions every time I run into a problem, but I don't see what I should use to get the green "Hello World" label go right into the center of the JPanel. Here is my code:
package game;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Javagame extends JPanel implements ActionListener{
protected JButton b1;
private JLabel label;
public Javagame() {
b1 = new JButton("Button!");
b1.setActionCommand("change");
b1.addActionListener(this);
add(b1);
label = new JLabel("Hello World!", SwingConstants.CENTER);
label.setFont(new Font("Arial", Font.BOLD, 20));
label.setForeground(new Color(0x009900));
add(label, BorderLayout.CENTER);
}
public void actionPerformed(ActionEvent e) {
if ("change".equals(e.getActionCommand())) {
label.setText("Hello Universe!");
b1.setActionCommand("changeBack");
}
if ("changeBack".equals(e.getActionCommand())) {
label.setText("Hello World!");
b1.setActionCommand("change");
}
}
private static void createWindow(){
JFrame frame = new JFrame("Javagame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(500,500));
Javagame newContentPane = new Javagame();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
createWindow();
}
}
BorderLayout.CENTER doesn't seem to work in add(). Any help would be appreciated, thank you!
The JLabel is in the centered within the parent container, the text is aligned within the label.
Try...
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalAlignment(JLabel.CENTER);
BorderLayout.CENTER doesn't seem to work
The default layout of a JPanel is a FlowLayout. You need to set the layout to a BorderLayout.
Also, you need to add the button to the NORTH of the BorderLayout.
Then the button will appear at the top and the label will be centered.
When adding the label use FlowLayout field.
//Code apove
label = new JLabel("Hello World!", SwingConstants.CENTER);
label.setFont(new Font("Arial", Font.BOLD, 20));
label.setForeground(new Color(0x009900));
add(label, FlowLayout.CENTER);//!!
//Code under
Because you haven't changed the layout in your panel, don't use BorderLayout.
If you really want to use BorderLayout rarther than FlowLayout add just setLayout() command in it.
//Code apove
label = new JLabel("Hello World!", SwingConstants.CENTER);
label.setFont(new Font("Arial", Font.BOLD, 20));
label.setForeground(new Color(0x009900));
setLayout(new BorderLayout()); //!!
add(label, BorderLayout.CENTER);
add(b1,BorderLayout.????); //Edited
//Code under
#Edit - add your button too after setLayout() method or set the layout in the beginning when you make you panel

Categories