0

I am new to JFrame and I am having problems with the layout in NetBean, how to solve this layout problem? I tried to resize, but the position of the elements will become mess. I am trying to display each detail to the specified text areas . Am i using the wrong layout or my coding are having problems? help...><

This is my output now This is my output

And this is the output i want This is the output i want

These are my codings :

public class PokemonJournal extends JFrame
    implements ActionListener {

JTextArea FirstName = new JTextArea(1, 10);
JTextArea LastName = new JTextArea(1, 10);
JTextArea Level = new JTextArea(1, 10);
JTextArea Gender = new JTextArea(1, 10);
JButton showPokemon = new JButton("Show");
JButton showRaid = new JButton("Show");
JButton showPokestop = new JButton("Show");
DBHandler db = new DBHandler();
ImageIcon image = new ImageIcon("p1.jpg");
JLabel imageLabel = new JLabel(image);

public static void main(String[] args) {
    PokemonJournal jf = new PokemonJournal();
}

public PokemonJournal() {
    setLayout(new FlowLayout());
    setSize(300, 600);
    setTitle("              Pokemon Journal         ");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
    setLocationRelativeTo(null);
    setResizable(false);

    JPanel top = new JPanel();
    add("north", top);
    top.add(new Label("Pokemon Journal"));

    JPanel side = new JPanel();
    add("West", side);
    side.setLayout(new GridLayout());
    side.add(imageLabel);

    JPanel line1 = new JPanel();
    add("center", line1);
    line1.setLayout(new GridLayout());
    line1.add(new Label("First Name :"));
    line1.add(FirstName);

    JPanel line2 = new JPanel();
    add("Center", line2);
    FirstName.setEditable(false);
    line2.setLayout(new GridLayout());
    line2.add(new Label("Last Name   :"));
    line2.add(LastName);
    LastName.setEditable(false);

    JPanel line3 = new JPanel();
    add("Center", line3);
    line3.setLayout(new GridLayout());
    line3.add(new Label("Level      :"));
    line3.add(Level);
    Level.setEditable(false);

    JPanel line4 = new JPanel();
    add("Center", line4);
    line4.setLayout(new GridLayout());
    line4.add(new Label("Gender  : "));
    line4.add(Gender);
    Gender.setEditable(false);

    JPanel line5 = new JPanel();
    add("Center", line5);
    line5.setLayout(new GridLayout());
    line5.add(new Label("Pokemon Caught:"));
    line5.add(showPokemon);

    JPanel line6 = new JPanel();
    add("Center", line6);
    line6.setLayout(new GridLayout());
    line6.add(new Label("Raid Won:"));
    line6.add(showRaid);

    JPanel line7 = new JPanel();
    add("Center", line7);
    line7.setLayout(new GridLayout());
    line7.add(new Label("Pokestop visited:"));
    line7.add(showPokestop);

}
Frakcool
  • 10,915
  • 9
  • 50
  • 89

1 Answers1

2

Am i using the wrong layout or my coding are having problems?

Well, yes, a little, but it has more to do with the size of your JFrame, never call setSize() on them, instead call pack(). However if you change it for pack(), the default orientation of the FlowLayout is FlowLayout.HORIZONTAL and thus all your components will go to the right of each other.

Then, you have 2 options:

  1. Keep the JFrame's layout as FlowLayout but make two JPanels, one for the image and one for the data, the image might have the default FlowLayout as well but the other one might have GridLayout.

  2. Use GridBagLayout for all your components, letting the image JLabel to have a height of 7 cells and all the others a height of 1.

For the following example I will be using the GridBagLayout option, and I recommend you to try to make the multipanel option (option 1).

However, before starting I must mention your other problems in your code:

  • You're not following the Java naming conventions: firstWordLowerCaseVariable, firstWordLowerCaseMethods(), FirstWordUpperCaseClasses, ALL_WORDS_UPPER_CASE_CONSTANTS, this will make your code easier to read and understand for you and for us.

  • You're not changing the behavior of the JFrame so, there's no need to inherit from it: See Extends JFrame vs. creating it inside the program for more information.

  • Related to the above point, it's wise to build your GUI towards JPanels instead of JFrames, see: The Use of Multiple JFrames: Good or Bad Practice? as well, as I think you might end up in similar problems in the future.

  • You're not placing your program on the Event Dispatch Thread (EDT), see this related answer to see how to solve this problem.

  • You're calling setSize(...) method, and as I said before, it's always better to call pack() method instead, leaving the calculations for the GUI size to the layout manager.

  • You're calling setVisible before adding all your components to the GUI, this could lead you to blank or black screens, it should be the last line in your program.

  • Related to the above point, I always like to start doing the GUI from inside out and adding the items that way, instead of outside in.

  • Why are you using JTextAreas instead of JTextFields for the user information?

Now, the code that follows the above recommendations using the 2nd option I gave you is this:

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.net.MalformedURLException;
import java.net.URL;

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.SwingUtilities;

public class PokemonJournal {
    private JFrame frame;
    private JPanel pane;
    private GridBagConstraints gbc;
    private JLabel imageLabel;
    private JLabel firstName;
    private JLabel lastName;
    private JLabel level;
    private JLabel gender;
    private JLabel pokemonCaught;
    private JLabel raidWon;
    private JLabel pokestopVisited;
    private JTextField nameField;
    private JTextField lastNameField;
    private JTextField levelField;
    private JTextField genderField;
    private JButton pokemonCaughtButton;
    private JButton raidWonButton;
    private JButton pokestopVisitedButton;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new PokemonJournal()::createAndShowGui);
    }

    private void createAndShowGui() {
        frame = new JFrame(getClass().getSimpleName());
        pane = new JPanel();
        pane.setLayout(new GridBagLayout());

        gbc = new GridBagConstraints();

        imageLabel = new JLabel();
        try {
            imageLabel.setIcon(new ImageIcon(
                    new URL("http://pm1.narvii.com/6535/1b362404d09091a335ce53fa68506827418890a3_128.jpg")));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        firstName = new JLabel("First Name: ");
        lastName = new JLabel("Last Name: ");
        level = new JLabel("Level: ");
        gender = new JLabel("Gender: ");
        pokemonCaught = new JLabel("Pokemon Caught: ");
        raidWon = new JLabel("Raid Won: ");
        pokestopVisited = new JLabel("Pokestop Visited: ");

        nameField = new JTextField(10);
        lastNameField = new JTextField(10);
        levelField = new JTextField(10);
        genderField = new JTextField(10);

        pokemonCaughtButton = new JButton("Show");
        raidWonButton = new JButton("Show");
        pokestopVisitedButton = new JButton("Show");

        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridheight = 7;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.insets = new Insets(5, 5, 5, 5);

        pane.add(imageLabel, gbc);

        gbc.gridx = 1;
        gbc.gridheight = 1;
        pane.add(firstName, gbc);

        gbc.gridx = 2;
        pane.add(nameField, gbc);

        gbc.gridx = 1;
        gbc.gridheight = 1;
        gbc.gridy++;
        pane.add(lastName, gbc);

        gbc.gridx = 2;
        pane.add(lastNameField, gbc);

        gbc.gridx = 1;
        gbc.gridheight = 1;
        gbc.gridy++;
        pane.add(level, gbc);

        gbc.gridx = 2;
        pane.add(levelField, gbc);

        gbc.gridx = 1;
        gbc.gridheight = 1;
        gbc.gridy++;
        pane.add(gender, gbc);

        gbc.gridx = 2;
        pane.add(genderField, gbc);

        gbc.gridx = 1;
        gbc.gridheight = 1;
        gbc.gridy++;
        pane.add(pokemonCaught, gbc);

        gbc.gridx = 2;
        pane.add(pokemonCaughtButton, gbc);

        gbc.gridx = 1;
        gbc.gridheight = 1;
        gbc.gridy++;
        pane.add(raidWon, gbc);

        gbc.gridx = 2;
        pane.add(raidWonButton, gbc);

        gbc.gridx = 1;
        gbc.gridheight = 1;
        gbc.gridy++;
        pane.add(pokestopVisited, gbc);

        gbc.gridx = 2;
        pane.add(pokestopVisitedButton, gbc);

        frame.add(pane);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

And it produces a GUI similar to this one:

enter image description here

Frakcool
  • 10,915
  • 9
  • 50
  • 89
  • ohh i see, looks like i still have plenty things to learn haha. I will learn from my mistakes. Thanks for your advises,it helped me a lot :D – Lin Chee Wei Oct 20 '17 at 04:53
  • I am using text areas because they are for details displaying instead of letting the users to input. – Lin Chee Wei Oct 20 '17 at 05:04
  • What you mean by "details displaying"? It's the same, you can call `setEnabled(false)` on the `JTextField` – Frakcool Oct 20 '17 at 05:07
  • displaying data from the access database, is it possible to add one big text area below like in my expected output? like when i press the show buttons, the details are displayed accordingly in there, i had tried to add one with your coding, but the size of the buttons and text fields will be changed, and the text area just filled the area after the picture. These are my codings : ` gbc.gridx = 1; gbc.gridheight = 1; gbc.gridy++; pane.add(showDetails,gbc);` – Lin Chee Wei Oct 20 '17 at 06:33
  • @LinCheeWei I'm not going to add the new text área in this answer, if you want you can ask a new question and post a [mcve] there explaining what you want to achieve and what you've tried. This is a Q&A site and this question has been already solved. But yes, it is possible to display data from the data base. Your expected output is confusing it seems like two different windows – Frakcool Oct 20 '17 at 13:26