Jump to content

script GUI help needed


datpigeon

Recommended Posts

i've spent about 15 combined hours trying to figure out how to:

1.create a GUI in a format that i want (like this: https://imgur.com/a/xVeFC0L)

2.have the GUI open when i start the script

 

currently i have used IntellJ's GUI form builder thing to get the GUI to look like this: https://imgur.com/a/tt0HL3E and https://imgur.com/a/LWiLL8E but the code looks like this: https://imgur.com/a/TLOlkva

 

References I have used:

Creating GUI: IntellJ's GUI form builder, Eclipse with the windowbuilder plugin, and jvider

Tutorials: 

 

 

(some of them are for other bot clients)

Open Source Scripts:

https://github.com/ColPowell/OSBotScripting/tree/master/ChocolateBuyer/src/nezz/org/chocolatebuyer

https://bitbucket.org/Fluffee/ (you can see it if you look for it, and i know it's using another bot client)

https://github.com/apaec/aio-herblore/tree/master/src/uk/co/ramyun/herblore (doesn't have a GUI but has a UI)

 

 

Questions i would like answered:

1. Is there NO GUI builder that allows me to drag and drop elements (like JButton, JList, JTextField, etc.) onto the the application window AND IT STAYS WHERE I PUT IT (meaning i don't have to hard code the exact position of every single element i put into the GUI)

2. Assuming i should still be using IntellJ's GUI form builder, why is there no code about how i customized it in the form onto the output code file

3. How do i get the GUI to open in onStart

4. Why do ALL of the GUI tutorials i find on this site and youtube only deal with a simple fucking button that NOBODY WOULD EVER USE ANYWHERE or some extremely specific case and not an in depth explanation of how to use most if not all of the different elements you can put in a GUI

 

I've made 3 scripts that work very well that i would not like to show the source code since they all use methods i would not like to reveal

Link to comment
Share on other sites

1. Is there NO GUI builder that allows me to drag and drop elements (like JButton, JList, JTextField, etc.) onto the the application window AND IT STAYS WHERE I PUT IT (meaning i don't have to hard code the exact position of every single element i put into the GUI)
 (not sure if this'll fix your issue, pretty sure it will)
 - Change your content pane layout to absolute (null). (I use eclipse guibuilder, so i'm not too sure on the intelliJ version), you can just use the line mainPn1.setLayout(null);

2. Assuming i should still be using IntellJ's GUI form builder, why is there no code about how i customized it in the form onto the output code file
 - I don't use intelliJ so I can't answer this sorry

3. How do i get the GUI to open in onStart
 - I would create a "main" void, set the frame equal to a new instance of your PidgeonGUI class, set the frame to visible & then utilize it with PidgeonGUI.main();, this probably isn't the 'right' way to go about it, but I have a "if it works, why change it" mentality about smaller things like this.

lmk if any of these help

 

  • Like 1
Link to comment
Share on other sites

1 hour ago, Slut said:

3. How do i get the GUI to open in onStart
 - I would create a "main" void, set the frame equal to a new instance of your PidgeonGUI class, set the frame to visible & then utilize it with PidgeonGUI.main();, this probably isn't the 'right' way to go about it, but I have a "if it works, why change it" mentality about smaller things like this.

so i tried to that (i used run instead of main for the function name) and when i started the script, nothing happened at all.  Even the logger didn't even show that a script started and whenever i try to rebuild the project it says it can't delete the .jar file until i close that instance of the osbot client

here's my code
 

//in the main class

public class Main extends Script {

	private PigeonGUI gui = new PigeonGUI();
	private Settings s = new Settings();

	@Override
    public void onStart() throws InterruptedException {
        log("Starting Script");
        gui.run(s);
    }

	@Override
	public int onLoop() throws InterruptedException {
		if (!gui.isVisible()) {
			//bot code here
			return random(200, 600);
		}
		return random(200, 600);
	}
}


//in the GUI class

public class PigeonGUI extends JFrame {
	//GUI code here
	
	public void run(Settings settings) {
        JFrame frame = new PigeonGUI();
        frame.setVisible(true);
    }
}

i have 2 return statements in onLoop and one shouldn't be there but the script doesn't even get past onStart to get there so it isn't a problem

Edited by datpigeon
Link to comment
Share on other sites

17 hours ago, datpigeon said:

so i tried to that (i used run instead of main for the function name) and when i started the script, nothing happened at all.  Even the logger didn't even show that a script started and whenever i try to rebuild the project it says it can't delete the .jar file until i close that instance of the osbot client

here's my code
 


//in the main class

public class Main extends Script {

	private PigeonGUI gui = new PigeonGUI();
	private Settings s = new Settings();

	@Override
    public void onStart() throws InterruptedException {
        log("Starting Script");
        gui.run(s);
    }

	@Override
	public int onLoop() throws InterruptedException {
		if (!gui.isVisible()) {
			//bot code here
			return random(200, 600);
		}
		return random(200, 600);
	}
}


//in the GUI class

public class PigeonGUI extends JFrame {
	//GUI code here
	
	public void run(Settings settings) {
        JFrame frame = new PigeonGUI();
        frame.setVisible(true);
    }
}

i have 2 return statements in onLoop and one shouldn't be there but the script doesn't even get past onStart to get there so it isn't a problem

	/*
	 *  in your main onStart() use PidgeonGUI.main();
	 */
	static PidgeonGUI frame;
	public static void main() {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					frame = new PidgeonGUI();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	
	public PidgeonGUI() {
		// gui code here
		mainPn1.setLayout(null);
	}


Modifying the template my GUI Builder gives would be this.

Link to comment
Share on other sites

1. DO NOT use absolute positioning (null layout), it's harder to maintain, and can easily looked fucked up on different systems with different configurations.
2. DO NOT use GUI designers/builders, they produce bad code which is hard to maintain, and often is not the best way to build the GUI. You also cannot achieve more advanced things if you're using a builder. Another good reason to do it "by hand", is so that you actually know what you are doing, you will learn nothing from a GUI builder.

3. Look at https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html5iP7AZ0.png, by combining these layout managers in nested JPanels you can easily achieve your desired GUI

Here is an example using the GridBagLayout: https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html#gridbag

gui2.PNG.9396ab511a3a40ac30fae2cb059b61b0.PNG

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;

import static java.awt.GridBagConstraints.HORIZONTAL;
import static java.awt.GridBagConstraints.NONE;

public class GUI {

    private final JFrame jFrame;

    public GUI() {
        jFrame = new JFrame("Pigeon GUI");

        JPanel mainPanel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        jFrame.setContentPane(mainPanel);
        mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10));

        JLabel titleLabel = new JLabel("Pigeon GUI");
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 4;
        gbc.insets = new Insets(0, 10, 20, 10);
        mainPanel.add(titleLabel, gbc);

        JLabel nameLabel = new JLabel("Name:");
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(0, 0, 0, 5);
        mainPanel.add(nameLabel, gbc);

        JTextField nameField = new JTextField(20);
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(0, 0, 0, 0);
        mainPanel.add(nameField, gbc);

        JScrollPane whitelistScrollPane = new JScrollPane();
        JList<String> whitelist = new JList<>();
        whitelistScrollPane.add(whitelist);
        gbc.gridx = 2;
        gbc.gridy = 1;
        gbc.ipadx = 200;
        gbc.ipady = 200;
        gbc.gridwidth = 2;
        gbc.insets = new Insets(10, 10, 0, 10);
        mainPanel.add(whitelistScrollPane, gbc);

        JButton insertButton = new JButton("Insert");
        gbc.gridx = 2;
        gbc.gridy = 2;
        gbc.fill = HORIZONTAL;
        gbc.weightx = 0.5;
        gbc.gridwidth = 1;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.insets = new Insets(10, 10, 0, 10);
        mainPanel.add(insertButton, gbc);

        JButton deleteButton = new JButton("Delete");
        gbc.gridx = 3;
        gbc.gridy = 2;
        gbc.fill = HORIZONTAL;
        gbc.weightx = 0.5;
        gbc.gridwidth = 1;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.insets = new Insets(10, 10, 0, 10);
        mainPanel.add(deleteButton, gbc);

        JButton startButton = new JButton("Start");
        gbc.gridwidth = 4;
        gbc.gridx = 0;
        gbc.gridy = 3;
        gbc.fill = NONE;
        gbc.insets = new Insets(20, 10, 0, 10);
        mainPanel.add(startButton, gbc);

        jFrame.pack(); // resize the JFrame so that all the components are at or above their preferred sizes
        jFrame.setLocationRelativeTo(null); // center the gui on screen
    }

    public void open() {
        jFrame.setVisible(true);
    }

    public void close() {
        jFrame.setVisible(false);
        jFrame.dispose();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new GUI().open());
    }
}



Here is another example purely using nested JPanels with BorderLayout and FlowLayouts.

 

gui.PNG.7597d413aa388f8da7d820a54682a071.PNG

 

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;

public class GUI {

    private final JFrame jFrame;

    public GUI() {
        jFrame = new JFrame("Pigeon GUI");

        // We want to split the GUI into three sections, title at the top, inputs in the middle, start button at the bottom
        // To do this we use a BorderLayout: https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html#border
        JPanel mainPanel = new JPanel(new BorderLayout());
        mainPanel.setPreferredSize(new Dimension(500, 400));
        jFrame.setContentPane(mainPanel); // use this panel as the main content panel for the GUI

        // Create a JPanel to contain the title. Here we use a FlowLayout https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html#flow
        // We set the alignment to FlowLayout.CENTER so the title appears in the middle.
        JPanel titlePanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        titlePanel.setBorder(new EmptyBorder(5, 5, 5, 5)); // We give the JPanel an empty border of 5px, so that there is some padding
        JLabel titleLabel = new JLabel("Pigeon GUI");
        titlePanel.add(titleLabel);
        mainPanel.add(titlePanel, BorderLayout.NORTH); // Add the title to the North side of the main panel

        // Create a JPanel to contain the main GUI inputs (textfield and whitelist)
        JPanel inputsPanel = new JPanel(new BorderLayout());

        // Create a JPanel to contain the name label and name input
        JPanel namePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        namePanel.setBorder(new EmptyBorder(10, 10, 10, 10));
        JLabel nameLabel = new JLabel("Name:");
        namePanel.add(nameLabel);
        JTextField nameField = new JTextField(20);
        namePanel.add(nameField);
        inputsPanel.add(namePanel, BorderLayout.WEST);

        // Create a JPanel to contain the whitelist and buttons
        JPanel whitelistPanel = new JPanel(new BorderLayout());
        whitelistPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
        inputsPanel.add(whitelistPanel, BorderLayout.EAST);

        // Create a JScrollPane to contain the whitelist
        // Add the JScrollPane to the whitelistpanel above
        JScrollPane whitelistScrollPane = new JScrollPane();
        JList<String> whitelist = new JList<>();
        whitelistScrollPane.add(whitelist);
        whitelistPanel.add(whitelistScrollPane, BorderLayout.CENTER);

        // Create a JPanel to contain the whitelist buttons
        JPanel whitelistButtons = new JPanel(new FlowLayout(FlowLayout.CENTER));
        JButton insertButton = new JButton("Insert");
        whitelistButtons.add(insertButton);
        JButton deleteButton = new JButton("Delete");
        whitelistButtons.add(deleteButton);
        whitelistPanel.add(whitelistButtons, BorderLayout.SOUTH);

        mainPanel.add(inputsPanel, BorderLayout.CENTER); // Add the inputs panel to the centre of the main panel

        // Crete a JPanel to contain the start button
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        buttonPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        JButton startButton = new JButton("Start");
        buttonPanel.add(startButton);
        mainPanel.add(buttonPanel, BorderLayout.SOUTH); // Add the button panel to the south of the main panel

        jFrame.pack(); // resize the JFrame so that all the components are at or above their preferred sizes
        jFrame.setResizable(false);
        jFrame.setLocationRelativeTo(null); // center the gui on screen
    }

    public void open() {
        jFrame.setVisible(true);
    }

    public void close() {
        jFrame.setVisible(false);
        jFrame.dispose();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new GUI().open());
    }
}

 

Edited by Explv
  • Like 2
  • Boge 1
Link to comment
Share on other sites

Quote

 

1. Is there NO GUI builder that allows me to drag and drop elements (like JButton, JList, JTextField, etc.) onto the the application window AND IT STAYS WHERE I PUT IT (meaning i don't have to hard code the exact position of every single element i put into the GUI)

2. Assuming i should still be using IntellJ's GUI form builder, why is there no code about how i customized it in the form onto the output code file

3. How do i get the GUI to open in onStart

4. Why do ALL of the GUI tutorials i find on this site and youtube only deal with a simple fucking button that NOBODY WOULD EVER USE ANYWHERE or some extremely specific case and not an in depth explanation of how to use most if not all of the different elements you can put in a GUI

 

  1. GUI builders let you pick which layout you want to use. This is important. A null layout will require you to specify the size and position of every component, whereas other layouts (GridBagLayout, BoxLayout, FlowLayout) automatically arrange your components, but you get to specify how they're arranged. You should write your own GUIs from scratch so you can build your GUIs exactly how you need them to be.
  2. I've never used that builder, so no comment.
  3. You're welcome.
  4. You're using a GUI builder. Why would somebody make an advanced tutorial for you when you're not going to learn the how's/why's of the actual underlying code?
  • Like 1
Link to comment
Share on other sites

5 hours ago, liverare said:
  1. GUI builders let you pick which layout you want to use. This is important. A null layout will require you to specify the size and position of every component, whereas other layouts (GridBagLayout, BoxLayout, FlowLayout) automatically arrange your components, but you get to specify how they're arranged. You should write your own GUIs from scratch so you can build your GUIs exactly how you need them to be.
  2. I've never used that builder, so no comment.
  3. You're welcome.
  4. You're using a GUI builder. Why would somebody make an advanced tutorial for you when you're not going to learn the how's/why's of the actual underlying code?

yeah i have looked at your GUI implementing tutorial, but i have never done anything dealing with atomic variables in my cs classes so far.  I would like to understand what im doing when i make anything rather than copy pasting or half understanding what is going on, but if nothing else works in this thread ill give it try.

Link to comment
Share on other sites

6 hours ago, Explv said:

1. DO NOT use absolute positioning (null layout), it's harder to maintain, and can easily looked fucked up on different systems with different configurations.
2. DO NOT use GUI designers/builders, they produce bad code which is hard to maintain, and often is not the best way to build the GUI. You also cannot achieve more advanced things if you're using a builder. Another good reason to do it "by hand", is so that you actually know what you are doing, you will learn nothing from a GUI builder.

3. Look at https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html5iP7AZ0.png, by combining these layout managers in nested JPanels you can easily achieve your desired GUI

i'm assuming it would be a better idea to use a GUI designer until i understand what each of the layouts do and what should go where, but ill use your snippets as a guide in the future, thanks!

Link to comment
Share on other sites

@Explv So i tried your GUI snippet (the GridBagLayout) and i tried to add actions to the buttons on the GUI but i keep getting a null pointer exception on the 18th line (in insertButtonActionPerformed, whitelist.setModel(dm)) and i was hoping you could tell me what i was doing wrong.  Would it be a better idea to put the event handlers in the main class like how liverare's tutorial shows or keep them there?

here's my code:
 

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;

import static java.awt.GridBagConstraints.HORIZONTAL;
import static java.awt.GridBagConstraints.NONE;

public class PigeonGUI {

    private final JFrame jFrame;
    DefaultListModel dm = new DefaultListModel();

    private void insertButtonActionPerformed(ActionEvent e) {
        if(nameField.getText() != null) {
            dm.addElement(nameField.getText());
            nameField.setText(null);
            whitelist.setModel(dm);
        }
    }

    private void deleteButtonActionPerformed(ActionEvent e) {
        if (whitelist.getSelectedValue() != null) {
            dm.removeElementAt(whitelist.getSelectedIndex());
            whitelist.setModel(dm);
        }
    }

    private void startButtonActionPerformed(ActionEvent e) {
        this.close();
    }


    public PigeonGUI() {
        jFrame = new JFrame("Pigeon GUI");

        mainPanel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        jFrame.setContentPane(mainPanel);
        mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10));

        titleLabel = new JLabel("Pigeon GUI");
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 4;
        gbc.insets = new Insets(0, 10, 20, 10);
        mainPanel.add(titleLabel, gbc);

        nameLabel = new JLabel("Name:");
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(0, 0, 0, 5);
        mainPanel.add(nameLabel, gbc);

        nameField = new JTextField(20);
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(0, 0, 0, 0);
        mainPanel.add(nameField, gbc);

        whitelistScrollPane = new JScrollPane();
        JList<String> whitelist = new JList<>();
        whitelistScrollPane.add(whitelist);
        gbc.gridx = 2;
        gbc.gridy = 1;
        gbc.ipadx = 200;
        gbc.ipady = 200;
        gbc.gridwidth = 2;
        gbc.insets = new Insets(10, 10, 0, 10);
        mainPanel.add(whitelistScrollPane, gbc);

        insertButton = new JButton("Insert");
        insertButton.addActionListener(e -> insertButtonActionPerformed(e));
        gbc.gridx = 2;
        gbc.gridy = 2;
        gbc.fill = HORIZONTAL;
        gbc.weightx = 0.5;
        gbc.gridwidth = 1;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.insets = new Insets(10, 10, 0, 10);
        mainPanel.add(insertButton, gbc);

        deleteButton = new JButton("Delete");
        deleteButton.addActionListener(e -> deleteButtonActionPerformed(e));
        gbc.gridx = 3;
        gbc.gridy = 2;
        gbc.fill = HORIZONTAL;
        gbc.weightx = 0.5;
        gbc.gridwidth = 1;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.insets = new Insets(10, 10, 0, 10);
        mainPanel.add(deleteButton, gbc);

        startButton = new JButton("Start");
        startButton.addActionListener(e -> startButtonActionPerformed(e));
        gbc.gridwidth = 4;
        gbc.gridx = 0;
        gbc.gridy = 3;
        gbc.fill = NONE;
        gbc.insets = new Insets(20, 10, 0, 10);
        mainPanel.add(startButton, gbc);

        jFrame.pack(); // resize the JFrame so that all the components are at or above their preferred sizes
        jFrame.setLocationRelativeTo(jFrame.getOwner()); // center the gui on bot client
    }

    //test variables
    private JPanel mainPanel;
    private JLabel titleLabel;
    private JLabel nameLabel;
    private JTextField nameField;
    private JScrollPane whitelistScrollPane;
    private JList<String> whitelist;
    private JButton insertButton;
    private JButton deleteButton;
    private JButton startButton;
    //end test variables


    public void open() {
        jFrame.setVisible(true);
    }

    public void close() {
        jFrame.setVisible(false);
        jFrame.dispose();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new PigeonGUI().open());
    }
}

 

Link to comment
Share on other sites

2 hours ago, datpigeon said:

@Explv So i tried your GUI snippet (the GridBagLayout) and i tried to add actions to the buttons on the GUI but i keep getting a null pointer exception on the 18th line (in insertButtonActionPerformed, whitelist.setModel(dm)) and i was hoping you could tell me what i was doing wrong.  Would it be a better idea to put the event handlers in the main class like how liverare's tutorial shows or keep them there?


You don't need to call setModel after adding elements to the model.

Just set the model once like so:
 

ListModel<String> model = new DefaultListModel<>();
JList<String> whitelist = new JList<>(model);
model.addElement("Whatever");


Event handlers are fine where you have put them. However, talking purely from a style perspective, the constructor should be the first function in the class, and the member variables should be above the constructor.
 

Edited by Explv
  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...