简体   繁体   English

在Java中将不同的jcomponents添加到jframe

[英]add different jcomponents to jframe in java

I want to draw some different JComponents in one JPanel. 我想在一个JPanel中绘制一些不同的JComponent。 I create some JComponents with different paint methods. 我用不同的绘制方法创建了一些JComponents。 Then create the objects in the main and put them to the JFrame. 然后在主对象中创建对象并将其放入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? 我如何在窗口中放置不同的JComponent,而又不删除或重新绘制旧的JComponent?

(Model2 works like Model1, but the paintComponent is a little bit different) (Model2的工作方式类似于Model1,但paintComponent有所不同)

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. 您需要重写组件的getPreferredSize()方法以返回组件的大小,以便布局管理器可以显示该组件。 Right now the size of your components are (0, 0) so there is nothing to paint. 现在,组件的大小为(0,0),因此无需绘制任何内容。

  2. The painting of a component is done from (0, 0), not (x, y). 组件的绘制是从(0,0)开始的,而不是从(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. 然后,如果将组件放置在面板上的特定点,则可以使用setLocation(x,y)来告诉Swing在何处绘画组件。

  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. 要设置组件的大小,可以在构造函数中使用setSize(getPreferredSize())。

So your Model1 class would look something like: 因此,您的Model1类如下所示:

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. JFrame默认使用BorderLayout When adding components without specifying the constraints, each component will be placed at CENTER . 在不指定约束的情况下添加组件时,每个组件将放置在CENTER

Either specify the constraints, or if BorderLayout isn't suffice for you, switch to another layout. 指定约束,或者如果BorderLayout不足以满足您的要求,请切换到其他布局。

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 . 我建议阅读“ 如何使用BorderLayout ”以及其他预定义布局的指南 Also, feel free to look online for 3rd party layouts, if none of the layouts available through the JDK fit your needs. 另外,如果JDK可用的布局都不符合您的需求,请随时在线查找第三方布局。 Or you could create your own LayoutManager if no layouts exist that fit your needs 或者,如果不存在符合您需要的布局,则可以创建自己的LayoutManager


I also recommend using pack() to size your frame based on the components inside instead of setting it's size with frame.setSize . 我还建议您使用pack() 根据内部组件调整框架的大小,而不是使用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. 但是最后一个变体效率不高:它在每次重绘时都会复制Graphics。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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