简体   繁体   中英

Only first object visible on JFrame

I'm not sure how to title this question so if you have a better one, please let me know.

My question is about Objects on JFrames. I'm given a class that is called ThreeButtonFrame and looks like this:

    import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/** ThreeButtons and ThreeButtonFrame supplier Classes
 * Author: David D. Riley
 * Date: April, 2004
 *
 *  ThreeButtons supports button events for the ThreeButtonFrame class.
 *  This class is designed to be inherited and its methods overridden.
 */
public abstract class ThreeButtons  {  

    /** The method below is an event handler for button clicks on
     *  the LEFT button of an object of type A3ButtonWindow 
     */
    public abstract void leftAction();

    /** The method below is an event handler for button clicks on
     *  the MID button of an object of type A3ButtonWindow 
     */
    public abstract void midAction();

    /** The method below is an event handler for button clicks on
     *  the RIGHT button of an object of type A3ButtonWindow 
     */
    public abstract void rightAction();

    /** The class below provides a JFrame that includes three JButtons (left, mid and right).
     *  The event handling of these three buttons will be performed by the leftAction
     *  midAction and rightAction methods of the subclass of ThreeButtons. 
     */
    protected class ThreeButtonFrame extends JFrame implements ActionListener{
        private JButton leftButton, midButton, rightButton;

        public ThreeButtonFrame(String s) {
            super(s);
            setBounds(20, 20, 600, 500);
            setVisible(true);
            Container pane = getContentPane();
            pane.setLayout(null);
            leftButton = new JButton("LEFT");
            leftButton.setBounds(100, 430, 100, 30);
            leftButton.addActionListener(this);
            pane.add(leftButton, 0);
            midButton = new JButton("MID");
            midButton.setBounds(250, 430, 100, 30);
            midButton.setText("MID");
            midButton.addActionListener(this);
            pane.add(midButton, 0);
            rightButton = new JButton("RIGHT");
            rightButton.setBounds(400, 430, 100, 30);
            rightButton.addActionListener(this);
            pane.add(rightButton, 0);
            pane.repaint();
        }

        public void setBackground(Color c) {
            super.getContentPane().setBackground(c);
        }

        /** Event Handler
         *  This method is called whenever any of the three
         *  buttons is clicked   
         */
        public void actionPerformed(ActionEvent e)  {
            if (e.getSource() == leftButton)
                leftAction();
            else if (e.getSource() == midButton)
                midAction();
            else if (e.getSource() == rightButton)
                rightAction();      
        }

    }

}

I'm then given the Rectangle class:

    import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

/** Rectangle Supplier Class 
 * Author: David D. Riley
 * Date: April, 2004
 */
public class Rectangle extends JComponent  {

    /** post:   getX() == x  and  getY() == y
     *          and  getWidth() == w  and getHeight() == h
     *          and  getBackground() == Color.black
     */
    public Rectangle(int x, int y, int w, int h)  {
        super();
        setBounds(x, y, w, h);
        setBackground(Color.black);
    }

    /** post:   this method draws a filled Rectangle
     *          and  the upper left corner is (getX(), getY()) 
     *          and  the rectangle's dimensions are getWidth() and getHeight()
     *          and  the rectangle's color is getBackground()
     */
    public void paint(Graphics g)  {
       // ((Graphics2D)g).setClip( new Ellipse2D.Double(getX(), getY(), getWidth(), getHeight()) );
        g.setColor( getBackground() );
        g.fillRect(0, 0, getWidth()-1, getHeight()-1);
        paintChildren(g);
   }

}

I then create a class called Analyzer that extends the Rectangle class and inside this class I initialize 2 JLabel 's, a JTextField .

Analyzer :

    import javax.swing.*;
import java.awt.*;

/**
 * Created by Sully on 4/5/16.
 */
public class Analyzer extends Rectangle {

    private JLabel topLabel;
    private JLabel resultLabel;
    private JTextField text;

    public Analyzer(int x, int y, int w, int h) {
        super(x, y, w, h);
        topLabel = new JLabel("Enter your sentence below: ");
        topLabel.setBounds(getX(), getY() - 25, 225, 30);
        topLabel.setBackground(Color.blue);
        text = new JTextField("BLAHBLAH");
        text.setBounds(topLabel.getX() + 2, topLabel.getY() + 30, 350, 20);
        text.setBackground(Color.CYAN);
        resultLabel = new JLabel("Results: ");
        resultLabel.setBounds(text.getX() - 5, text.getY() + 20, 150, 30);
        resultLabel.setBackground(Color.MAGENTA);
        setBackground(Color.white);


        add(topLabel);
        add(text);
        add(resultLabel);
        repaint();


    }

    public void paint(Graphics g) {
        // ((Graphics2D)g).setClip( new Ellipse2D.Double(getX(), getY(),                    getWidth(), getHeight()) );
        g.setColor(getBackground());
        g.fillRect(0, 0, getWidth() - 1, getHeight() - 1);
        paintChildren(g);
    }

}

In a driver class where I initialize a ThreeButtonFrame object and add Analyzer objects to the frame, although when I make 3 separate objects in my driver class like so:

Analyzer a1 = new Analyzer(win.getX() + 1, win.getY() + 10, 450, 100);
    Analyzer a2 = new Analyzer(a1.getX() + 25, a1.getY() + (30 + a1.getHeight()), 450, 100);
    Analyzer a3 = new Analyzer(a2.getX() + 25, a2.getY() + (30 + a2.getHeight()), 450, 100);
win.add(a1, 0);        
win.add(a2, 0);
    win.add(a3, 0);


    win.repaint();

Only the first call (a1) is visible. The remaining 2 white boxes are added but without the elements. Why is this?

I tried changing the variables in the Analyzer class to instance variables inside the constructor method.

You seem to have a significant misunderstanding in how container layout management works. Child components are automatically offset by the containers x/y position, this makes the child component's position contextual to the parent container, meaning that the top/left position is always 0x0 within any given container

For example, if I change...

topLabel.setBounds(getX(), getY() - 25, 225, 30);

to

topLabel.setBounds(0, 0, 225, 30);

It will generate...

屏幕

Having said that, I would STRONGLY discourage you from doing this and start using appropriate layout managers

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM