Results 1 to 3 of 3
  1. #1
    Mate de Vita is offline Member
    Join Date
    Mar 2012
    Posts
    60
    Rep Power
    0

    Default Swing GUI Interaction between components

    I am creating a simple GUI for the 24 game (in short, a game where you get 4 random numbers, and you have to make an expression with them that equals 24). Now I've gone through the basics of swing and a lot of the tutorials on specific swing components, but there has, at least so far, been very little mention of how to put all of it together.
    I'm guessing, since this is very basic stuff, that there is a template or something to tell us how components and the frame/content pane should be related in the program.
    This is an abbreviated version of my design:

    Java Code:
    public class Main {
        public static void main (String[] args) {
            SwingUtilities.invokeLater (new Runnable() {
                public void run() {
                    createGUI();
                }
            });
        }
        
        private static void createGUI() {
            try {
                UIManager.setLookAndFeel (UIManager.getSystemLookAndFeelClassName());
            }
            catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
                e.printStackTrace();
            }
            
            JFrame frame = new JFrame ("24 Game");
            frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
            
            frame.setContentPane (new MainPanel());
            
            frame.pack();
            frame.setLocationRelativeTo (null);
            frame.setVisible (true);
        }
    }
    
    public class MainPanel extends JPanel {               //the main panel of the program - where all the components will be layed out
        NumberButtonPanel numberButtonPanel = new NumberButtonPanel();
        OperatorButtonPanel operatorButtonPanel = new OperatorButtonPanel();
        ExprTextArea exprTextArea = new ExprTextArea();
        
        MainPanel() {                            //there's actually some layout stuff in here as well, and also a few other components, but this is enough to give you the general idea
            add (numberButtonPanel);                 //the component that displays the 4 numbers you got as buttons
            add (operatorButtonPanel);               //the component that displays the available operators
            add (exprTextArea);                         //the component that displays the expression you are building with the numbers and operators
            
            restart();
        }
        
        public void restart() {                    //resets all the components of the program (skipping the ones that don't need to be reset)
            numberButtonPanel.reset();
            exprTextArea.reset();
        }
    }
    
    public class NumberButtonPanel extends JPanel implements ItemListener {
        public static final int NUM_BUTTONS = 4;
        public static final int GOAL_RESULT = 24;
        public static final int DEF_RANGE = 9;
        private int range;
        
        NumberButtonPanel() {
            super (new GridLayout (0,2));       //displays the number buttons in two collumns (with 4 numbers in a 2x2 square)
            range = DEF_RANGE;
            for (int i = 0; i < NUM_BUTTONS; i++) add (new NumberButton());
        }
    
    
        public void itemStateChanged (ItemEvent e) {                         //when a button is clicked, its corresponding number is appended to the expression text area
            NumberButton source = (NumberButton)e.getSource();
            if (e.getStateChange() == ItemEvent.SELECTED) ExprTextArea.append (source.getText());    //!!!
            //some other stuff
        }
        
        private class NumberButton extends JToggleButton {
            private NumberButton() {
                super();
            }
            //some other stuff
        }
        
        public void setRange (int range) throws IllegalArgumentException {
            if (/*something*/) this.range = range;
            else throw new IllegalArgumentException ("Invalid range specified.");
        }
        public int getRange() {return range;}
        
        public void reset() {               //resets this panel by resetting the numbers on the buttons
            Random generator = new Random();
            for (Component a : this.getComponents()) ((NumberButton)a).setText (Integer.toString (generator.nextInt (range) + 1));
            deselectAll();
        }
        
        public int[] getNumbers() {              //returns the current numbers on the panel
            int[] result = new int[NUM_BUTTONS];
            NumberButton button = null;
            int i = 0;
            for (Component a : this.getComponents()) {
                button = (NumberButton)a;
                result[i++] = Integer.valueOf (button.getText());
            }
            return result;
        }
        
        public void deselectAll() {               //deselects all buttons on the panel
            for (Component a : this.getComponents()) ((NumberButton)a).setSelected (false);
        }
    }
    
    public class OperatorButtonPanel extends JPanel {
        public static final String[] ALLOWED_OPERATORS = {"+", "-", "/", "*"};
    
        OperatorButtonPanel() {
            super();
            add (new Operators());
            //add some other stuff
        }
        
        private class Operators extends JPanel implements ActionListener {
            private Operators() {
                super (new GridLayout (ALLOWED_OPERATORS.length,1));        //lays out all buttons in a single column
                
                for (String operator : ALLOWED_OPERATORS) {
                    JButton button = new JButton (operator);
                    button.addActionListener (this);
                    add (button);
                }
            }
    
            public void actionPerformed (ActionEvent e) {           //when a button is pressed, its corresponding operator is appended to the expression text area
                JButton source = (JButton)e.getSource();
                ExprTextArea.append (source.getText());     //!!!
            }
        }
    }
    
    public class ExprTextArea extends JTextArea {
        ExprTextArea() {
            super (1, 25);
        }
        
        public void reset() {
            setText ("");
        }
        
        public void clear() {
            setText ("");
            NumberButtonPanel.deselectAll();     //!!!
        }
    
        public void append (String s) {
            setText (getText() + s);
        }
    }
    Now the problem I'm having is the calls to methods belonging to another component (marked with !!!), as they are static calls to non-static methods. My guess is that there is a certain convention as to how interaction like this is supposed to be designed.
    One possibility would be to make all my component classes singletons, and simply call the methods on the instances of those singletons.
    Another possibility would be to call those methods indirectly by going through the component container (in this case the MainPanel).

    I'm sure there are other possible solutions here, but my question I guess is, is there a certain conventional design model that I should follow for such interaction between components of a swing GUI?

  2. #2
    KevinWorkman's Avatar
    KevinWorkman is offline Crazy Cat Lady
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    3,874
    Rep Power
    8

    Default Re: Swing GUI Interaction between components

    There isn't a convention per se, but I think you're asking more about general Object Oriented practices than specific Swing coding.

    I would start with something much smaller. Make a JFrame that contains 2 JButtons. Click either one of the buttons disables itself and enables the other.

    When you have that little program, you'll have a nice little template to follow for adding more components and interactions.

    Keep in mind that each JButton can have its own ActionListener, or you can check what the source of the ActionEvent is.
    How to Ask Questions the Smart Way
    Static Void Games - Play indie games, learn from game tutorials and source code, upload your own games!

  3. #3
    Mate de Vita is offline Member
    Join Date
    Mar 2012
    Posts
    60
    Rep Power
    0

    Default Re: Swing GUI Interaction between components

    Fair enough, I'll do that. Thanks for the answer.

Similar Threads

  1. some swing components are not displaying
    By mDennis10 in forum AWT / Swing
    Replies: 6
    Last Post: 01-27-2012, 09:26 AM
  2. Swing components are not well-displayed
    By Josep_16 in forum AWT / Swing
    Replies: 1
    Last Post: 08-21-2011, 02:37 AM
  3. binding swing components
    By furqankhan in forum Advanced Java
    Replies: 1
    Last Post: 06-25-2010, 12:08 PM
  4. Problem In Swing Components
    By SANDY_INDIA in forum AWT / Swing
    Replies: 1
    Last Post: 07-19-2008, 10:23 PM
  5. How to print Swing components
    By Java Tip in forum java.awt
    Replies: 0
    Last Post: 06-22-2008, 11:04 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •