Components are not displayed in my JFrame using Swing.
Actually my aim is:
Add Frame
In the frame add panel
Panel cantains 3 buttons
But it didn't show.
Here is my code
public class Panels
{
JFrame frame;
JPanel panel;
private JButton addButton;
private JButton modifyButton;
private JButton deleteButton;
Panels()
{
initGUI();
launchFrame();
}
public void initGUI()
{
frame = new JFrame();
panel = new JPanel();
addButton = new JButton("Add");
modifyButton = new JButton("Modify");
deleteButton = new JButton("Delete");
}
public void launchFrame()
{
addButton.setBounds(130,50,225,25);
addButton.setBounds(150,50,225,25);
addButton.setBounds(170,50,225,25);
addButton.setBounds(190,50,225,25);
panel.add(addButton);
panel.add(modifyButton);
panel.add(deleteButton);
panel.setLayout(null);
panel.setBackground(Color.RED);
frame.add(panel);
frame.setTitle("My Frame with Panel");
frame.setSize(600,400);
frame.setLocationRelativeTo(null);
frame.setLayout(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Here is main for calling Panels class
When run on main function Frame is shown without controllers (ie 3 buttons not shown)
public class Main
{
public static void main(String[] args)
{
Panels obj_panel=new Panels();
}
}
This is the main problem
frame.setLayout(null);
When you set the layout to null, that means that all of its components must have boundaries set. You try to add the panel, without any boundaries. You only set the boundaries for the buttons in the panel. If you remove the above line, it works.
Other Issues I'd really take a look at:
Don't use null layouts at all. Instead make use of layout managers, and let them handle the sizing and positioning for you. This results in a a much more manageable and flexible UI. Please take some time to learn the different layout managers. Start at Laying out Components Within a Container
All Swing apps should run on a special thread known as the Event Dispatch Thread (EDT). Please take some time to read Initial Threads to learn how you can accomplish this.
Here is a refactor (fixing the "Other issues") with no null layout, just using layout managers, margins, and borders, and the code in the main shows how to run the program on the Event Dispatch Thread
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
Panels obj_panel = new Panels();
}
});
}
}
class Panels {
private JFrame frame;
private JPanel panel;
private JButton addButton;
private JButton modifyButton;
private JButton deleteButton;
Panels() {
initGUI();
launchFrame();
}
private void initGUI() {
frame = new JFrame(); // default layout manager is BorderLayout
panel = new JPanel(); // default layout manager is FlowLayout
addButton = new JButton("Add");
modifyButton = new JButton("Modify");
deleteButton = new JButton("Delete");
}
private void launchFrame() {
JPanel buttonPanel = new JPanel(new GridLayout(0, 1, 10, 10));
buttonPanel.setBackground(Color.RED);
buttonPanel.add(addButton);
buttonPanel.add(modifyButton);
// add margin to left and right of delete button
// other buttons will follow suit because of GridLayout
deleteButton.setMargin(new Insets(0, 50, 0, 50));
buttonPanel.add(deleteButton);
// create some space at the top for the buttonPanel
buttonPanel.setBorder(new EmptyBorder(20, 0, 0, 0));
panel.add(buttonPanel);
panel.setBackground(Color.RED);
frame.add(panel);
frame.setTitle("My Frame with Panel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Related
How do I display two JPanels in the 'North' in borderlayout?
Here's and example code that outputs a GUI with three distinct rows, Top, Middle, Bottom. There's one button covering the first row, 3 buttons covering the second row, and one covering the bottom row.
package borderLayoutDemo;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
public class BorderLayoutDemo {
public static void main(String[] args) {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame fj = new JFrame("Demonstration of Border Layout");
fj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton jbtn1 = new JButton("UP");
JButton jbtn2 = new JButton("DOWN");
JButton jbtn3 = new JButton("LEFT");
JButton jbtn4 = new JButton("RIGHT");
JButton jbtn5 = new JButton("MIDDLE");
JPanel pnl = new JPanel();
pnl.setLayout(new BorderLayout());
pnl.add(jbtn1, BorderLayout.NORTH);
pnl.add(jbtn2, BorderLayout.SOUTH);
pnl.add(jbtn3, BorderLayout.WEST);
pnl.add(jbtn4, BorderLayout.EAST);
pnl.add(jbtn5, BorderLayout.CENTER);
fj.add(pnl);
fj.pack();
fj.setVisible(true);
}
}
Output of above code:
output of above code
However, I'd like there to be two jpanels in the North section so it'd make 4 "rows" like this:
|---------------button--------------| //north
|---------------button2-------------| //north
----------------center--------------- //center
|---------------button3-------------| //south
I've tried simply just adding it as follows:
pnl.add(jbtn1, BorderLayout.NORTH);
pnl.add(jbtn2, BorderLayout.NORTH);
But what happens here is the second button just replaces the first one:
|---------------button2-------------| //north
----------------center--------------- //center
|---------------button3-------------| //south
How would I get two rows in the north layout area?
Creating a more complex GUI is straightforward when you think of a GUI as a JFrame with as many JPanels as necessary to define the GUI.
Here's the GUI you were looking for.
I created a JPanel for each section of the JFrame (NORTH, CENTER, and SOUTH). Each of those JPanels used a BorderLayout so that when you expand the GUI, the NORTH and SOUTH buttons stay the same height.
Here's the complete runnable example code.
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class BorderLayoutDemo implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new BorderLayoutDemo());
}
#Override
public void run() {
JFrame fj = new JFrame("Demonstration of Border Layout");
fj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fj.add(createNorthPanel(), BorderLayout.NORTH);
fj.add(createCenterPanel(), BorderLayout.CENTER);
fj.add(createSouthPanel(), BorderLayout.SOUTH);
fj.pack();
fj.setLocationByPlatform(true);
fj.setVisible(true);
}
private JPanel createNorthPanel() {
JPanel panel = new JPanel(new BorderLayout());
JButton button1 = new JButton("North Button");
panel.add(button1, BorderLayout.NORTH);
JButton button2 = new JButton("North Button 2");
panel.add(button2, BorderLayout.SOUTH);
return panel;
}
private JPanel createCenterPanel() {
JPanel panel = new JPanel(new BorderLayout());
JButton button = new JButton("Center Button");
panel.add(button, BorderLayout.CENTER);
return panel;
}
private JPanel createSouthPanel() {
JPanel panel = new JPanel(new BorderLayout());
JButton button = new JButton("South Button");
panel.add(button, BorderLayout.SOUTH);
return panel;
}
}
I'm trying to learn Java Swing. Right now, I'm making a simple program and I need to make a button. I have two classes: driver and swing.
I create the button and import the javax.swing.JButton and added the button. Finally, the button added to the panel but Idk why I just get the panel?
Can anyone help me, please? Here's my code:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Swing extends JFrame {
private JFrame f;
private JButton button;
private JLabel label;
private JPanel panel;
public Swing() {
}
public Swing(String titleName) {
creatButton();
creatFrame(titleName);
}
public void creatButton() {
JButton btn = new JButton("click me");
JPanel panel = new JPanel();
panel.add(btn);
btn.setBounds(50, 100, 95, 30);
add(panel);
}
private void creatFrame(String title) {
JFrame f = new JFrame(title);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
f.setSize(400, 500);
f.setLayout(null);
}
}
public class Driver {
public static void main (String [] args) {
new Swing ("calculator");
}
}
Okay,lets start with...
JButton btn = new JButton("click me");
JPanel panel = new JPanel();
panel.add(btn);
btn.setBounds(50, 100, 95, 30);
add(panel);
You:
Create a button
Create a panel
You add the button to panel
You add the panel to the frame
And then...
JFrame f = new JFrame("calculator");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new
f.setVisible(true);
You create a brand new instance of JFrame and show it, but it has nothing on to it?! 😱!
Instead, you should avoid extending from JFrame and maybe use JPanel instead, something like...
public class Swing extends JPanel {
private JButton button;
private JLabel label;
public Swing() {
creatButton();
add(button);
}
public void creatButton() {
JButton btn = new JButton("click me");
}
}
Then you can just create a window (or other container) and add it to it
JFrame f = new JFrame(title);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new Swing());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
As a general rule, JFrame is a really poor extension point, it's a complex, compound component and locks you into a single use case. It's generally a better idea to start with something JPanel which provides you with a lot more flexibility and a lot less complexity and is easily reusable.
You really, really, really need to avoid null layouts
creatFrame is creating a new JFrame different than the frame itself (your Swing class extending JFrame).
Remove the line:
JFrame f = new JFrame(title);
and call the methods over this instead of f.
In my code, My okButton is in bad appear, so large and long, How fix this problem?
public class d7Table extends JFrame {
public JTable table;
public JButton okButton;
public d7Table() {
table = new JTable(myTableModel(res));
okButton = new JButton("Ok");
add(new JScrollPane(table), BorderLayout.CENTER);
add(okButton, BorderLayout.PAGE_END);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(800, 600);
this.setLocation(300, 60);
this.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new d7Table();
}
});
}
}
I remove Irrelevant codes.
You've added the button to the SOUTH position of a BorderLayout. This is the default behaviour of BorderLayout.
To fix it, create another JPanel, add your button to it, then add the panel to the SOUTH position instead
Take a look at
A visual guide to layouts
Using Layout Managers
The approach mentioned above is commonly known as compound layouts, as you use a series of containers with different layout managers to achieve the desired effect.
JPanel buttonPane = new JPanel(); // FlowLayout by default
JButton okayButton = new JButton("Ok");
buttonPanel.add(okayButton);
add(okayButton, BorderLayout.SOUTH);
Because the default layout of JFrame is BorderLayout, and PAGE_END means the bottom of the frame horizontally like this:
You have to change the layout of the frame, but don't do that, just create a panel, and add the components to it then add the panel to the container.
JPanel p = new JPanel();
p.add(okButton);
add(p,BorderLayout.PAGE_END);
Here some links may help you understand more about layout managers that usually used:
How To Use BorderLayout
How To Use FlowLayout
And MigLayout which I prefer to use it as it's very flexible layout manager, try it it's amazing.
import java.awt.*;
import javax.swing.*;
public class TableAndButton extends JFrame {
public JTable table;
public JButton okButton;
public TableAndButton() {
table = new JTable();
okButton = new JButton("Ok");
add(new JScrollPane(table), BorderLayout.CENTER);
JPanel bottomPanel = new JPanel();
bottomPanel.add(okButton);
add(bottomPanel, BorderLayout.PAGE_END);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//this.setSize(800, 600); better to call pack()
this.pack();
//this.setLocation(300, 60); better to..
this.setLocationByPlatform(true);
this.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TableAndButton();
}
});
}
}
For some reason i am having problems centering my panel vertically that is located inside another panel. I do exactly as the examples i studied but still no luck.
Down there is my code. Despite using setAlignmentY(0.5f) on my container panel, it still wont center when i resize the window.
Also the components inside container panel wont center either, despite setAligenmentX(0.5f).
I wonder if there is a solution for this, I pretty much tried everything out there but couldnt find a solution.
JLabel idLabel;
JLabel passLabel;
JTextField id;
JTextField pass;
JButton enter;
JPanel container;
public JournalLogin()
{
//setLayout(new FlowLayout());
//setPreferredSize(new Dimension(500, 500));
//setBorder(BorderFactory.createEmptyBorder(100, 100, 100, 100));
container = new JPanel();
container.setLayout(new MigLayout());
container.setAlignmentX(0.5f);
container.setAlignmentY(0.5f);
container.setPreferredSize(new Dimension(300, 300));
container.setBorder(BorderFactory.createTitledBorder("Login"));
add(container);
idLabel = new JLabel("ID:");
idLabel.setAlignmentX(0.5f);
container.add(idLabel);
id = new JTextField();
id.setText("id");
id.setAlignmentX(0.5f);
id.setPreferredSize(new Dimension(80, 20));
container.add(id, "wrap");
setAlignmentX and Y are not the way to go about doing this. One way to center a component in a container is to have the container use GridBagLayout and to add the component without using any GridBagConstraints, a so-called default addition. There are other ways as well.
For example to alter Nick Rippe's example (1+ to him):
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import javax.swing.*;
public class UpdatePane2 extends JPanel {
private static final int PREF_W = 300;
private static final int PREF_H = 200;
public UpdatePane2() {
JPanel innerPanel = new JPanel();
innerPanel.setLayout(new BorderLayout());
innerPanel.add(new JLabel("Hi Mom", SwingConstants.CENTER),
BorderLayout.NORTH);
innerPanel.add(new JButton("Click Me"), BorderLayout.CENTER);
setLayout(new GridBagLayout());
add(innerPanel);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("UpdatePane2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new UpdatePane2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Alignments tend to be pretty picky in Swing - they do [usually] work... but if all you're looking for is a panel that's centered, I'd recommend using Boxes in the BoxLayout (My personal favorite LayoutManager). Here's an example to get you started:
import java.awt.Dimension;
import javax.swing.*;
public class UpdatePane extends JPanel{
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
//Create Buffers
Box verticalBuffer = Box.createVerticalBox();
Box horizontalBuffer = Box.createHorizontalBox();
verticalBuffer.add(Box.createVerticalGlue()); //Top vertical buffer
verticalBuffer.add(horizontalBuffer);
horizontalBuffer.add(Box.createHorizontalGlue()); //Left horizontal buffer
//Add all your content here
Box mainContent = Box.createVerticalBox();
mainContent.add(new JLabel("Hi Mom!"));
mainContent.add(new JButton("Click me"));
horizontalBuffer.add(mainContent);
horizontalBuffer.add(Box.createHorizontalGlue()); //Right horizontal buffer
verticalBuffer.add(Box.createVerticalGlue()); //Bottom vertical buffer
// Other stuff for making the GUI
verticalBuffer.setPreferredSize(new Dimension(300,200));
JFrame frame = new JFrame();
frame.add(verticalBuffer);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
You will need to get the LayoutManager to center the layout for you. Currently it looks like the implementation of "MigLayout" does not honor the Alignment. Try changing it or creating a subclass.
I have this app, but, when I resize the window, the element JTextArea inside, it doesn't resize with the window. Why?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ExampleGUI {
private JTextArea text_area;
private JScrollPane scroll_bar;
private JFrame frame;
private JPanel panel;
public ExampleGUI(){
frame = new JFrame("Example GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
text_area = new JTextArea();
scroll_bar = new JScrollPane(text_area);
panel = new JPanel();
panel.add(scroll_bar);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){public void run(){new ExampleGUI();}});
}
}
You need to set your GridBagConstraint x and y weights (weightx and weighty -- the 5th and 6th parameters in the GridBagConstraint constructor) to a positive value other than 0.0. You should read tutorials on GridBagLayout if you're going to use it as it is fairly complex. Some have had great success nesting simpler layouts or using 3rd party layouts such as MigLayout.
Your frame layout is a FlowLayout. This does not resize children. From the docs:
A flow layout lets each component assume its natural (preferred) size.
You will be better off using a BorderLayout and putting the pane in the CENTER.
Replace this:
frame.setLayout(new FlowLayout());
frame.add(pane);
with this:
frame.setLayout(new BorderLayout());
frame.add(pane, BorderLayout.CENTER);
Also, as Hovercraft points out, if you need the individual components to resize when the pane resizes, then you need to have non-zero weights in the GridBagConstraints.
This takes into account the advice of Hovercraft Full Of Eels & Ted Hopp with a few other tweaks.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Collection;
public class AziendaGUI implements ActionListener {
private JButton view_list;
private JButton save_list;
private JTextArea text_area;
private JScrollPane scrollpane;
private JPanel pane;
private JFrame frame;
private GridBagLayout grid;
public AziendaGUI() {
frame = new JFrame("Immobiliari s.p.a");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
view_list = new JButton("View Property");
view_list.setActionCommand("view_list");
view_list.addActionListener(this);
save_list = new JButton("Save List");
save_list.setActionCommand("save_list");
save_list.addActionListener(this);
text_area = new JTextArea(10,22);
text_area.setEditable(false);
scrollpane = new JScrollPane(text_area);
grid = new GridBagLayout();
pane = new JPanel();
pane.setLayout(grid);
/* Set Constraints view_list button */
grid.setConstraints(view_list, new GridBagConstraints(0,0,1,1,0.0,0.0,GridBagConstraints.WEST,GridBagConstraints.NONE,new Insets(5,5,5,5),0,0));
pane.add(view_list);
/* Set Constraints save_list button */
grid.setConstraints(save_list,new GridBagConstraints(1,0,1,1,0.1,0.1,GridBagConstraints.EAST,GridBagConstraints.NONE,new Insets(5,5,5,5),0,0));
pane.add(save_list);
frame.add(scrollpane);
frame.add(pane, BorderLayout.NORTH);
frame.pack();
frame.setVisible(true);
}
private void store(){
String file_name = JOptionPane.showInputDialog("Inserisci il nome del file");
}
#Override
public void actionPerformed(ActionEvent e){
String s = e.getActionCommand();
if(s.equals("view_list")){
}
if(s.equals("save_list")){
store();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){#Override
public void run(){new AziendaGUI();}});
}
}