Search code examples
javaswingjframejpaneljapplet

Office layout example. JLabels don't show up in JApplet


I have searched (I think) thoroughly for an answer to my problem. I'm a beginner so I may just not know what to look for. I am trying to make an overview of an office layout (tables, chairs), which I coded using Graphics2D and GeneralPath, and JLabels with names by each chair. If this has already been answered I apologize but I did look. (Note: the graphics are super simple for now: table is just a square and chairs are just lines.)

public class DemoReception extends JApplet{

@Override    
public void paint(Graphics g){
    //draws table
    Graphics2D g2 = (Graphics2D) g;
    g2.setStroke(new BasicStroke(4.0f));
    g2.setColor(Color.BLACK);

    int[] xPoints={150,700,700,150};
    int[] yPoints={250,250,550,550};
    GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD,xPoints.length);

    path.moveTo(xPoints[0], yPoints[0]);
    for (int i = 0; i < xPoints.length; i++) {
        path.lineTo(xPoints[i], yPoints[i]);
    }
    path.closePath();
    g2.draw(path);

    //draws chairs
    g2.setColor(Color.RED);
    path = new GeneralPath(GeneralPath.WIND_NON_ZERO);
    path.moveTo(260,240);//Person1
    path.lineTo(310,240);

    path.moveTo(510,240);//Person2
    path.lineTo(560,240);

    path.moveTo(260,560);//Person3
    path.lineTo(310,560);

    path.moveTo(510,560);//Person4
    path.lineTo(560,560);
    path.closePath();
    g2.draw(path);                               
   }

And here is the main method:

   public static void main(String[] args) { 
    int labelwidth = 50;
    int labelheight = 10;

    JFrame testFrame = new JFrame("Test Layout");
    testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JApplet demo = new DemoReception();
    testFrame.setBackground(Color.white);
    testFrame.getContentPane().add(demo);
    testFrame.pack();
    testFrame.setMinimumSize(new Dimension(1000,710));
    testFrame.setSize(new Dimension(1000,710));

    JPanel testPanel = new JPanel();
    testPanel.setAlignmentX(0);
    testPanel.setAlignmentY(0);

    label1 = new JLabel("Person1");
    label2 = new JLabel("Person2");
    label3 = new JLabel("Person3");
    label4 = new JLabel("Person4");

    label1.setAlignmentX(260);
    label1.setAlignmentY(235);
    label1.setSize(labelwidth, labelheight);
    label1.setVisible(true);        
    testPanel.add(label1);

    label2.setAlignmentX(510);
    label2.setAlignmentY(235);
    label2.setSize(labelwidth, labelwidth);
    label2.setVisible(true);
    testPanel.add(label2);

    label3.setAlignmentX(260);
    label3.setAlignmentY(565);
    label3.setSize(labelwidth, labelwidth);
    label3.setVisible(true);
    testPanel.add(label3);

    label4.setAlignmentX(510);
    label4.setAlignmentY(565);
    label4.setSize(labelwidth, labelwidth);
    label4.setVisible(true);
    testPanel.add(label4);

    testFrame.getContentPane().add(testPanel);
    testFrame.setVisible(true);
}

When I run it all I get is the JFrame with the graphics but the JLabels don't show up. Any help would be appreciated.


Solution

  • The JLabel does not appear in the JApplet as JFrame#pack is called before all labels have been added. The result is that those components are not validated so dont appear

    The solution is to invoke the method before calling setVisible

    testFrame.pack();
    testFrame.setVisible(true);
    

    However further changes are necessary as the applet window itself will not appear when this is done. This is because the statement

    testFrame.getContentPane().add(testPanel);
    

    will cause the JPanel testPanel to be displaced as implemented in the earlier statement

    testFrame.getContentPane().add(demo); 
    

    BorderLayout can only contain one component at the CENTER location.

    To fix, remove the testPanel and add the JLabel components directly to the JApplet demo instead.

    Also add

    super.paint(g);
    

    to the paint method to ensure that the JLabels are painted by Swing.


    Of course paint should never be used for custom painting in Swing. Rather use paintComponent

    As a future exercise, make sure to replace the paint functionality by using a JComponent based class instead and overriding paintComponent. Remember to invoke super.paintComponent(g). Follow the steps outlined in Performing Custom Painting