Search code examples
javaswingjframelayout-manager

java - Setting Buttons and TextAreas at locations


So I've been looking at other solutions to this problem, but it seems that none of them help at all. Can someone help me?

Code:

public static void main(String[] args) {

    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // Container cont = frame.getContentPane();
    JPanel buttonpanel = new JPanel();
    JButton[] button = new JButton[12];
    JTextArea score1, score2;
    score1 = new JTextArea(100, 200);
    score2 = new JTextArea(100, 200);

    frame.setSize(800, 600);
    frame.setVisible(true);
    score1.setLayout(null);
    score1.setBackground(Color.BLUE);
    score2.setLayout(null);
    score2.setBackground(Color.RED);

    score1.setLocation(0, 100);
    score2.setLocation(700, 100);

    frame.add(score1);

    for (int i = 0; i < button.length / 2; i++) {
        button[i].setBounds(100 * (i + 1), 100, 100, 100);
        button[i].setBackground(Color.GRAY);
        buttonpanel.add(button[i]);
    }

    frame.add(buttonpanel);

    frame.add(score2);

    // frame.add(panel);
}

It just gives me window completely blue.


Solution

  • You're seeing all blue because you're adding score1, an all blue JTextArea to the JFrame's contentPane, a container that uses a BorderLayout, and this makes the JTextArea fill the contentPane, leaving nothing but blue. Nothing else is added because the NullPointerException that is caused by your using a JButton array that is filled with nulls. Once you fix this bug (which you never told us about), you'll see nothing but red because of the same issue.

    The best solution, which you've undoubtedly read about is to use layout managers to the best advantage to create your GUI. 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.

    Other problems:

    • You're calling setVisible(true) on your JFrame before adding anything to it which is backwards. You want to make this call after everything has been added, so that it will show in the JFrame when it is displayed.
    • You're setting the layout of a JTextArea which doesn't make sense since you'll never want to use these as containers for other components.
    • Also understand that this isn't doing what you think it's doing: JTextArea(100, 200);. You're not creating a JTextArea that is 100 by 200 pixels but rather is 100 rows by 200 columns which is one amazingly huge JTextArea. You'll want to read the documentation, the API when using unfamiliar components.
    • You state, "So I've been looking at other solutions to this problem, but it seems that none of them help at all." Likely the "other solutions" have recommended that you use layout managers, and rather than state that they don't "help at all", you should instead strive to learn how to use these tools since those other solutions are correct.
    • And yeah, you're trying to use JButtons in a JButton array that have not yet been created. Understand that an array of reference type, such as an array of JButton is initially filled with nothing but null references, similar to an empty carton of eggs. Just like you can't use any eggs from the carton until you put eggs in there, you can't use an JButtons in your array before you've placed them in there. In the for loop where you iterate through the array, create each JButton item on the top line: button[i] = new JButton("Something");

    You can find links to the Swing tutorials and to other Swing resources here: Swing Info

    For example, you tell me which is easier to debug, your code, or this code:

    import java.awt.BorderLayout;
    import java.awt.GridLayout;
    import javax.swing.*;
    
    public class Foo2 extends JPanel {
       private static final String[] BUTTON_TEXTS = { "A", "B", "C", "D", "E", "F",
             "G", "H", "I", "J", "K", "l" };
       private static final int GAP = 3;
       private JTextArea textArea1 = new JTextArea(20, 30);
       private JTextArea textArea2 = new JTextArea(20, 30);
    
       public Foo2() {
          JPanel textAreaGrid = new JPanel(new GridLayout(1, 0, GAP, GAP)); // gridlayout 1 row
          textAreaGrid.add(new JScrollPane(textArea1));
          textAreaGrid.add(new JScrollPane(textArea2));
    
          JPanel buttonPanel = new JPanel(new GridLayout(2, 0, GAP, GAP)); // 2 rows
          for (String btnText : BUTTON_TEXTS) {
             buttonPanel.add(new JButton(btnText));
          }
    
          setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
          setLayout(new BorderLayout(GAP, GAP)); // main GUI uses border layout
          add(textAreaGrid, BorderLayout.CENTER);
          add(buttonPanel, BorderLayout.PAGE_END);
       }
    
       private static void createAndShowGui() {
          Foo2 mainPanel = new Foo2();
    
          JFrame frame = new JFrame("Foo2");
          frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
          frame.getContentPane().add(mainPanel);
          frame.pack();
          frame.setLocationByPlatform(true);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }
    

    Which displays as:

    enter image description here