JButton wont change size or position on JPanel - java

I added a button into JPanel and tried to change the size and the position of the button. I've tried different lines of codes but they wont work. Also putting in parent.setLayout(null); or panel.setLayout(null); will just completely remove the button and the background
Here is the code:
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.*;
public class app {
public static void main(final String[] args) {
final JFrame parent = new JFrame("CPS TEST");
JButton button = new JButton("Button");
JPanel panel = new JPanel();
panel.setLayout(null);
panel.add(button);
panel.setBackground(Color.DARK_GRAY);
parent.add(panel, BorderLayout.CENTER);
parent.setSize(500, 300);
parent.setBackground(Color.CYAN);
parent.setLocationRelativeTo(null);
parent.setVisible(true);
parent.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

Here are three ways to increase the size of a button:
Changing the position of a component is worthy of a separate question, but changing the size of a button is easy.

Related

Two JPanels in one JFrame

I want to use two JPanels in one JFrame, with an invisible horizontal line between them. I played a little bit and got this:
public class Application {
public static void main(String[] args)
{
JFrame jframe = new JFrame();
jframe.setSize(500,700);
jframe.setVisible(true);
jframe.setTitle("Title");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setResizable(false);
JSplitPane splitPane = new JSplitPane();
JPanel leftPanel = new JPanel();
JPanel rightPanel = new JPanel();
splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
splitPane.setDividerLocation(250);
splitPane.setLeftComponent(leftPanel);
splitPane.setRightComponent(rightPanel);
jframe.add(splitPane);
}
}
Now, the first problem is how can I turn off the "resizability" of the Line between the panels? And how do I make it "invisible"? Maybe use something else than split pane?
Second of all, how do can I work with only one side of the JPanel?
(I am working on an application that lets you draw a circle on the left hand side).
This seems like an easy question but I am relatively new to Java.
As said before in a comment by #MadProgrammer you can use BorderLayout or GridBagLayout but as you're placing the "split" line right in the middle of both panels you could use GridLayout which will make both panels be of the same size no matter if the window is resized.
I didn't tried with GridBagLayout but I did an example on how you could achieve this pane separation without using a JSplitPane.
With GridLayout all you need to do is add the elements to the left pane (in my example I used a JLabel to differentiate them) while in BorderLayout you need to specify that the panel where you'll be painting the circle to be aligned to the left (WEST constant) as I did.
However if you use BorderLayout approach and add text or elements to the right pane, they will be aligned to the right, you can fix it by "boxing" the elements in another pane with a different Layout.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Application {
private JFrame frame;
private JPanel containerPane;
private JPanel topPane;
private JPanel bottomPane;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Application().createAndShowGui();
}
});
}
public void createAndShowGui() {
frame = new JFrame("Example of 2 panels");
containerPane = new JPanel();
topPane = new JPanel();
bottomPane = new JPanel();
containerPane.setLayout(new GridLayout(2, 1));
topPane.setLayout(new GridLayout(1, 2));
bottomPane.setLayout(new BorderLayout());
topPane.add(new JLabel("Left side"));
topPane.add(new JLabel("Right side"));
bottomPane.add(new JLabel("Left side"), BorderLayout.WEST);
bottomPane.add(new JLabel("Right side"), BorderLayout.EAST);
topPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLUE), "Using GridLayout"));
bottomPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLUE), "Using BorderLayout"));
containerPane.add(topPane);
containerPane.add(bottomPane);
frame.add(containerPane);
// frame.pack();
frame.setSize(500, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
I didn't call pack() in this example because the size of both panels (or JLabels in this case was not tall enough to show the difference:
Using pack():
Calling setSize():
Additional tips
Don't forget to place your program on the Event Dispatch Thread (EDT), I did it by writing these lines on the main method:
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Application().createAndShowGui();
}
});
Don't place all your code on the constructor, otherwise it will be hard to maintain
It looks like you can use GridLayout to do this. Here is what i think,
public class Application {
public static void main(String[] args) {
JFrame jframe = new JFrame();
jframe.setTitle("Title");
jframe.setResizable(false);
//This creates one row and two equally divided columns
GridLayout gridLayout = new GridLayout(0, 2);
jframe.setLayout(gridLayout);
gridLayout.layoutContainer(jframe);
JPanel leftPanel = new JPanel();
leftPanel.add(new Label("Left side"));
jframe.add(leftPanel);
JPanel rightPanel = new JPanel();
rightPanel.add(new Label("Right side"));
jframe.add(rightPanel);
jframe.setSize(800, 500);
jframe.setVisible(true);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Here is how it looks:
The panels will not resize as well as there is no line visible that seprates them.

How can I change the background color of a jPanel containing JRadioButtons?

I have an java assignment in which I need to have the background color of a GUI change depending on user selected radio buttons listing different colors.
My program has a JFrame to hold everything, then 3 JPanels (1 Instruction area, 1 Radio Button grid, 1 result Textfield) within that frame.
My action listener is currently setting the background color with this statement: getContentPane().setBackground(Color.decode(colorMap.get(btn.getName())));
The background for the JFrame and two of the three panels successfully changes to the correct color, but the panel holding the JRadioButtons will not change at all!
I have tried changing the opaque setting, I have tried setting the panel's background color to (0,0,0,0) but so far none of that is working for me. Does anyone have a suggestion of what I might try or read up on next?
I don't have enough reputation to post a picture but if seeing what I'm talking about helps, let me know and I can email you a screenshot.
Thanks!
You must additionally set all JRadioButtons.setOpaque(false).
Example with one JRadioButton opaque and one non-opaque:
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class XFrame
extends JFrame
{
public XFrame(String title)
{
super(title);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JRadioButton b1 = new JRadioButton("Non opaque button");
// button must not be opaque
b1.setOpaque(false);
// this button is opaque and does not use the background color of the frame
JRadioButton b2 = new JRadioButton("Opaque button");
JPanel p1 = new JPanel();
// panel must be non opaque also
p1.setOpaque(false);
p1.setLayout(new BoxLayout(p1, BoxLayout.Y_AXIS));
p1.add(b1);
p1.add(b2);
add(p1, BorderLayout.CENTER);
getContentPane().setBackground(Color.red);
setSize(200, 200);
}
public static void main(String[] args)
{
XFrame frame = new XFrame("Test");
frame.setVisible(true);
}
}

how would i change my code to cardLayout

package garage;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
*
* #author Jela
*/
public class VehicleParts extends JPanel {
public VehicleParts() {
JPanel card0 = new JPanel();
//card0.setPreferredSize(new Dimension(800, 600));
JPanel card1 = new JPanel(new BorderLayout());
JPanel card2 = new JPanel(new BorderLayout());
JPanel card3 = new JPanel(new BorderLayout());
JLabel zero = new JLabel("0");
JLabel one = new JLabel("1");
JLabel two = new JLabel("2");
JLabel three = new JLabel("3");
card0.add(zero);
card1.add(one);
card2.add(two);
card3.add(three);
card1.setVisible(false);
card2.setVisible(false);
card3.setVisible(false);
card0.setVisible(false);
JButton buttonZero = new JButton("Repair");
JButton buttonOne = new JButton("Parts");
JButton buttonTwo = new JButton("Stock");
JButton buttonThree = new JButton("Supplier");
//JButton buttonback = new JButton("Parts");
buttonZero.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
card0.setVisible(true);
card1.setVisible(false);// shows card1 when button is clicked
card2.setVisible(false);
card3.setVisible(false);
}
});
buttonOne.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
card1.setVisible(true);// shows card1 when button is clicked
card2.setVisible(false);
card3.setVisible(false);
card0.setVisible(false);
}
});
add(buttonZero);
add(buttonOne);
add(buttonTwo);
add(buttonThree);
add(card0);
add(card1);
add(card2);
add(card3);
}
}
Im not sure how i would change this code into CardLayout. If anyone can give me tips of how i could change it, please tell me. This is not my main class. Ive tried cardlayout, however whenever i use it, i cannot see my buttons anymore.
To make sure the buttons are visible using all the cards, you simply divide the panel into two panels - one panel that will contain the buttons, and the other that will contain the cards.
So - your main panel (VehicleParts) will have a BorderLayout.
You add two panels to it. One is the cards panel. It will have a CardLayout. Make the cards panel reference variable final, so that you can access it from the buttons' event listeners (which are anonymous classes). Although the cards panel itself has a card layout, you add it to your main panel using BorderLayout.CENTER.
The other panel is the buttons panel. It can have a GridLayout, for example. Add it to the main panel using, perhaps, BorderLayout.SOUTH to put it at the bottom.
Add your cards to the cards panel. Don't forget to give them names.
Then create the buttons, and in each button's listener, change cards using the CardLayout.show() method. Add each button to the buttons panel.

JButton not changing size

I've researched the ways to change the size of a jbutton to be displayed on a JFrame.
I am trying both the button.setSize(200,200) and button.setPreferredSize(new Dimension(200,200)), but it does not change. Here's the code:
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Index extends JFrame{
private String title = "This is the motherfucking title";
Dimension dim = new Dimension(500,500);
public Index(){
this.setResizable(false);
this.setTitle(title);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(dim);
this.getContentPane().setBackground(Color.BLACK);
JButton button = new JButton("Button");
button.setSize(200,200);
this.add(button);
}
public static void main(String args[]){
Index ih = new Index();
ih.setVisible(true);
}
}
Here's the result: http://i.imgur.com/Llj0pfo.png
What am I doing wrong?
try this:
JButton button = new JButton("Button");
button.setSize(200,200);
getContentPane().setLayout(null);
getContentPane().add(button);
setVisible(true);
inside your constructor.
this.add(button);
You are adding the button to the content pane of the frame. By default the content uses a BorderLayout and the component is added to the CENTER. Any component added to the CENTER will automatically get the extra space available in the frame. Since you set the size of the frame to (500, 500) there is lots of space available.
As a general rule you should NOT attempt to set the preferred size of a component, since only the component know how big it should be in order to paint itself properly. So your basic code should be:
JButton button = new JButton("...");
frame.add(button);
frame.pack();
frame.setVisible(true);
Now the button will be at its preferred size. However, the button will change size if you resize the frame. If you don't want this behaviour, then you need to use a different Layout Manager.
Use SwingUtilities.invokeLater(); create your Index() inside it, then call setVisible(true); at the end of constructor. At the same time remeber that by default JFrame uses BorderLayout.
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new Index();
}
});

Last button in JFrame is set as background?

import javax.swing.JButton;
import javax.swing.JFrame;
public class Test extends JFrame {
private static final long serialVersionUID = 1L;
public Test() {
super("A test");
setSize(360,300);//Size of JFrame
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);//Sets if its visible.
JButton num1 = new JButton("1");//Set the JButton name
JButton num2 = new JButton("2");
JButton num3 = new JButton("3");
num1.setBounds(80,70,50,50);
num2.setBounds(130,70,50,50);
num3.setBounds(180,70,50,50);
add(num1);
add(num2);
add(num3);
}
public static void main (String[] args) {
new Test().setVisible(true);
}
}
Here the num3 button is set as the background, I want the buttons to be aligned. This might be a trivial mistake I'm not sure as I've just started working with JFrame. Thank you.
The Problem
Basically, there are three parts that are causing this problems...
JFrame uses a BorderLayout by default. This means that only the last component add to any one of the five available layout positions will be managed
You call setVisible(true) before adding anything to the frame
You call setBounds on the buttons.
Because the components are generally painted in z-order (in FIFO order generally) and because of the optimisation in the code, the last button is been controlled by the BorderLayout of the frame, but the other two maintain the bounds you set before
Really interesting problem
Solution(s)
Use an appropriate layout manager, maybe a FlowLayout or GridBagLayout
Call setVisible last where ever possible
Check out Laying Out Components Within a Container for details
This is because of Layout Manager. Please check the code below.
i use another JPanel to put all the buttons. i set the panel as it will have 1 row and 3 columns objects.
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test extends JFrame {
private static final long serialVersionUID = 1L;
JPanel buttonPanel;
public Test() {
super("A test");
setSize(360,300);//Size of JFrame
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);//Sets if its visible.
setLayout(null);
buttonPanel = new JPanel(new GridLayout(1, 3));
buttonPanel.setBounds(80, 70, 150, 50);
JButton num1 = new JButton("1");//Set the JButton name
JButton num2 = new JButton("2");
JButton num3 = new JButton("3");
buttonPanel.add(num1);
buttonPanel.add(num2);
buttonPanel.add(num3);
add(buttonPanel);
}
public static void main (String[] args) {
new Test().setVisible(true);
}
}
Well, never use raw placing and no Layout Manager.
This is your Bible
You can do that with some Layout tricks. For example this one:
First of all import the Layout classes.
import java.awt.GridLayout;
import java.awt.BorderLayout;
Make the frame a BorderLayout frame by copying this in the constructor of it.
setLayout(new BorderLayout());
Then make another JPanel and make it a GridLayout JPanel:
JPanel panel = new JPanel(new GridLayout(1,3));
panel.add(num1);
panel.add(num2);
panel.add(num3);
Arguments 1 and 3 mean "use exactly 1 row and 3 columns to place the widgets in this JPanel".
Finally add the last panel at the center of the frame:
add(panel,BorderLayout.CENTER);
This way you won't deal with dimensions or precise spots and still do what you want...
(to test it copy all the code in "Test" constructor)

Categories