如何让 Java Swing 组件显示在 JFrame 内的 JPanel 上,以便随后添加和删除它们?

问题描述 投票:0回答:1

我有这个自定义组件:

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

public class Comp extends JComponent{
    
        int x;
        int y;
        String name;
    
        public Comp(int px, int py, String pn){
            name=pn;
            System.out.println("new cp--"+name);
            x = px;
            y = py;
            //setBounds(x, y, 50, 50);
        }
        @Override
        protected void paintComponent(Graphics g){
            System.out.println("paint cp--"+name);
            g.setColor(Color.BLACK);
            g.drawOval(x,y,50,50);
            g.drawString(name, x+25, y+25);
        }

        @Override
        public Dimension getPreferredSize() {
            System.out.println("\tG pref size");
            return new Dimension(50,50);
        }
    }

这个测试类:

import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

public class Ts {

    JFrame frame;
    Comp c1;
    Comp c2;

    public Ts(){
        frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(500,500);
        frame.setBackground(Color.YELLOW);
        //frame.setLayout(null);
        frame.setVisible(true);
        
        
        c1 = new Comp(100,200,"c1");
        c2 = new Comp(200,100,"c2");
        


        frame.add(c1);

        frame.revalidate();
        

        delay();
        frame.add(c2);
        
        frame.revalidate();
        
        
        rmC();
    }

    private void rmC(){
        delay();
        System.out.println("rm c1");
        frame.remove(c1);

        //frame.revalidate();
        frame.repaint();

        delay();

        System.out.println("rm c2");
        frame.remove(c2);

        //frame.revalidate();
        frame.repaint();
    }

    void delay(){
        System.out.println("....dly");
        try{
            Thread.sleep(3000);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

到目前为止效果很好(我希望能够根据命令添加和删除我的测试组件)

现在当我在这门课上尝试时:

import java.awt.Color;

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

public class TsPanel {

    JFrame frame;
    JPanel panel;
    Comp c1;
    Comp c2;

    public TsPanel(){
        frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(500,500);
        frame.setBackground(Color.YELLOW);
        //frame.setLayout(null);
        frame.setVisible(true);

        panel = new JPanel();
        //panel.setLayout(null);
        panel.setBackground(Color.GREEN);

        frame.add(panel);
        
        
        c1 = new Comp(100,200,"c1");
        c2 = new Comp(200,100,"c2");
        


        panel.add(c1);
        //panel.add(new JButton());

        panel.revalidate();
        frame.revalidate();
        frame.repaint();
        

        delay();
        panel.add(c2);
        
        panel.revalidate();
        frame.revalidate();
        frame.repaint();
        
        
        rmC();
    }

    private void rmC(){
        delay();
        System.out.println("rm c1");
        panel.remove(c1);

        //panel.revalidate();
        panel.repaint();
        frame.repaint();

        delay();

        System.out.println("rm c2");
        panel.remove(c2);

        //panel.revalidate();
        panel.repaint();
        frame.repaint();
    }

    void delay(){
        System.out.println("....dly");
        try{
            Thread.sleep(3000);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

我的组件根本不会显示(如果我将 Layoutmanager 设置为空,则根本不会调用绘制方法;如果我设置了边界,它会调用 getPreferredSize() 方法几次,但也不会显示任何内容,如果我将 Layoutmanager 设置为 null 并设置调用绘制方法的边界,但它仍然不会显示任何内容)。另外,如果我向面板添加按钮或标签,它们就可以被看到,只是我的 Comp 类不起作用。

我将不胜感激任何帮助!

我尝试在程序中制作图形显示视图(用于学校;Dijkstra 等),它可以让我添加和删除顶点和边作为组件。我想如果我只是分别扩展 JComponent 类,添加组件,调用面板重绘(显然不是必需的)和重新验证(如果使用布局管理器)方法,组件就会显示,如果我从面板中删除它们(然后调用再次重新绘制和重新验证方法)它们会消失,而无需我“手动”重新绘制所有内容。

相反,如果我尝试在面板上执行此操作,组件根本不会显示。

java swing components jpanel jcomponent
1个回答
0
投票

考虑对您添加组件的面板使用

LayoutManager
。摆弄
setPreferredSize()
getPreferredSize()
可能会很麻烦(请参阅下面的 讨论)。

我猜你的代码按预期工作

panel.setLayout(new BorderLayout());
,例如。

否则,您需要手动确保组件的首选尺寸足以绘制其内容。

© www.soinside.com 2019 - 2024. All rights reserved.