-2

I can't display button and i don't know why Is there any way to fix it

I want it to appear at the top in the far left

import java.awt.event.*;
import java.awt.*;

import javax.swing.*;

public class test extends JFrame{

    JButton b1 = new JButton("b1");
    
    public test() {
        
        b1.setBounds(0, 0, 125,100);
        
        add(b1);
        
    }

    public static void main(String[] args) {
            
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(null);
        f.setSize(925, 500);
        f.setVisible(true);

    }

}
Naofumi
  • 1
  • 1
  • 1
    You extend a JFrame and create a separate, different JFrame in the main method. Oracle has a helpful tutorial, [Creating a GUI With Swing](https://docs.oracle.com/javase/tutorial/uiswing/index.html). Skip the Learning Swing with the NetBeans IDE section. Pay particular attention to the [Laying Out Components Within a Container](https://docs.oracle.com/javase/tutorial/uiswing/layout/index.html) section. – Gilbert Le Blanc Sep 21 '22 at 18:22
  • 1
    **Don't use a null layout** and `setBounds(...)`. Swing was designed to be used with layout managers. All the examples from the above links in the Swing tutorial will demonstrate how to use layout managers. Class names should start with a capital letter. Learn and follow Java naming conventions to avoid confusion. – camickr Sep 21 '22 at 18:30

2 Answers2

2

Your code has several problems, including:

  • Your class extends JFrame: There's no reason to extend a class if you're not changing the innate behavior of that class, in other words, if you're not overriding methods of the class.
  • Also, extending JFrame forces your code to create JFrames, and that limits the flexibility of the code, since sometimes you will want to use the same GUI code in other ways, such as nested within another JFrame or JPanel or in a dialog window such as a JDialog or JOptionPane.
  • Even though you extend JFrame in your "test" class, you never create an instance of this class, your main method has no call to new test(), and so that JFrame class, while defined, is never utilized.
  • You are using setBounds(...) to artificially place a component in your Swing GUI. For this to work, you would need to change the container's layout (here the "test" JFrame) to null, something that you don't do.
  • Also, while null layouts 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.
  • You are calling setSize(...) on the JFrame that you do create, artificially constraining your top-level window (the JFrame) to some size, a size that may not be optimal for that GUI on all platforms.

Instead, I suggest that you:

  • Don't extend JFrame, don't extend anything unless needed, and in that situation, you would usually extend a JPanel and not a JFrame. You would usually do this when you desire to override one of the JPanel's methods such as its paintComponent(Graphics g) method to allow it to paint an image or drawing on it.
  • Nest JPanels each using its own layout manager. This will require that you first learn about how to use the Swing layout managers: Layout Manager Tutorial
  • If you do need to create a larger GUI, then override the public Dimension getPreferredSize() method in a smart way.
  • Create your JFrame, just as you are doing, in the main method
  • But do so in a Swing thread-safe way, on the Swing event thread, using SwingUtilities.invokeLater(...).
  • Study and learn from the Swing tutorials. You can find links to the Swing tutorials and to other Swing resources here: Swing Info.
  • Ignore Bala Yokesh Mani's suggestions and code. While he may mean well, he is offering bad examples, I'm afraid.
  • Avoid over-use of static fields and methods (as incorrectly shown in Bala Yokesh Mani's code) and instead do most work in the instance (non-static) domain.
  • Learn and use Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.

For example, your code could look something like:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.*;

@SuppressWarnings("serial")
// not really needed to extend JPanel here, but doing it
// for simplicity's sake
public class TestPanel1 extends JPanel {
    public static final int PREF_W = 640;
    public static final int PREF_H = 480;
    private JButton button1 = new JButton("B1");
    
    public TestPanel1() {
        JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
        topPanel.add(button1);
        
        // this is not the cleanest way to do this, but it is simple:
        setPreferredSize(new Dimension(PREF_W, PREF_H));
        
        setLayout(new BorderLayout());
        add(topPanel, BorderLayout.PAGE_START);        
    }
    
    public static void main(String[] args) {
        // use SwingUtilities to start the GUI on the event thread
        SwingUtilities.invokeLater(() -> {
            // create instance of our class
            TestPanel1 mainPanel = new TestPanel1();

            // create JFrame
            JFrame frame = new JFrame("Test 1");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            
            // add our instance to the JFrame
            frame.add(mainPanel);
            
            // pack the JFrame to activate layouts and to 
            // set sizes of all components and containers
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }

}

Then later if you wanted to add a background image, you could do so easily:

enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class TestPanel2 extends JPanel {
    public static final String IMG_PATH = "https://upload.wikimedia.org/"
            + "wikipedia/commons/thumb/e/ef/"
            + "Mesurupetala%2C_dragonfly%2C_Late_Late_Jurassic%2C_Tithonian_Age"
            + "%2C_Solnhofen_Lithographic_Limestone%2C_Solnhofen%2C_Bavaria"
            + "%2C_Germany_-_Houston_Museum_of_Natural_Science_-_DSC01817.JPG/"
            + "640px-thumbnail.jpg";
    private JButton button1 = new JButton("B1");
    private BufferedImage backgroundImg = null;
    
    public TestPanel2(BufferedImage bkgImg) {
        this.backgroundImg = bkgImg;
        
        JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
        topPanel.setOpaque(false);
        topPanel.add(button1);
        
        setLayout(new BorderLayout());
        add(topPanel, BorderLayout.PAGE_START);        
    }
    
    @Override
    public Dimension getPreferredSize() {
        Dimension originalSize = super.getPreferredSize();
        
        if (backgroundImg != null) {
            int w = Math.max(backgroundImg.getWidth(), originalSize.width);
            int h = Math.max(backgroundImg.getHeight(), originalSize.height);
            return new Dimension(w, h);
        } else {
            return super.getPreferredSize();
        }
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (backgroundImg != null) {
            g.drawImage(backgroundImg, 0, 0, null);
        }
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            BufferedImage img = null;
            try {
                URL imgUrl = new URL(IMG_PATH);
                img = ImageIO.read(imgUrl);
            } catch (IOException e) {
                e.printStackTrace();
                System.exit(-1);
            }
            
            TestPanel2 mainPanel = new TestPanel2(img);

            JFrame frame = new JFrame("Test");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(mainPanel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
-2

I have edited your code like below to make it display the button

import javax.swing.*;

public class Test {

    public Test() {   
        JFrame f = new JFrame(); 
        JButton b1 = new JButton("b1");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(null);
        f.setSize(925, 500);
        f.setVisible(true);
        b1.setBounds(0, 0, 125,100); 
        f.add(b1); 
    }

    public static void main(String[] args) {    
        new Test();
    }

}
  • 3
    (1-) Although this may work it is a poor example to build on. and breaks so many Swing coding practices. 1) a class should NOT extend JFrame and then create a JFrame. It should only create the frame in the main() method. 2) class names should start with an upper case character 3) don't use a null layout and setBounds() 4) don't use static variables for Swing components. The Swing tutorial provided far better examples to use as a starting point. – camickr Sep 21 '22 at 18:44
  • @camickr I have edited my answer as per your suggestions. But I am wondering why shouldn't we use null layout manager with setBounds(). Also why should we create frame only in `main()` method. Let me know if my answer still doesn't follow best practices. – Bala Yokesh Sep 22 '22 at 15:36
  • 2
    _I am wondering why shouldn't_ don't wonder, instead do some research (f.i. starting with the reference in the other answer ;) And please delete the incorrect example, future readers might get confused seeing both – kleopatra Sep 22 '22 at 15:51