Java 正在调用PaintComponent(),但未绘制JComponent

Java 正在调用PaintComponent(),但未绘制JComponent,java,swing,Java,Swing,基本上,我有一个问题,绘画的自定义组件我做的。无论何时调用repaint(),都会调用Button类的paintComponent(),但框架中没有显示任何内容。我还知道组件的大小和位置正确,因为我设置了边框来检查这一点 以下是我的自定义组件类: public class Button extends JComponent { protected static final Color BUTTON_COLOR = Color.black; protected Point position; p

基本上,我有一个问题,绘画的自定义组件我做的。无论何时调用repaint(),都会调用Button类的paintComponent(),但框架中没有显示任何内容。我还知道组件的大小和位置正确,因为我设置了边框来检查这一点

以下是我的自定义组件类:

public class Button extends JComponent {

protected static final Color BUTTON_COLOR = Color.black;
protected Point position;
protected Dimension size;

public Button(int posX, int posY, int width, int height) {
    super();
    position = new Point(posX, posY);
    size = new Dimension(width, height);
    setBounds(position.x, position.y, size.width, size.height);
    setBorder(BorderFactory.createTitledBorder("Test"));
    setOpaque(true);
}

@Override
protected void paintComponent(Graphics g) {
    setBounds(position.x, position.y, size.width, size.height);
    drawButton(g);
    super.paintComponent(g);
}

@Override
public Dimension getPreferredSize() {
    return size;
}

public void drawButton(Graphics g) {

    selectColor(g, BUTTON_COLOR);
    g.fillRect(position.x, position.y, size.width, size.height);
    g.setColor(Color.black);
    g.drawRect(position.x, position.y, size.width, size.height);

}}
这是添加自定义组件的JPanel:

public class MainMenu extends JPanel {
public MainMenu() {
    setBackground(Color.BLACK);
    setLocation(0,0);
    setPreferredSize(new Dimension(800,600));
    setDoubleBuffered(true);
    setVisible(true);
    this.setFocusable(true);
    this.requestFocus();
}}
最后,我将以下组件添加到主菜单JPanel中:

    main_menu.add(new Button(200, 200, 150, 50));
    dropdown = new JComboBox<File>() {
        @Override
        public void paintComponent(Graphics g) {
            dropdown.setLocation(new Point(400, 200));
            super.paintComponent(g);
        }
    };

    main_menu.add(dropdown);
主菜单。添加(新按钮(20020015050));
dropdown=newjcombobox(){
@凌驾
公共组件(图形g){
设置位置(新点(400200));
超级组件(g);
}
};
主菜单。添加(下拉菜单);
奇怪的是,当在主菜单上调用repaint()时,JComboBox会被绘制,但按钮不会被绘制,即使按钮的paintComponent()被调用。

几个问题:

  • 在绘制方法(如
    paintComponent
    )中,决不能调用
    setBounds(…)
    。此方法仅适用于绘画和绘画
  • 您的边界和绘制区域是相同的,但它们代表两个非常不同的东西。边界是组件相对于其容器的位置,绘制x、y是相对于JComponent本身的。所以你画得太离谱了
  • 同样,您的
    drawButton
    方法应该在0,0:
    g.drawRect(0,0,size.width,size.height)处绘制
  • setBounds
    无论如何都不应该被调用。这就是布局管理员的工作。通过这样做,您可以添加一整层潜在的、难以发现的bug
  • 我将重写
    getPreferredSize()
    ,以帮助设置组件的最佳大小(编辑——您已经这样做了,尽管是以一种非常简单的方式)
  • 您不应该在按钮内部设置按钮的位置——同样,这是其容器布局管理器的工作
  • 在paintComponent覆盖中,可能应该首先调用super.paintComponent(g)
  • 我会避免给我的类起一个与公共核心类冲突的名字