I have a Jframe that contains a JPanel which has a label that I use as a background image and a second JPanel that I want to add my controls into. I am attempting to add and position labels dynamically. I can add the labels but they all appear at the top of the second JLabel eventhough I have set location to be towards the bottom. Here is my code.

package Game;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 *
 * @author Henry Sanders
 */
public class BJTable extends javax.swing.JFrame {

    Image img;

    /**
     * Creates new form BJTable
     */
    public BJTable() {
        this.setPreferredSize(new Dimension(800, 600)); // **** note change
        this.setTitle("Henderson Games - Blackjack");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel TableLayout = new PicturePanel();

        Toolkit kit = Toolkit.getDefaultToolkit();
        img = kit.getImage("C:\\Users\\Henry Sanders\\Pictures\\cards_jpg\\Blackjack Table.jpg");
        img = img.getScaledInstance(785, -1, Image.SCALE_SMOOTH);

        //Construct Componts to add to panel
        //Construct Labels
        JPanel Controls = new JPanel();
        Controls.setPreferredSize(new Dimension(800, 600));
        Controls.setOpaque(false);
        JLabel jLabel4 = new JLabel();
        JLabel jLabel5 = new JLabel();
        JLabel jLabel6 = new JLabel();
        JLabel jLabel7 = new JLabel();
        JLabel jLabel8 = new JLabel();
        jLabel4.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/Chip_$1.jpg")));
        jLabel5.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/Chip_$5.jpg")));
        jLabel6.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/Chip_$25.jpg")));
        jLabel7.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/Chip_$100.jpg")));
        jLabel8.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/Chip_$500.jpg")));

        //Add Componts to panel
        //Add Labels
        Controls.add(jLabel4);
        jLabel4.setLocation(166, 488);
        Controls.add(jLabel5);
        Controls.add(jLabel6);
        Controls.add(jLabel7);
        Controls.add(jLabel8);

        //Add JPanels to frame
        TableLayout.add(Controls);
        add(TableLayout);

        pack();  // **** added

        setVisible(true);
        SetCenter();
        initComponents();
    }

    private void SetCenter() {
        // Get the size of the screen
        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();

        // Determine the new location of the window
        int w = this.getSize().width;
        int h = this.getSize().height;
        int x = (dim.width - w) / 2;
        int y = (dim.height - h) / 2;

        // Move the window
        this.setLocation(x, y);
    }

    private class PicturePanel extends JPanel {

        // **** this method should be paintComponent, not paint
        public void paintComponent(Graphics g) {
            //  **** don't forget to call the super method first
            super.paintComponent(g);
            g.drawImage(img, 0, 0, this);
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setMinimumSize(new java.awt.Dimension(800, 600));
        setPreferredSize(new java.awt.Dimension(800, 600));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 800, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 600, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;

                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(BJTable.class
                    .getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(BJTable.class
                    .getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(BJTable.class
                    .getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(BJTable.class
                    .getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new BJTable().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    // End of variables declaration                   
}

I have tried for several days to get this going so any and all help is appreciated.

Recommended Answers

All 23 Replies

Simply placing components on top of each other in an ordinary JFrame doesn't work. There are (at least) two ways to put controls over a background image:
1. Subclass JPanel and override paintComponent to draw the background image directly into the JPanel
2. USe a JLayeredPane to place your controls explicitly on top of the JLabel that has the background ImageIcon

With either method, if you have a problem with the positioning of the controls, that's to do with your layout manager, not the background image.

I tried using 2 layeredPanes 1 to hold the background image and the other for the controls. I could't get my controls to show on top of the background. I just used the drag and drop method for the controlsso I have no code to post. I'm new to java and moving from vb6 so if you could give me to an example point me to one. Thanks

Also what layout do you recomend since some of these controls will be overlapping others (as in when the cards are dealt). Labels will be the controls that will be added dynamically.

With overlapping controls JLayeredPane is the way to go. You use just ONE layered pane, put enerything in that and use the depth variables to define which things overlap in front of which.

ps: This sounds like one of those very rare cases where none of the standard layout managers in going to let you position everything just right, so maybe you would be better off using a null layout manager and positioning/sizing everything with setBounds

I can't figure out what I'm doing wrong, although I'm sure it's something simple.

`package Game;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;


public class BJTable extends javax.swing.JFrame {

    Image img;

    public BJTable() {
        this.setPreferredSize(new Dimension(800, 600)); // **** note change
        this.setTitle("Henderson Games - Blackjack");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Creates a Panel(BGHolder) to hold a Label(BGImage)which will hold the Image for the BackGround.
        JPanel BGHolder = new JPanel();
        BGHolder.setPreferredSize(new Dimension(800, 600));
        BGHolder.setVisible(true);
        BGHolder.setLayout(null);

        //Creates Label(BGImage) to hold Backgrond Image
        JLabel BGImage = new JLabel();
        BGImage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/Blackjack Table.jpg")));
        BGImage.setBounds(0, 0, 797, 600);
        BGImage.setVisible(true);
        BGImage.setOpaque(false);

        //Creates JLayeredPane(CHolder) to hold a panel(Controls) to hold the dynamically created labels
        JLayeredPane CHolder = new JLayeredPane();
        CHolder.setBounds(0, 0, 800, 600);
        CHolder.setOpaque(false);

        //Creates JPanel(Controls) to hold the dynamically created labels
        JPanel Controls = new JPanel();
        Controls.setBounds(0, 0, 800, 600);
        Controls.setOpaque(false);

        JLabel jLabel4 = new JLabel();
        jLabel4.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/Chip_$1.jpg")));

        //Add Componts to panel
        //Add Labels
        Controls.add(jLabel4);
        jLabel4.setLocation(166, 488);
        jLabel4.setVisible(true);
        jLabel4.setFocusCycleRoot(true);

        //Add JPanels to frame        
        BGHolder.add(BGImage);
        BGHolder.add(CHolder);
        CHolder.add(Controls);
        add(BGHolder);

        pack();

        setVisible(true);
        SetCenter();
        initComponents();
    }

    private void SetCenter() {
        // Get the size of the screen
        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();

        // Determine the new location of the window
        int w = this.getSize().width;
        int h = this.getSize().height;
        int x = (dim.width - w) / 2;
        int y = (dim.height - h) / 2;

        // Move the window
        this.setLocation(x, y);
    }

    private class PicturePanel extends JPanel {

        // **** this method should be paintComponent, not paint
        public void paintComponent(Graphics g) {
            //  **** don't forget to call the super method first
            super.paintComponent(g);
            g.drawImage(img, 0, 0, this);
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setMinimumSize(new java.awt.Dimension(800, 600));
        setPreferredSize(new java.awt.Dimension(800, 600));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 800, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 600, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;

                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(BJTable.class
                    .getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(BJTable.class
                    .getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(BJTable.class
                    .getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(BJTable.class
                    .getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new BJTable().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    // End of variables declaration                   
}`

Now I cant see my control(jLabel4) to tell if it is being placed correctly. I'm stumped on this issue. I have seen something about z order but don't know how or where to implement it. HELP ME PLEASE!!!????

That's got too complicated - you seem to have kept code from each approach you have tried, and it's all in there muddled together. It's definitely time to start again with an empty file and just copy over things as you determine that you need them.
Remmeber, just one panel - a JLayeredPane - put the JLabel with the imageicon at the back and the other controls in front of it. Use setBounds to position and size things to overlap properly.
See the Oracle tutorial that explains exactly how to do it, with examples:
http://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html

I studied the tutorial you suggested but it's not for someone new to java. I downloaded the sample and it was even more confusing with all the jumping around and creating the various aspects of the program. This is what I came up with,

import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

public class BJTableLayered extends javax.swing.JFrame {

    /**
     * Creates new form BJTableLayered
     */
    public BJTableLayered() {

        initComponents();

        JLayeredPane BJGame = new JLayeredPane();//Create the Pane to hold the background image
        BJGame.setPreferredSize(new Dimension(800, 600));//Set the size of the pane
        BJGame.setOpaque(true);
        BJGame.setBackground(Color.yellow);
        BJGame.setVisible(true);
        BJGame.setLayout(null);

        JLabel BGImage = new JLabel();// Create label for background image
        BGImage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/Blackjack Table.jpg")));//Set image in the label
        BGImage.setPreferredSize(new Dimension(800, 600));//Set the size of the label
        BGImage.setVisible(true);

        this.add(BJGame);       
        BJGame.add(BGImage);

        this.setContentPane(BJGame);
        pack();

    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setMinimumSize(new java.awt.Dimension(800, 600));
        setPreferredSize(new java.awt.Dimension(800, 600));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 800, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 600, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(BJTableLayered.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(BJTableLayered.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(BJTableLayered.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(BJTableLayered.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new BJTableLayered().setVisible(true);
            }
        });
    }

Still can't get it to load the label with the backgroung image. I did try: BJGame.add(BGImage, 0); .Thinking that 0 would set the layer and there was no change. Just a 800 x 600 yellow screen. FOR GOD'S SAKE throw me a bone. I'm stuck and don't know how to get over this wall.

OK
You have to master all the material in that tutorial if you want to work with overlapping ojects. I know it's not easy, but programming isn't easy. Just sit somewhere quiet and work through it one step at a time.
I said twice: do not use a layout manager for overlapping objects, use setBounds instead.
Using a GUI drawing tool is a major mistake here. It's not going to give you the results you want, but it is going to confuse you. Stop using it; just type the code yourself so you understand and control it yourself. Start with the first example of the tutorial as a template.

Right, your plea has melted my heart. Here's the simplest eg I can come up with. It adds a background label (z coordinate 0) (just solid yellow, but could be image), and two overlapping labels in front of it at z-coodintes 10 and 20. Swap the 10 and 20 to swap which one is in front.

import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;

public class Layers {

   public static void main(String[] args) {

        JLayeredPane p = new JLayeredPane();
        p.setPreferredSize(new Dimension(300, 200));

        JLabel back = new JLabel();
        back.setOpaque(true); 
        back.setBackground(Color.YELLOW);
        back.setBounds(0, 0, 300, 200);
        p.add(back, new Integer(0));

        JLabel a = new JLabel("this is a");
        a.setOpaque(true);
        a.setBackground(Color.RED);
        a.setBounds(20,20,80,20);
        p.add(a,new Integer(10));

        JLabel b = new JLabel("this is b");
        b.setForeground(Color.BLUE);
        b.setBounds(30,30,80,20);
        p.add(b,new Integer(20));

        JFrame frame = new JFrame("Close this to exit application");
        frame.add(p);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
   }
}

Well God bless, so the whole issue all along is that I have been using the IDE to create my frame and layeredpane and trying to code in everthing else. Where I have to code in everything. Well back to the drawing(typing) board to apply the lesson of the day. Thanks for the advice. I SHALL MAKE YOU PROUD!

IDE screen designers are fine for data entry forms and the like, but hopeless for artistic or visually-excting games. You'll also see alot of advice here saying that it's better to learn how it all works by writing and debugging your own code first. Otherwize the generated code never stops being a mystery

BAMM!!!! I think I got it now.

import javax.swing.*;

import java.awt.*;

/**
 *
 * @author Henry S.
 */
public class MyLayer extends JPanel {

    private JLabel back;
    private JLabel lblChip;
    private JLayeredPane Pane;
    private int[] Denom = {1, 5, 25, 100, 500};

    public MyLayer() {

        ImageIcon backGround = createImageIcon("/Images/Blackjack Table.jpg");

        //Create and set up the layered pane.
        Pane = new JLayeredPane();
        Pane.setPreferredSize(new Dimension(800, 600));
        Pane.setLayout(null);

        //Create the JLabel for the background image and add the image.
        back = new JLabel(backGround);
        back.setOpaque(true);
        back.setBounds(0, 0, 800, 600);
        back.setVisible(true);
        Pane.add(back, new Integer(0));

        //Labels for $1.00 to $500.00 Chip Images.
        Point origin = new Point(166, 488);
        int offset = 100;

        for (int i = 0; i < Denom.length; i++) {
            int Val = Denom[i];
            ImageIcon Chip = createImageIcon("/Images/Chip_$" + Val + ".jpg");
            lblChip = new JLabel(Chip);
            lblChip.setOpaque(true);
            lblChip.setBounds(origin.x += offset, origin.y, 32, 33);
            lblChip.setVisible(true);
            Pane.add(lblChip, new Integer(1));
        }

        add(Pane);
    }

    private static void createAndShowGUI() {

        //Create and set up the window.
        JFrame frame = new JFrame("My Layered Pane Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        JComponent ContentPane = new MyLayer();
        ContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(ContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);
    }

    public static void main(String[] args) {

        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

    protected static ImageIcon createImageIcon(String path) {
        java.net.URL imgURL = MyLayer.class.getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }
}

I know I still have much to learn. Sure glad there are guys like yourself who are willing and able to help. Thank you for all of your help.

Excellent! Glad to help.

One tiny bit of feedback - you explicity but unneccessarily set a few things that are the default values or inappropriate anyway:

layered panes have a null layout manager by default.

all the setVisibles except one are redundant - those components are all visible by default except for the JFrame.

setOpaque(true) for an image JLabel is pointless if the image itself is not transparent. If you do have (partly) transparent images then you definitely do NOT want setOpaque(true) for the JLabel that contains it.

... and (another) final observation...

You are using Swing - the current standard for cross-platform Java GUIs, but as of Java 8 Oracle are starting to push JavaFX as a replacement for Swing, especially in highly-graphical applications. It's certainly far ahead of Swing for anything multi-media or animated. I don't know how quickly the Java Swing development population will re-train (if ever), but it may be worth a look, depending on where you want to take this application.

I will get on correcting that right away.

As for my app, I don't plan to have much animation. This is my first java program outside of some tutorial samples but not my first computer program as I was using VB4,VB6 and VB.Net. We both know these things are never done so who knows what the future may hold as far as animation and such.

... in which case I'd ignore JavaFX for now. J

The code to add all the controls to the Pane has gotten really long. Is there a way to create a seperate class that creates and adds the controls to the Pane, call it from the MyLayer method. I still have a lot of code to put in and I would like to keep the code in the main form as simple as possible. I will continue researching the issue, but any assitance is appreciated.

That's a common problem with Swing (or any other powerful GUI toolset), and there isn't any good solution. An IDE with code folding helps when you are editing the code.
You can certainly put it all in a method in the same class, but if you use a different class then you have to worry about accessing all the variables for the different components in the GUI. If that's not too serious a problem then you can create a subclass of JPanel (or layered pane etc) that implements all the content, and in your main form just add a new one of those.

When I'm doing this for real I usually create a JPanel subclass containing all the contents, then provide a public interface in terms of the logic rather than the presentation, thus keeping all the actual JComponents private. Eg: Its a roulette application - I may have stuff like

class RouletteTable extends JPanel {
    public RouletteTable() {...
    public void showBet(int amount, Place p) {
       // enum Place is a number, colour. odd/even etc
       // may display piles of chips in the right place tec
       ...
    public int spinWheel() {
       // animated, retunrns final result

Note that this does very complicated and beautiful graphics, but it knows nothing about the processes of a game of roulette... it just displays what it's told to display.

Now I can program the logic and flow of a game, and use RouletteTable without knowing anything about its graphics...

    RouletteTable rt = new RouletteTable();
    frame.add(rt);
    ...
    playOneGame() {
       rt.showBet(100, ROUGE);
       int number = rt.spinWheel();
       if (number ... // who won, who lost?
       rt.clearBets();
       ...

By separating the responsibilities in this way I can work on the long and tedious graphics code in isolation, then I can completely forget about that while I get on with programming the game.

So a BJTable.java that builds the table then a BJGame.java that calls for a new BJTable()?

Yes, for a start. Don't be afraid to create new classes to organise your code.
Eg: You may have a game with a highly graphical display of the game in progress, plus a number of buttons that the user uses to start/play/end the game. I would think of having classes like:
GameDisplay extends JPanel - the graphical display (see previous post)
ButtonPanel - the buttons and their action listeners
GameLogic - the current state of the game and an implementation of its rules
GameMaster - has the main method, creates a GameLogic and a JFrame with a GameDisplay and a ButtonPanel.

Any time you can separate out a coherent chunk of code that has limited interaction with the rest of the program, you should consider separating and packaging it in a separate class/java file. Remmeber also that programs grow - what starts as a small class will grow to medium, and what starts as a big class will become unmanagable

I wish I had posted this in a new discussion. This info my also be useful to others. Is there a way you can move it to a new thread?

A bit too late for that now, but I've updated the title to reflect the new content. J.

This discussion is now being continued in its own thread. See here

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.