Results 1 to 13 of 13
  1. #1
    waterpolobro is offline Member
    Join Date
    May 2011
    Posts
    8
    Rep Power
    0

    Question Reccomended Layout?

    Alright, so I've made a Scrabble game and am trying to figure out the best layout possible for it.

    There's three graphics panels -- 1 for the game (it's about 600 pixels by 600 pixels) and 1 for each hand (each 210 x 30 pixels).

    In additions, there's a button to end your turn, and a panel with a set of radio buttons and label to turn tokens (a box that comes up with a letter's value when hovering over it) on or off.

    Finally there's a panel that contains two labels, one for each player's score in a grid layout (2 rows, 1 column).

    At the moment, everything is simply in a flowLayout since I was working on actually making the game work. Now that the games done, I want to make it look better; any recommendations for what type of layout(s) to use? I may want to add functionality to name each player, or make one player a computer (more radio buttons) later too.

    And on an unrelated note, when I first start the game only one of the panels for the hand paints; the other will not show until the first ends its turn. Can this be explained?

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    The layout tutorials will show you a visual representation of the layouts which will help you out. Also remember that layouts can effectively be nested by nesting JPanels, each using its own layout. Having said that, overall you will probably need a BorderLayout with the scrabble board held in the BorderLayout.CENTER position.

    Regarding your unrelated question -- it's hard to know what's wrong without code, but I wonder if you're adding components after packing your GUI and setting it visible.

  3. #3
    waterpolobro is offline Member
    Join Date
    May 2011
    Posts
    8
    Rep Power
    0

    Default Thanks

    I guess I'll look into the BorderLayout; I've never used anything other than Flow, Grid, and Box.

    For help figuring out the mysteriously invisible components:
    http://i51.tinypic.com/1zg585u.jpg <--- GUI when program is first run
    http://i51.tinypic.com/154dnph.jpg <--- GUI on third turn, and what it should essentially look like when it's first started

    And the code that creates the GUI:
    Java Code:
    f = new JFrame("Scrabble");
            f.setSize(700,800);
            f.setLayout(new FlowLayout());
            hp = new HandPanel();     
            hp2 = new HandPanel();
            hp2.reverseVisible();
            gp = new GamePanel(hp, hp2);
            
            f.addWindowListener(new WindowAdapter()
            {
                public void windowClosing(WindowEvent we)
                {
                    hp.end();
                    hp2.end();
                    gp.end();
                    System.exit(0);
                }
            });
            
            hp.setBoard(gp.getBoard());
            hp2.setBoard(gp.getBoard());
            f.add(hp);
            f.add(gp);
            f.add(hp2);
            hp.repaint();
            gp.repaint();
            hp2.repaint();
            
            endTurn = new JButton("End Turn");
            endTurn.setFocusable(false);
            endTurn.addActionListener(this);
            f.add(endTurn);
            
            JPanel scorePanel = new JPanel();
            scorePanel.setLayout(new GridLayout(2, 1, 5, 5));
            hpScore = new JLabel();
            hpScore.setText("Player 1 Score: " + hp.getScore());
            hp2Score = new JLabel();
            hp2Score.setText("Player 2 Score: " + hp2.getScore());
            scorePanel.add(hpScore);
            scorePanel.add(hp2Score);
            f.add(scorePanel);
            
            JPanel tokenOnOff = new JPanel();
            JLabel tokenLabel = new JLabel();
            tokenLabel.setText("Show Tokens:");
            tokenOnOff.add(tokenLabel);
            tOF = new JRadioButton[2];
            tOF[0] = new JRadioButton("On");
            tOF[1] = new JRadioButton("Off");
            ButtonGroup token = new ButtonGroup();
            for(int x=0; x<tOF.length; x++)
            {
                tOF[x].addActionListener(this);
                token.add(tOF[x]);
                tokenOnOff.add(tOF[x]);            
            }
            tOF[0].setSelected(true);
            f.add(tokenOnOff);
            
            f.setVisible(true);
    Could it have something to do with how HandPanel and GamePanel both implement runnable so there's essentially three threads running?

  4. #4
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

  5. #5
    waterpolobro is offline Member
    Join Date
    May 2011
    Posts
    8
    Rep Power
    0

    Default Yep

    I tried that when you mentioned it in your first post, but it had no effect on making the second "hand" paint and in fact made the GUI look worse since it put every component in the same line (due to the FlowLayout, I suppose). So I took it out again.

    I honestly have no clue why hp2 won't paint until it's that player's first turn.

  6. #6
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    The layouts won't work unless you tell them to work. The method pack does this, but also resizes the JFrame. The other method you should be familiar with is revalidate, and you should call this on any JComponent that has had components added to it, after the components have been added. You don't call this on a JFrame (which is not a JComponent) but on its contentPane which really is a JComponent/JPanel, but must be cast as such for it to work. So in other words, before calling f.setVisible(true), call

    Java Code:
    ((JPanel)f.getContentPane()).revalidate(); // tells the layout managers to do layouts.
    f.getContentPane().repaint();  // sometimes this is needed, esp. if components have been removed
    
    // now you can call
    f.setVisible(true);

  7. #7
    waterpolobro is offline Member
    Join Date
    May 2011
    Posts
    8
    Rep Power
    0

    Default Thanks Again

    Thanks; I'll keep that in mind when making GUIs in the future.

    However, adding those two lines in still doesn't solve the problem of the second set of letters not appearing right off the bat :confused:.

  8. #8
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Quote Originally Posted by waterpolobro View Post
    Thanks; I'll keep that in mind when making GUIs in the future.

    However, adding those two lines in still doesn't solve the problem of the second set of letters not appearing right off the bat :confused:.
    I think for further help you'll need to create and post a small compilable runnable program that has no program logic, but just creates a simple GUI but demonstrates the problem you're having, an SSCCE. Please check the link for details.

  9. #9
    waterpolobro is offline Member
    Join Date
    May 2011
    Posts
    8
    Rep Power
    0

    Default I Tried

    I've seen people asking for those in other posts so I attempted to create one, but I failed.

    It's weird because I can't emulate this problem in another program... obviously, if you look at the screenshots, there IS a problem.

    But when I basically copy and paste the code and gut it so there's no actual game and nothings happening when the mouse moves, all the components show up fine. Basically, I can't seem to make a SSCCE that emulates the problem because I haven't a fathom of a clue what the problem could even POSSIBLY be.

    Here's the SSCCE I attempted to make that ended up showing the components just fine:
    Java Code:
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    public class Engine implements ActionListener
    {  
        JFrame f;
        HandPanel hp;
        GamePanel gp;
        HandPanel hp2;
        JRadioButton[] tOF;
        JButton endTurn;
        JLabel hpScore;
        JLabel hp2Score;
        public static void main(String[] args)
        {
            Engine start = new Engine();
        }
        public Engine()
        {
            f = new JFrame("Scrabble");
            f.setSize(700,700);
            f.setLayout(new FlowLayout());
            hp = new HandPanel();     
            hp2 = new HandPanel();
            gp = new GamePanel(hp, hp2);
            
            f.addWindowListener(new WindowAdapter()
            {
                public void windowClosing(WindowEvent we)
                {
                    hp.end();
                    hp2.end();
                    gp.end();
                    System.exit(0);
                }
            });
            
            f.add(hp);
            f.add(gp);
            f.add(hp2);
            hp.repaint();
            gp.repaint();
            hp2.repaint();
            
            endTurn = new JButton("End Turn");
            endTurn.setFocusable(false);
            endTurn.addActionListener(this);
            f.add(endTurn);
            
            JPanel scorePanel = new JPanel();
            scorePanel.setLayout(new GridLayout(2, 1, 5, 5));
            hpScore = new JLabel();
            hpScore.setText("Player 1 Score: " + 0);
            hp2Score = new JLabel();
            hp2Score.setText("Player 2 Score: " + 0);
            scorePanel.add(hpScore);
            scorePanel.add(hp2Score);
            f.add(scorePanel);
            
            JPanel tokenOnOff = new JPanel();
            JLabel tokenLabel = new JLabel();
            tokenLabel.setText("Show Tokens:");
            tokenOnOff.add(tokenLabel);
            tOF = new JRadioButton[2];
            tOF[0] = new JRadioButton("On");
            tOF[1] = new JRadioButton("Off");
            ButtonGroup token = new ButtonGroup();
            for(int x=0; x<tOF.length; x++)
            {
                tOF[x].addActionListener(this);
                token.add(tOF[x]);
                tokenOnOff.add(tOF[x]);            
            }
            tOF[0].setSelected(true);
            f.add(tokenOnOff);
            
            ((JPanel)f.getContentPane()).revalidate(); // tells the layout managers to do layouts.
            f.getContentPane().repaint();  // sometimes this is needed, esp. if components have been removed
    
            f.setVisible(true);
        }
        public void actionPerformed(ActionEvent ae)
        {
        }
    }
     class HandPanel extends JPanel implements Runnable, MouseMotionListener, MouseListener
    {
    private Image dbImage;
    private int WIDTH = 210;
    private int HEIGHT = 30;
    private Graphics dbg;
    private boolean run;
        public HandPanel()
        {
            this.setMaximumSize(new Dimension(WIDTH, HEIGHT));
            this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
            this.setBackground(Color.white);
            this.setForeground(Color.black);
            run = true;
            Thread th = new Thread(this);
            th.start();
        }
        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            g.setColor(Color.white);
            g.fillRect(0,0,WIDTH,HEIGHT);
        }
        public void run()
        {
            while(run)
                this.repaint();
        }
        public void end()
        {
            run = false;
        }
        public void update (Graphics g)
        {
            if (dbImage == null)
            {
                dbImage = createImage (this.getSize().width, this.getSize().height);
                dbg = dbImage.getGraphics ();
            }
            dbg.setColor (getBackground ());
            dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);
            dbg.setColor (getForeground());
            paint(dbg);
            g.drawImage (dbImage, 0, 0, this);
        }
        public void mouseExited(MouseEvent me)
        {
        }
        public void mouseEntered(MouseEvent me)
        {}
        public void mousePressed(MouseEvent me)
        {
        }
        public void mouseClicked(MouseEvent me)
        {}
        public void mouseReleased(MouseEvent me)
        {
        }
        public void mouseMoved(MouseEvent me)
        {
        }
        public void mouseDragged(MouseEvent me)
        {
        }
    }
    
    class GamePanel extends JPanel implements Runnable, MouseMotionListener, MouseListener
    {
    public static final int WIDTH = 600;
    public static final int HEIGHT = 600;
    private Image dbImage;
    private HandPanel hp;
    private HandPanel hp2;
    private Graphics dbg;
    private boolean run;
        public GamePanel(HandPanel hp1, HandPanel hp2)
        {
            hp = hp1;
            this.hp2 = hp2;
            this.setMaximumSize(new Dimension(WIDTH, HEIGHT));
            this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
            this.setBackground(Color.white);
            this.setForeground(Color.black);
            run = true;
            Thread th = new Thread(this);
            th.start();
        }
        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            g.setColor(Color.white);
            g.fillRect(0, 0, WIDTH, HEIGHT);
        }
        public void end()
        {
            run = false;
        }
        public void run()
        {
            while(run)
                this.repaint();
        }
        public void update (Graphics g)
        {
            if (dbImage == null)
            {
                dbImage = createImage (this.getSize().width, this.getSize().height);
                dbg = dbImage.getGraphics ();
            }
            dbg.setColor (getBackground ());
            dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);
            dbg.setColor (getForeground());
            paint(dbg);
            g.drawImage (dbImage, 0, 0, this);
        }
        public void mouseMoved(MouseEvent me)
        {
        }
        public void mouseExited(MouseEvent me)
        {
        }
        public void mouseEntered(MouseEvent me)
        {}
        public void mousePressed(MouseEvent me)
        {
        }
        public void mouseClicked(MouseEvent me)
        {}
        public void mouseReleased(MouseEvent me)
        {
        }
        public void mouseDragged(MouseEvent me)
        {
        }
    }
    It's right in line with the actual program, except missing classes such as Letter, Tile, Board, etc. that solely have to do with the game. Nothing happens when mouse events are fired as well (unlike the actual game).

    And yet, no problem is produced when the above code is run.
    Last edited by waterpolobro; 05-08-2011 at 05:30 AM. Reason: just making last part make more sense

  10. #10
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,242
    Rep Power
    19

    Default

    1. Respect Swing's single threaded rule.
    Threads and Swing
    The Last Word in Swing Threads
    Lesson: Concurrency in Swing (The Java™ Tutorials > Creating a GUI With JFC/Swing)

    2. Don't call repaint() in a tight loop. You only need to call repaint() when there's a change of state. That can be accomplished by listeners.

    db

  11. #11
    waterpolobro is offline Member
    Join Date
    May 2011
    Posts
    8
    Rep Power
    0

    Default

    Already done; I had made a copy and deleted the threading earlier because I knew the threads were to be avoided if possible (apparently, avoided no matter what).

    Still doesn't fix the problem with the component not painting initially, and creates another problem I haven't tinkered with enough to bring up here.

  12. #12
    waterpolobro is offline Member
    Join Date
    May 2011
    Posts
    8
    Rep Power
    0

    Default

    HAHAHAHA... I finally figured it out.

    What was causing my problems is I named the boolean variable that causes the opposite hand to not draw (and draw a brown rectangle instead) "visible". Apparently, that overrode JPanel's "visible" boolean (at least that's my theory) and caused all sorts of screwy things to happen to the component. It didn't show up initially because the second HandPanel's visible value is initially set to false so the HandPanel is truly invisible; not just the hand's contents.

  13. #13
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,242
    Rep Power
    19

    Default

    First time I've seen anyone inadvertently change the visible property, but there have been a number of threads where a custom getX() / getY() resulted in the location of the component being changed, sometimes enough to place it outside the window.

    Glad your problem is solved.

    db

Similar Threads

  1. don't know the right layout
    By temyong in forum New To Java
    Replies: 4
    Last Post: 03-10-2011, 01:13 PM
  2. Please help me in this layout :(
    By orionorion in forum Java Applets
    Replies: 1
    Last Post: 02-09-2011, 02:47 PM
  3. Please Help me to do a layout
    By neway003 in forum AWT / Swing
    Replies: 3
    Last Post: 11-03-2010, 06:28 PM
  4. looking for a layout
    By imorio in forum AWT / Swing
    Replies: 3
    Last Post: 08-13-2010, 05:02 PM
  5. Edit layout Layout please help me
    By manhtungtnk28@gmail.com in forum New To Java
    Replies: 4
    Last Post: 11-23-2009, 08:41 AM

Posting Permissions

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