How to fix component size in GridBagLayout for java swing

45 views Asked by At

I have been working on making a GUI interface for a game im working on. I decided to use java swing because it's just built into the language and there are a lot of tutorials online. Here is the design I sketched up to work from

The original draft

I started reading up and I realized I needed to use a GridBagLayout to get the format I wanted. The game runs entirely in text, so I decided I would just use text components for all the boxes and fetch the text from the game engine while having the GUI run separately on top. Originally I tried JLabels, but I had issues with linebreaks, alignment, etc. So, I thought JEditorPane's were what I needed, and I would just make them non-editable.

Here is what I got after a night of work:

The first attempt

This is pretty good and pretty close to what I want. There are still some issues with font I need to tweak, but that is just figuring out some numbers.

The main issue at the moment is the components resizing with the text. They seem to maintain a minimum size (how they look in the screenshot, unless they are given an empty string as text in which case the entire GUI breaks), but if they are given more text, they will stretch to accommodate it, even if they still have space for it. (or appear to at least)

this is mainly an issue for the middle block (what I have been calling the console log, and in code is named 'con'). Sometimes it will only display a single line of text, in which case the single line prints at the top with substantial whitespace (or blackspace) below it, but other times it will print several paragraphs, which will push it up to cover the other tree boxes, and even then its own text will be cutoff.

I did not show it clearly in the original sketch, but I imagined the console log simply printing the text in sequence, and as it fills the box it would push up, perhaps with a scrollbar to view the history.

I would really just be happy if someone can help me with fixing the size of the boxes, but if it is possible I would like to implement what I described in the above paragraph as well. I figure I must need to do something more involved, perhaps having every component in their own JPanel, which are then added to the global panel (called 'panel' in the code) in place of where I have their components now. This way, I could include a JScrollBar with con.

Here is my code (reduced for simplicity):

    public class Gui {

    private JFrame frame;
    private JEditorPane map;
    private JEditorPane status;
    private JEditorPane inventory;
    private JEditorPane con;
    private JTextField input;

    public Gui() {  
        frame = new JFrame();
        frame.setLayout(new BorderLayout(10,5));
        frame.setTitle("Test");
        frame.setPreferredSize(new Dimension(1000,800));
        frame.setResizable(false);
        frame.setUndecorated(true);

        JPanel panel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();

        map = new JEditorPane("plain", "");
        map.setEditable(false);
        map.setFont(new Font("Courier New", Font.PLAIN, 20));

        status = new JEditorPane("plain", "");
        status.setEditable(false);
        status.setFont(new Font("Courier New", Font.PLAIN, 10));

        inventory = new JEditorPane("plain", "");
        inventory.setEditable(false);
        inventory.setFont(new Font("Courier New", Font.PLAIN, 10));

        con = new JEditorPane("plain", "Welcome to EverDark!\nWould you like to load from file? (Y/N)");
        con.setEditable(false);
        con.setFont(new Font("Courier New", Font.PLAIN, 12));

        input = new JTextField("What do you do?");
        input.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(), BorderFactory.createLineBorder(DARK)));//to add margins to the textfield, doesnt work :(
        input.setFont(new Font("Courier New", Font.PLAIN, 12));

        input.addFocusListener(new FocusListener() {
                                        public void focusGained(FocusEvent e) {
                                            input.setText("");
                                        }
                                        public void focusLost(FocusEvent e) {
                                            input.setText("What do you do?");
                                        }   
                                    });
                                    
        input.addActionListener( ae -> update());

        add(map, panel, gbc, 0, 0, 1, 1, 0.5, 0.5);
        add(status, panel, gbc, 1, 0, 1, 1, 0.25, 0.5);
        add(inventory, panel, gbc, 2, 0, 1, 1, 0.25, 0.5);
        add(con, panel, gbc, 0, 1, 5, 1, 1, 0.49995);
        add(input, panel, gbc, 0, 2, 5, 1, 1, 0.005);

        panel.setBackground(GRAY);

        frame.add(panel, BorderLayout.CENTER);  
    }

    private void add(JComponent j, JPanel p, GridBagConstraints gbc, int x, int y, int width, int height, double weightx, double weighty) {
        j.setOpaque(true);
        j.setBackground(DARK);
        j.setForeground(Color.WHITE);
        gbc.insets = new Insets(5,5,5,5);
        gbc.fill = GridBagConstraints.BOTH;
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
        gbc.weightx = weightx;
        gbc.weighty = weighty;
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.gridwidth = width;
        gbc.gridheight = height;
        p.add(j, gbc);
    }

    public void show() {
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public void update(String feedback) {
        //fetches text for all the fields from the game engine
    }
}

TL;DR: how to fix component size in GridBagLayout

UPDATE: Managed to get what I was imagining MOSTLY working, and I recorded a video of me demoing it (recorded this for my friends but it shows mostly what I'm talking about anyways): https://www.youtube.com/watch?v=IKkjZXgZTX4

If there's anyway to stop this behaviour (the console log being small during character creation but then expanding afterwards), I'd like to hear it. I tried changing the weighty but it didn't do anything. I figure it's because the menu being drawn in the map field is pushing down, so I should just reduce the height of the menu, but maps come in various sizes in the game so I'd like a general fix to lock the size of the map field. Thanks :D

0

There are 0 answers