views:

49

answers:

1

I've added a JPanel to my Netbeans generated GUI, and add a JPanel BoxThing that overrides paintComponent and draws a small red box, but it doesn't display, paintComponent never even gets invoked. If I instantiate my own JFrame and put a JPanel containing a BoxThing in it, it works fine.

I've seen this question asked a few other times on random forums, and the people don't answer the question, instead they point to the custom painting tutorial, which obviously doesn't help.

I tried with Netbeans 5.5 first, then switched to Netbeans 6.8, same issue.

Main.java

package MadProGUI9000;

public class Main extends javax.swing.JFrame {

    /** Creates new form Main */
    public Main() {
        initComponents();
        panel.add(new BoxThing());
    }

    /** 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() {

        panel = new javax.swing.JPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        panel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        javax.swing.GroupLayout panelLayout = new javax.swing.GroupLayout(panel);
        panel.setLayout(panelLayout);
        panelLayout.setHorizontalGroup(
            panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 260, Short.MAX_VALUE)
        );
        panelLayout.setVerticalGroup(
            panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 185, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(69, 69, 69)
                .addComponent(panel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(69, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(45, 45, 45)
                .addComponent(panel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(68, Short.MAX_VALUE))
        );

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

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Main().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    private javax.swing.JPanel panel;
    // End of variables declaration

}

BoxThing.java

package MadProGUI9000;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * A component with a red box in the center.
 */
public class BoxThing extends JPanel {

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        Dimension size = getSize();

        int rX = (size.width - 5)/2;
        int rY = (size.height - 5)/2;

        g.setColor(Color.RED);
        g2.fillRect(rX, rY, 5, 5);
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("BoxThing demo");
                JPanel panel = new JPanel();
                frame.add(panel);
                panel.add(new BoxThing());
                frame.setVisible(true);
                panel.setPreferredSize(new Dimension(100, 100));
                frame.pack();
            }
        });
    }

}

As you can see, it works if you just run BoxThing.java's main. If you run the Netbeans GUI, it wont work. So, how can I add custom components to a Netbeans generated Swing GUI?

+1  A: 

That's the way Group layout works. It divides the screen real estate up into Groups. During layout it cycles through the groups to determine the bounds for each component. When you added your panel to the container, it was not added to any group, and so was never given a size or location. As a result it has a size of (0,0) and is never painted.

You can make it appear by setting a size, but as it's not being considered in the layout, it will most likely wind up overlapping with other components.

To accomplish what you want, you need to set panel's layout to something else, like BorderLayout. For example:

public Main() {
    initComponents();
    panel.setLayout(new BorderLayout());
    panel.add(new BoxThing(), Borderlayout.CENTER);
}
Devon_C_Miller