简体   繁体   中英

add different jcomponents to jframe in java

I want to draw some different JComponents in one JPanel. I create some JComponents with different paint methods. Then create the objects in the main and put them to the JFrame. My problem is, that only the last Object is painted in the Window.

How can I put different JComponents in the window, without remove or repaint the old ones?

(Model2 works like Model1, but the paintComponent is a little bit different)

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class GuiModel{  
    public static void main(String[] args){         
        JFrame frame = new JFrame();        
        frame.setSize(600, 600);
        frame.setLocation(150, 150);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);                 

        frame.getContentPane().add(new Model1(0,0));
        frame.getContentPane().add(new Model2(25,37,true));             

    }
}
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComponent;    
public class Model1 extends JComponent {
    private int xPos, yPos;


    Model1 (int x, int y){
        this.xPos = x;
        this.yPos = y;
    }

    @Override
    protected void paintComponent(Graphics g) {     
        g.setColor(Color.BLACK);
        g.drawOval(xPos, yPos, 5, 5);                   
    }
}

When doing custom painting:

  1. You need to override the getPreferredSize() method of your component to return the size of the component so a layout manager can display the component. Right now the size of your components are (0, 0) so there is nothing to paint.

  2. The painting of a component is done from (0, 0), not (x, y). Then if you position the component at a specific point on the panel you use setLocation(x, y) to tell Swing where to painting the component.

  3. If you want to paint the component at a random position then you also need to use a null layout on the panel and you must also set the size of the component. To set the size of the component you would use setSize( getPreferredSize()) in your constructor.

So your Model1 class would look something like:

public class Model1 extends JComponent {
    //private int xPos, yPos;

    Model1 (int x, int y){
        //this.xPos = x;
        //this.yPos = y;
        setLocation(x, y);
        setSize( getPreferredSize() );
    }

    @Override
    public Dimension getPreferredSize()
    {
        return new Dimension(5, 5);
    }
    @Override
    protected void paintComponent(Graphics g) {     
        g.setColor(Color.BLACK);
        //g.drawOval(xPos, yPos, 5, 5);                   
        g.drawOval(0, 0, 5, 5);                   
    }
}

JFrame uses BorderLayout by default. When adding components without specifying the constraints, each component will be placed at CENTER .

Either specify the constraints, or if BorderLayout isn't suffice for you, switch to another layout.

To add constraints:

frame.add(new Model1(0,0), BorderLayout.NORTH);

I suggest reading How to use BorderLayout , as well as guides on the other predefined layouts . Also, feel free to look online for 3rd party layouts, if none of the layouts available through the JDK fit your needs. Or you could create your own LayoutManager if no layouts exist that fit your needs


I also recommend using pack() to size your frame based on the components inside instead of setting it's size with frame.setSize . This ensures your frame tightly wraps around anything inside of it, leaving no empty spaces. If you want empty spaces, it should be handled by the layout manager

You can specify size for components or use Layouts to place objects not in one place. Or you can create copy of Graphics and write in it:

protected void paintComponent(Graphics g) {
    g = g.create();
    g.setColor(Color.BLACK);
    g.drawOval(xPos, yPos, 5, 5);
    g.dispose();
}

But the last variant is not efficient: it makes copy of Graphics on each repaint.

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