0

I have a basic gui (it doesn't need to look pretty, it just needs to work. It's a gui to display several algorithms I'm implementing for my thesis.) but the checkboxes and button won't show up randomly. Sometimes they appear, sometimes they don't. I honestly have no clue why this could be happening and I'm pretty scrub at swing, so I'm lost.

EDIT: Here's what i want my gui to look like:

enter image description here

//import java.awt.*;
import java.awt.Dimension;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.*;

import javax.swing.ButtonGroup;

import javax.swing.*;  //notice javax
public class MapWindowController extends JFrame implements ActionListener, ItemListener
{
    private static final int WIDTH = 600, HEIGHT = 800;
    private static final int SETTINGS_WIDTH = 600, SETTINGS_HEIGHT = 200;
    private static final int NUM_MAP_TYPE = 2;
    private static final int NUM_ALGORITHM_TYPE = 4;
    private static final int MAP_IMAGE_SIZE = 400, ACTUAL_MAP_SIZE = 10;


    private JButton run;
    private JCheckBox[] map_type;
    private JCheckBox[] algorithm_type;
    JPanel panel = new JPanel();
    JPanel settings_panel = new JPanel();
    MapView map_view = new MapView(MAP_IMAGE_SIZE);
    SettingsButtonsPanel settings = new SettingsButtonsPanel();

    MapModel map_model = new MapModel(ACTUAL_MAP_SIZE, map_view);

    ButtonGroup bgMap;
    ButtonGroup bgAlgorithm;

    public MapWindowController()
    {

        setLocationRelativeTo(null);
        setTitle("HPA* Test");
        setSize(WIDTH, HEIGHT);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        add(panel);
        panel.setBounds(0, 0, 600, 800);
        panel.setLayout(null);
        /*GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 0;*/
        instantiateSettingsPanel();
        //panel.add(settings);
        /*c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 1;*/

        panel.add(map_view);
        map_view.setBounds(0,200,600,600);
        //button_panel.setBounds(0,0);
        map_view.repaint();

    }

    public void instantiateSettingsPanel() {
        settings_panel.setLayout(new GridBagLayout());

        GridBagConstraints c = new GridBagConstraints();

        //this.setLayout(null);

        map_type = new JCheckBox[NUM_MAP_TYPE];

        map_type[0] = new JCheckBox("Sparse");
        map_type[0].setSelected(true);

        map_type[1] = new JCheckBox("Maze");
        map_type[1].setSelected(false);

        algorithm_type = new JCheckBox[NUM_ALGORITHM_TYPE];

        algorithm_type[0] = new JCheckBox("A*");
        algorithm_type[0].setSelected(true);

        algorithm_type[1] = new JCheckBox("HPA*");
        algorithm_type[1].setSelected(false);

        algorithm_type[2] = new JCheckBox("TA*");
        algorithm_type[2].setSelected(true);

        algorithm_type[3] = new JCheckBox("PTHPA*");
        algorithm_type[3].setSelected(false);

        bgMap = new ButtonGroup( );
        bgAlgorithm = new ButtonGroup( );



        settings_panel.setMaximumSize(new Dimension(600,200));
        for(int i = 0; i < NUM_MAP_TYPE; i++)
        {
            bgMap.add(map_type[i]);
            map_type[i].addItemListener(this);
            c.fill = GridBagConstraints.HORIZONTAL;
            c.gridx = 0;
            c.gridy = i+1;
            settings_panel.add(map_type[i], c);
        }

        for(int i = 0; i < NUM_ALGORITHM_TYPE; i++)
        {
            bgAlgorithm.add(algorithm_type[i]);
            algorithm_type[i].addItemListener(this);
            c.fill = GridBagConstraints.HORIZONTAL;
            c.gridx = 1;
            c.gridy = i+1;
            settings_panel.add(algorithm_type[i], c);
        }

        run = new JButton("Run");
        run.addActionListener(this);
        settings_panel.add(run);
        panel.add(settings_panel);
        settings_panel.setBounds(0,0,SETTINGS_WIDTH,SETTINGS_HEIGHT);
    }

    public void itemStateChanged(ItemEvent e)
    {
        Object source = e.getItemSelectable();
        //if(source == )
    }

    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();

        String algorithm = "A*";
        String map = "Sparse";
        for(int i = 0; i < algorithm_type.length; i++) {
            if(algorithm_type[i].isSelected()) {
                algorithm = algorithm_type[i].getText();
                break;
            }
        }

        for(int i = 0; i < map_type.length; i++) {
            if(map_type[i].isSelected()) {
                map = map_type[i].getText();
                break;
            }
        }

        if(source == run) {
            if(map.equals("Sparse")) 
                map_model.createRandomObstaclesSparse(10, 1);
            else
                map_model.createRandomObstaclesMaze(1);
            map_model.startPathfinding(algorithm, 0, true);
            map_view.setMapScale(ACTUAL_MAP_SIZE);
            map_view.setMapModel(map_model);
        }
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
zaloo
  • 879
  • 3
  • 13
  • 27
  • 3
    `panel.setLayout(null);` this is a good indication of the source of your problems... – MadProgrammer Mar 23 '14 at 23:19
  • I didn't want to use a layout, what's wrong with that? – zaloo Mar 23 '14 at 23:21
  • 1
    Many, Swing was designed to operate with listeners, so all the event notifications about changes to hierarchy are linked to the layout managers so they know when they should update themselves. You can't predict how your UI might be rendered on different platforms, meaning that the UI that works on your machine won't work (or look the same) on others... – MadProgrammer Mar 23 '14 at 23:24
  • So what kind of layout should I use? The majority of the screen is taken up by a "map" and the top 1/4th is just buttons – zaloo Mar 23 '14 at 23:26
  • In this case, I might be tempted to write my own, but I can't see what it is you are trying to achieve... – MadProgrammer Mar 23 '14 at 23:30
  • Edited my post to show you what i want the gui to look like – zaloo Mar 23 '14 at 23:45
  • 1
    Java GUIs might have to work on a number of platforms, on different screen resolutions & using different PLAFs. As such they are not conducive to exact placement of components. To organize the components for a robust GUI, instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556), along with layout padding & borders for [white space](http://stackoverflow.com/q/17874717/418556). **To specifics** I would use a combination of `Borderlayout` for the main GUI. A `JTextArea` with a large `EmptyBorder` for the `CENTER` with another `JPanel` for buttons.. – Andrew Thompson Mar 24 '14 at 00:05
  • .. the panel containing the buttons would have a different layout, depending on how you would like them arranged within that area. – Andrew Thompson Mar 24 '14 at 00:06

1 Answers1

5

Your first mistake is using a null layout, your second mistake is calling setVisible before the UI is completed.

Your basic idea is sound, separating the various areas of responsibility into separate components, this will make you life much easier.

Basically, I used a GridBagLayout as it allows you to define fill weights for each component, providing a 1/4 of the vertical space to the buttons and the remainder to the map...

Map

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class MapWindowController extends JFrame implements ActionListener, ItemListener {

    private static final int WIDTH = 600, HEIGHT = 800;
    private static final int SETTINGS_WIDTH = 600, SETTINGS_HEIGHT = 200;
    private static final int NUM_MAP_TYPE = 2;
    private static final int NUM_ALGORITHM_TYPE = 4;
    private static final int MAP_IMAGE_SIZE = 400, ACTUAL_MAP_SIZE = 10;

    private JButton run;
    private JCheckBox[] map_type;
    private JCheckBox[] algorithm_type;
    JPanel content = new JPanel();
    JPanel settings_panel = new JPanel();
    private JPanel mapPane = new JPanel(new BorderLayout());

    ButtonGroup bgMap;
    ButtonGroup bgAlgorithm;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                new MapWindowController();
            }
        });
    }

    public MapWindowController() {

        setLocationRelativeTo(null);
        setTitle("HPA* Test");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        content.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.weighty = 0.25;
        gbc.weightx = 1;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        content.add(settings_panel, gbc);
        gbc.gridy++;
        gbc.weighty = 0.75;
        content.add(mapPane, gbc);

        try {
            mapPane.add(new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("/Map.png")))));
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        add(content);
        /*GridBagConstraints c = new GridBagConstraints();
         c.fill = GridBagConstraints.HORIZONTAL;
         c.gridx = 0;
         c.gridy = 0;*/
        instantiateSettingsPanel();
        //panel.add(settings);
        /*c.fill = GridBagConstraints.HORIZONTAL;
         c.gridx = 0;
         c.gridy = 1;*/

        pack();
        setLocationByPlatform(true);
        setVisible(true);


    }

    public void instantiateSettingsPanel() {
        settings_panel.setLayout(new GridBagLayout());

        GridBagConstraints c = new GridBagConstraints();

        //this.setLayout(null);
        map_type = new JCheckBox[NUM_MAP_TYPE];

        map_type[0] = new JCheckBox("Sparse");
        map_type[0].setSelected(true);

        map_type[1] = new JCheckBox("Maze");
        map_type[1].setSelected(false);

        algorithm_type = new JCheckBox[NUM_ALGORITHM_TYPE];

        algorithm_type[0] = new JCheckBox("A*");
        algorithm_type[0].setSelected(true);

        algorithm_type[1] = new JCheckBox("HPA*");
        algorithm_type[1].setSelected(false);

        algorithm_type[2] = new JCheckBox("TA*");
        algorithm_type[2].setSelected(true);

        algorithm_type[3] = new JCheckBox("PTHPA*");
        algorithm_type[3].setSelected(false);

        bgMap = new ButtonGroup();
        bgAlgorithm = new ButtonGroup();

        settings_panel.setMaximumSize(new Dimension(600, 200));
        for (int i = 0; i < NUM_MAP_TYPE; i++) {
            bgMap.add(map_type[i]);
            map_type[i].addItemListener(this);
            c.fill = GridBagConstraints.HORIZONTAL;
            c.gridx = 0;
            c.gridy = i + 1;
            settings_panel.add(map_type[i], c);
        }

        for (int i = 0; i < NUM_ALGORITHM_TYPE; i++) {
            bgAlgorithm.add(algorithm_type[i]);
            algorithm_type[i].addItemListener(this);
            c.fill = GridBagConstraints.HORIZONTAL;
            c.gridx = 1;
            c.gridy = i + 1;
            settings_panel.add(algorithm_type[i], c);
        }

        run = new JButton("Run");
        run.addActionListener(this);
        settings_panel.add(run);
    }

    public void itemStateChanged(ItemEvent e) {
        Object source = e.getItemSelectable();
        //if(source == )
    }

    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();

        String algorithm = "A*";
        String map = "Sparse";
        for (int i = 0; i < algorithm_type.length; i++) {
            if (algorithm_type[i].isSelected()) {
                algorithm = algorithm_type[i].getText();
                break;
            }
        }

        for (int i = 0; i < map_type.length; i++) {
            if (map_type[i].isSelected()) {
                map = map_type[i].getText();
                break;
            }
        }

        if (source == run) {
//            if (map.equals("Sparse")) {
//                map_model.createRandomObstaclesSparse(10, 1);
//            } else {
//                map_model.createRandomObstaclesMaze(1);
//            }
//            map_model.startPathfinding(algorithm, 0, true);
//            map_view.setMapScale(ACTUAL_MAP_SIZE);
//            map_view.setMapModel(map_model);
        }
    }
}

Don't use setSize of setBounds on a window, instead, use pack to automatically set the optimal size of the window based on it's contents preferred size.

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366