在 java 中向 jframe 添加不同的 jcomponents

add different jcomponents to jframe in java

我想在一个 JPanel 中绘制一些不同的 JComponents。我用不同的绘制方法创建了一些 JComponents。然后在main中创建对象,放到JFrame中。 我的问题是,只有最后一个对象被绘制在 Window 中。

如何在 window 中放置不同的 JComponent,而不删除或重新绘制旧的?

(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);                   
    }
}

JFrame 默认使用 BorderLayout。在不指定约束的情况下添加组件时,每个组件将放置在 CENTER.

要么指定约束,要么如果 BorderLayout 对您来说不够,请切换到另一个布局。

要添加约束:

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

我建议阅读How to use BorderLayout, as well as guides on the other predefined layouts。此外,如果通过 JDK 提供的布局中有 none 符合您的需要,请随意在线查找第 3 方布局。或者,如果不存在满足您需要的布局,您可以创建自己的 LayoutManager


我还建议使用 pack() 根据内部组件 调整框架的大小,而不是使用 frame.setSize 设置框架的大小。这可确保您的框架紧紧包裹其中的任何东西,不留空隙。如果你想要空白,应该由布局管理器处理

您可以指定组件的大小或使用布局将对象放置在不同的地方。或者您可以创建 Graphics 的副本并在其中写入:

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

但最后一个变体效率不高:它会在每次重绘时复制图形。

进行自定义绘画时:

  1. 您需要将组件的 getPreferredSize() 方法重写为组件的 return 大小,以便布局管理器可以显示组件。现在你的组件的大小是 (0, 0) 所以没有什么可画的。

  2. 组件的绘制是从(0, 0)开始,而不是(x, y)。然后,如果您将组件定位在面板上的特定点,您可以使用 setLocation(x, y) 告诉 Swing 在何处绘制组件。

  3. 如果要在任意位置绘制组件,则还需要在面板上使用空布局,还必须设置组件的大小。要设置组件的大小,您可以在构造函数中使用 setSize(getPreferredSize())。

因此您的 Model1 class 看起来像:

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);                   
    }
}