0

I want to be able to dynamically add new 60x80 images that will act as buttons to open new frames. However, for some odd reason my createFrame() method fails to add any type of component into the jpanel. I've been trying to fix the issue for a few hours now and I'm not sure what's wrong. I've tried adding plain panels, labels, buttons... but nothing is working. My main JPanel will use FlowLayout for all the images and my main JFrame uses BorderLayout, that way I can position another specific content JPanel under the main one later on.

Here's my code (includes revalidate() as of my edit, which fixed it):

package testit;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.border.LineBorder;

class TestIt extends JFrame  implements ActionListener {
    //Main window frame and content panel
    private JFrame main_frame;
    private JPanel main_panel;

    //Screen size variable
    private Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();

    public TestIt() {            
        //Set up the main frame
        main_frame = new JFrame("Test Program");
        main_frame.setLayout(new BorderLayout());
        main_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        main_frame.setIconImage(
             new ImageIcon("src/testit/resources/img/app_icon.gif").getImage());

        //Set up the inner content panel
        main_panel = new JPanel();
        main_panel.setLayout(new FlowLayout());
        main_panel.setPreferredSize(
             new Dimension((screen.width / 10) * 6,(screen.height / 10) * 6)); 

        //Add the menu bar and the main panel to the main frame
        main_frame.add(main_panel, BorderLayout.CENTER);       
        main_frame.setJMenuBar(createMenuBar());

        //Display the main GUI
        main_frame.pack();
        main_frame.setLocationRelativeTo(null);
        main_frame.setVisible(true);

    }

    //Create an instance of the program
    private static void runIt() {
        TestIt program = new TestIt();
    }

    private JMenuBar createMenuBar() {
        //Create the top menu bar
        JMenuBar top_menu_bar = new JMenuBar();

        //Create the menu
        JMenu main_menu = new JMenu ("Menu");
        main_menu.setMnemonic(KeyEvent.VK_M);
        top_menu_bar.add(main_menu);

        //Create the menu items and add them to the menu
        JMenuItem menu_item;

        menu_item = new JMenuItem("Add New");
        menu_item.setMnemonic(KeyEvent.VK_N);
        menu_item.setAccelerator(
                KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.ALT_MASK));
        menu_item.setActionCommand("new");
        menu_item.addActionListener(this);
        main_menu.add(menu_item);

        menu_item = new JMenuItem("Save");
        menu_item.setMnemonic(KeyEvent.VK_S);
        menu_item.setAccelerator(
                KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.ALT_MASK));
        menu_item.setActionCommand("save");
        menu_item.addActionListener(this);
        main_menu.add(menu_item);

        menu_item = new JMenuItem("Exit");
        menu_item.setMnemonic(KeyEvent.VK_X);
        menu_item.setAccelerator(
                KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.ALT_MASK));
        menu_item.setActionCommand("exit");
        menu_item.addActionListener(this);
        main_menu.add(menu_item);

        //Return the assembled menu bar
        return top_menu_bar;
    }

    public void actionPerformed(ActionEvent e) {
        if("new".equals(e.getActionCommand())) {
            createFrame();
        } else if("save".equals(e.getActionCommand())) {
            //save();
        } else {
            quit();
        }
    }

    private void createFrame() {
        /*
        ImageIcon image = new ImageIcon("src/testit/resources/img/test.gif");
        JLabel label = new JLabel("", image, JLabel.CENTER);        
        main_panel.add(label);
        */

        JButton frame = new JButton("test");
        frame.setBorder(new LineBorder(Color.BLACK));
        frame.setPreferredSize(new Dimension(60, 80));
        frame.setVisible(true);
        main_panel.add(frame);
        main_frame.revalidate();

    }

    private void quit() {
        System.exit(0);
    }

    public static void main(String [] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                runIt();
            }
        });
    }
}

Any ideas what the error in my code is?

EDIT: I was able to fix it by using main_frame.revalidate()... is that the most appropriate way? It appears the the same thing is accomplished using validate(), but unfortunately, I don't understand the difference even after reading the javadoc.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
B.K.
  • 9,982
  • 10
  • 73
  • 105
  • `revalidate()` is an asynchronous method. It allows telling Swing: when you have finished handling the events (click, mouse, etc.) that are in the queue, call `validate()`. `validate()` is synchronous. It executes the validation action immediately. – JB Nizet May 12 '13 at 14:50
  • @JB Nizet Ahh, cool. Thank you, that's a much better explanation than what javadoc has. I appreciate it. – B.K. May 12 '13 at 17:31

2 Answers2

1

Perhaps you can clarify but you have stated that class TestIt extends JFrame therefor you have no need for main_frame = new JFrame("Test Program"); within your constructor.

It could be replaced by something like this:

public testIt() {

   super("Test Program");
   this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   this.setSize(500, 500);

   // whatever code goes here such as...
   // this.add(somePanel);
   // this.add(new JButton("Click Me!"));
   // etc..

   this.setVisible(true);
   this.pack();

}

Unless there is an explicit reason for the frame. Also your not wrong your just doing it differently but the reason I brought it up is because why subclass JFrame if you dont take advantage of it?

  • Hmm, true, it works. I'm still pretty new to Java, so I wasn't 100% sure how extends worked. Thank you. ;) – B.K. May 12 '13 at 17:30
0

Create Dynamic JButton with Image and ActionListener - Java Swing

Create JButton dynamically with Image and the ActionListener . You will be able to change the button height , width horizontal gap and vertical gap in one place.

enter image description here

I have create dummy database class which will return the Main menu items and the Sub menu items.You will see the Main menu item in your JFrame. If you select main Item (FOOD) from the button panel it will load Sub Items from the dummy database class (sub items of the FOOD)

you can find more details with images and source Code from here

private void addMainMenue() {

    pnl_button.removeAll();
    repaint();

    Image img, sub;
    ImageIcon icon;
    String imagePath, imag = "/com/images/";

    ArrayList menue = new ArrayList();
    ArrayList itemName = new ArrayList();

    for (int size = 0; size < ItemDB.mainMenuCodes.length; size++) {
        menue.add(ItemDB.mainMenuCodes[size]);
        itemName.add(ItemDB.mainMenuDesc[size]);
    }

    JButton[] buttons = new JButton[menue.size()];

    for (int i = 0; i < buttons.length; i++) {

        imagePath = imag + menue.get(i).toString() + ".jpeg";

        URL url = getClass().getResource(imagePath);
        // System.out.println(imagePath +"   Get Res : "
        // +getClass().getResource(imagePath));

        if (url != null) {
            img = Toolkit.getDefaultToolkit().getImage(url);
            sub = img.getScaledInstance(button_width - 8,
                    button_height - 30, Image.SCALE_FAST);
            icon = new ImageIcon(sub);
        } else
            icon = new ImageIcon();

        buttons[i] = new JButton(itemName.get(i).toString(), icon);
        buttons[i].setVerticalTextPosition(AbstractButton.BOTTOM);
        buttons[i].setHorizontalTextPosition(AbstractButton.CENTER);

        buttons[i]
                .setBorder(javax.swing.BorderFactory.createEtchedBorder());
        buttons[i].setFont(new java.awt.Font("Tahoma", 1, 13));
        buttons[i].setForeground(new java.awt.Color(0, 51, 255));

        buttons[i].setActionCommand(menue.get(i).toString());
        buttons[i].addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                String choice = e.getActionCommand();
                addSubmenue(choice);
            }
        });
    }

    int b = 0;
    int vGap = verticalGap;
    int hGap = horizontalGap;
    int bLength = buttons.length;
    int bRows = bLength / numberOfColumns + 1;

    L1: for (int j = 0; j < bRows; j++) {
        vGap = 10;
        for (int k = 0; k < numberOfColumns; k++) {

            pnl_button.add(buttons[b],
                    new org.netbeans.lib.awtextra.AbsoluteConstraints(vGap,
                            hGap, button_width, button_height));
            repaint();
            vGap += button_width + verticalGap;
            b++;
            if (b >= bLength) {
                break L1;
            }
        }
        hGap += button_height + horizontalGap;
    }
    pack();
}

private void addSubmenue(String choice) {
    pnl_button.removeAll();
    repaint();

    Image img, sub;
    ImageIcon icon;
    String imagePath, imag = "/com/images/";

    ArrayList menue = new ArrayList();
    ArrayList itemName = new ArrayList();

    ArrayList list = ItemDB.getSubMenu(choice);
    String subCode[] = (String[]) list.get(0);
    String subDesc[] = (String[]) list.get(1);

    for (int size = 0; size < subCode.length; size++) {
        menue.add(subCode[size]);
        itemName.add(subDesc[size]);
    }

    JButton[] buttons = new JButton[menue.size()];

    for (int i = 0; i < buttons.length; i++) {

        imagePath = imag + menue.get(i).toString() + ".jpeg";

        URL url = getClass().getResource(imagePath);
        // System.out.println(imagePath +"   Get Reso : "
        // +getClass().getResource(imagePath));

        if (url != null) {
            img = Toolkit.getDefaultToolkit().getImage(url);
            sub = img.getScaledInstance(button_width - 8,
                    button_height - 30, Image.SCALE_FAST);
            icon = new ImageIcon(sub);
        } else
            icon = new ImageIcon();

        buttons[i] = new JButton(itemName.get(i).toString(), icon);
        buttons[i].setVerticalTextPosition(AbstractButton.BOTTOM);
        buttons[i].setHorizontalTextPosition(AbstractButton.CENTER);

        buttons[i]
                .setBorder(javax.swing.BorderFactory.createEtchedBorder());
        buttons[i].setFont(new java.awt.Font("Tahoma", 1, 13));
        buttons[i].setForeground(new java.awt.Color(0, 51, 255));

        buttons[i].setActionCommand(menue.get(i).toString());
        buttons[i].addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                String choice = e.getActionCommand();
                addItems(choice);
            }
        });
    }
    int b = 0;
    int vGap = verticalGap;
    int hGap = horizontalGap;
    int bLength = buttons.length;
    int bRows = bLength / numberOfColumns + 1;

    L1: for (int j = 0; j < bRows; j++) {
        vGap = 10;
        for (int k = 0; k < numberOfColumns; k++) {

            pnl_button.add(buttons[b],
                    new org.netbeans.lib.awtextra.AbsoluteConstraints(vGap,
                            hGap, button_width, button_height));
            repaint();
            vGap += button_width + verticalGap;
            b++;
            if (b >= bLength) {
                break L1;
            }
        }
        hGap += button_height + horizontalGap;
    }
    pack();
}

private void addItems(String choice) {

    if (choice.equals("P"))
        choice = "PIZZA";
    else if (choice.equals("B"))
        choice = "BURGER";
    else if (choice.equals("FJ"))
        choice = "FRUIT JUICE";
    else if (choice.equals("HB"))
        choice = "HOT BEVERAGES";
    JOptionPane.showMessageDialog(this, "You have select  " + choice);
}
Chathura Wijesinghe
  • 3,310
  • 3
  • 25
  • 41