如何动态删除一个JPanel? [英] How to dynamically remove a JPanel?

查看:335
本文介绍了如何动态删除一个JPanel?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个GUI看起来如下。

我要动态添加/删除面板。我使用的ArrayList 继续的JP​​anel 对象的痕迹。
而现在,我可以动态地添加面板,但我要删除一个面板,使我无法删除它,我不能让自己的属性。

下面是我的code:

 公共类主要实现的ActionListener {
    私人列表< myPanel> MPLIST;
    私人的JPanel btnPanel;
    私人的JButton jbtAdd,jbtDelete;
    私人的JFrame JF;
    私人的JPanel JP;
    私人JScrollPane的JS;
    私人myPanel熔点;
    私有静态诠释大小= 0;
    私人INT selectedId = -1;
    //私人的
    公众的Main(){
        MPLIST =新的ArrayList< myPanel>();
        btnP​​anel =新JPanel();
        jbtAdd =的新的JButton(addJpanel);
        jbtDelete =的新的JButton(delJpanel);
        btnP​​anel.setLayout(新的FlowLayout(FlowLayout.LEFT,1,1));
        btnP​​anel.add(jbtAdd);
        btnP​​anel.add(jbtDelete);
        JF =新的JFrame(你好);
        JP =新JPanel();
        JS =新JScrollPane的(JScrollPane.VERTICAL_SCROLLBAR_​​AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_​​AS_NEEDED);
        //jp.setLayout(new的FlowLayout(FlowLayout.LEFT,1,1));
        jf.setLayout(新的BorderLayout(10,10));
        jp.setLayout(新网格布局(0,1,1,1));
        jp.set preferredSize(新尺寸(500,82 * 6));
        的for(int i = 0;我6;;我++){
            myPanel MP =新myPanel();
            //mp.setSize(400,​​82);
            //mp.setBounds(0,82*i,480,82);
            mp.getFileTypeIconLabel()的setText(将String.valueOf(I))。
            mp.setIndexId(大小);
            大小++;
            mpList.add(0,熔点);
            mp.addMouseListener(新的MouseListener(){
                @覆盖
                公共无效的mouseClicked(的MouseEvent E){
                // TODO自动生成方法存根
                    如果(2 == e.getClickCount()){
                        的System.out.println(indexInd为+ mpList.get(0).getIndexId());
                        //System.out.println(index);
                        mpList.get(0).setBackground(Color.yellow);
                    }
                }                @覆盖
                公共无效的mouseEntered(的MouseEvent E){
                    // TODO自动生成方法存根                }                @覆盖
                公共无效的mouseExited(的MouseEvent E){
                    // TODO自动生成方法存根                }                @覆盖
                公共无效鼠标pressed(的MouseEvent E){
                    // TODO自动生成方法存根                }                @覆盖
                公共无效的mouseReleased(的MouseEvent E){
                    // TODO自动生成方法存根                }});
            jp.add(mpList.get(0));
        }
        js.setViewportView(JP);
        jf.setSize(600,500);
        jf.add(btnPanel,BorderLayout.NORTH);
        jf.add(JS);
        jbtAdd.addActionListener(本);
        jbtDelete.addActionListener(本);
        jf.setVisible(真);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    }
    公共静态无效的主要(字符串ARGS []){
        新的Main();
    }
    @覆盖
    公共无效的actionPerformed(ActionEvent的五){
        // TODO自动生成方法存根
        如果(e.getSource()== jbtAdd){
            addMyPanel();
        }
        否则如果(e.getSource()== jbtDelete){
            delMyPanel();
        }
    }
    公共无效addMyPanel(){
        的System.out.println(OK);
        熔点=新myPanel();
        。mp.getFileTypeIconLabel()的setText(将String.valueOf(mpList.size()));
        mp.setIndexId(大小);
        的System.out.println(大小);
        大小++;
        mpList.add(0,熔点);
        mp.addMouseListener(新的MouseListener(){
            @覆盖
            公共无效的mouseClicked(的MouseEvent E){
            // TODO自动生成方法存根
                如果(2 == e.getClickCount()){
                    的System.out.println(indexInd为+ mpList.get(0).getIndexId());
                    //System.out.println(index);
                    mpList.get(0).setBackground(Color.yellow);
                }
            }            @覆盖
            公共无效的mouseEntered(的MouseEvent E){
                // TODO自动生成方法存根            }            @覆盖
            公共无效的mouseExited(的MouseEvent E){
                // TODO自动生成方法存根            }            @覆盖
            公共无效鼠标pressed(的MouseEvent E){
                // TODO自动生成方法存根            }            @覆盖
            公共无效的mouseReleased(的MouseEvent E){
                // TODO自动生成方法存根            }});
        jp.add(mpList.get(0));
        jp.set preferredSize(新尺寸(500,82 * mpList.size()));
        //jp.validate();
        js.validate();
        //jp.repaint();
        js.repaint();
    }
    公共无效delMyPanel(){
        selectedId = getIndexOfMyPanelById();
        如果(selectedId> = 0){
            INT IndexID为= getIndexOfMyPanelById();
            jp.remove(mpList.get(IndexID为));
            mpList.remove(IndexID为);
            jp.set preferredSize(新尺寸(500,82 * mpList.size()));
            jp.repaint();
        }
    }
    保护INT getIndexOfMyPanelById(){
        迭代器< myPanel>它= mpList.iterator();
        为(中间体编号= 0; it.hasNext();编号++){
            myPanel熔点;
            熔点= it.next();
            如果(mp.isSelected()){
                返回ID;
            }
        }
        返回-1;
    }
}

下面是 myPanel

的code

 类myPanel继承JPanel {
    私有静态最后的serialVersionUID长1L =;
    JProgressBar的私人downloadProgress;
    私人的JLabel f​​ileTypeIconLabel,fileNameLabel,downloadInfoLabel,freeLabel;
    私人诠释IndexID为;
    私人布尔isSelected = FALSE;
    保护myPanel(){
        setLayout的(NULL);
        downloadProgress = JProgressBar的新(0,100);
        fileTypeIconLabel =新的JLabel(测试);
        fileNameLabel =新的JLabel(fileNameLabel);
        downloadInfoLabel =新的JLabel(downloadInfoLabel);
        freeLabel =新的JLabel(freeLabel);
        downloadProgress.setBounds(80,44,400,18);
        downloadProgress.setStringPainted(真);
        //downloadProgress.setString(\"88%);
        fileTypeIconLabel.setBounds(0,0,80,80);
        fileTypeIconLabel.setBackground(Color.cyan);
        fileTypeIconLabel.setOpaque(真);
        fileNameLabel.setBounds(80,0,400,22);
        fileNameLabel.setBackground(Color.black);
        fileNameLabel.setOpaque(真);
        downloadInfoLabel.setBounds(80,22,400,22);
        downloadInfoLabel.setBackground(Color.red);
        downloadInfoLabel.setOpaque(真);
        //downloadProgress.setValue(50);
        freeLabel.setBounds(80,62,400,18);
        freeLabel.setBackground(Color.lightGray);
        freeLabel.setOpaque(真);
        加(downloadProgress);
        加(fileTypeIconLabel);
        加(fileNameLabel);
        加(downloadInfoLabel);
        加(freeLabel);    }
    保护的JLabel getFileTypeIconLabel(){
        返回fileTypeIconLabel;
    }
    保护INT getIndexId(){
        返回IndexID为;
    }
    保护无效setIndexId(INT IndexID为){
        this.indexId = IndexID为;
    }
    保护布尔isSelected(){
        返回isSelected;
    }
    保护无效的setSelected(布尔isSelected){
        this.isSelected = isSelected;
    }
}


解决方案

有关许多部件在一个空间中,使用的 CardLayout 因为看到这个的小例子

提示

  jp.set preferredSize(新尺寸(500,82 * 6));

请参阅我应避免使用一套(preferred |最大|最小)?在大小的Java Swing (是)。

  downloadProgress.setBounds(80,44,400,18);

Java的图形用户界面可能需要在多个平台上工作,在不同的屏幕分辨率和放大器;使用不同的PLAFs。因此,它们不利于组件的确切位置。组织组件强大的图形用户界面,而是使用布局管理器,或 1 其中组合与布局填充和放一起;对于空白 2




编辑1

顺便说一句,在屏幕截图的尖叫声 JList的自定义渲染器给我。例如。

 进口java.awt中的*。
进口java.awt.event.ActionEvent中;
进口的javax.swing *。
进口javax.swing.border.EmptyBorder中;公共类DymanicDownloadList {    //由用户看到的GUI(无边框)
    JPanel的GUI =新JPanel(新的BorderLayout(2,2));    公共无效initGUI(){
        gui.setBorder(新EmptyBorder(2,3,2,3));        JToolBar中TB = JToolBar的新();
        gui.add(TB,BorderLayout.PAGE_START);        最后DefaultListModel<下载并GT; =的ListModel
                新DefaultListModel<&下载GT;();
        最终的JList<下载并GT;名单=新的JList<&下载GT;(ListModel的);
        list.setCellRenderer(新DownloadListCellRenderer());
        list.setVisibleRowCount(3);
        gui.add(新JScrollPane的(列表),BorderLayout.CENTER);        添加动作=新AbstractAction(添加下载){            @覆盖
            公共无效的actionPerformed(ActionEvent的五){
                listModel.addElement(新下载());
            }
        };        操作删除=新AbstractAction(删除下载){            @覆盖
            公共无效的actionPerformed(ActionEvent的五){
                INT指数= list.getSelectedIndex();
                如果(指数℃下){
                    JOptionPane.showMessageDialog(
                            列表中,
                            选择一个下载删除!
                            选择下载
                            JOptionPane.ERROR_MESSAGE);
                }其他{
                    listModel.removeElementAt(索引);
                }
            }
        };        tb.add(添加);
        tb.addSeparator();
        tb.add(删除);        为(中间体二= 0;ⅱ2;ⅱ++){
            listModel.addElement(新下载());
        }
    }    公共JComponent的getGUI(){
        返回贵;
    }    公共静态无效的主要(字串[] args){
        可运行R =新的Runnable(){            @覆盖
            公共无效的run(){
                DymanicDownloadList DDL =新DymanicDownloadList();
                ddl.initGUI();                JFrame的F =新的JFrame(动态表);
                f.add(ddl.getGUI());
                //确保JVM结束后架(S)关闭
                //所有非守护线程都完成
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                //见http://stackoverflow.com/a/7143398/418556的演示。
                f.setLocationByPlatform(真);                //保证帧是它需要的最小尺寸
                //为了显示它内部的组件
                f.pack();
                //应最后完成,避免闪烁,移动,
                //调整文物。
                f.setVisible(真);
            }
        };
        //摇摆的GUI应创建和更新的EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(R);
    }
}类下载{    下载() {
    }
}类DownloadListCellRenderer扩展DefaultListCellRenderer {    的JPanel downloadPanel =新JPanel(新的BorderLayout(10,10));
    的JPanel labelStack =新JPanel(新的GridLayout(0,1,2,2));
    JLabel的数量=新的JLabel(,SwingConstants.CENTER);
    JLabel的源=新的JLabel(文件名称标签,SwingConstants.CENTER);
    JLabel的信息=新的JLabel(下载信息标签,SwingConstants.CENTER);
    JLabel的免费=新的JLabel(自由标签,SwingConstants.CENTER);
    进度JProgressBar的新= JProgressBar的(){
        @覆盖
        公共尺寸的get preferredSize(){
            维D = super.get preferredSize();            返回新尺寸(400,为d.height);
        }
    };    DownloadListCellRenderer(){
        downloadPanel.add(labelStack,BorderLayout.CENTER);
        labelStack.setOpaque(假);
        number.setFont(number.getFont()的deriveFont(40F)。);
        labelStack.add(源);
        labelStack.add(信息);
        labelStack.add(进度);
        labelStack.add(免费);
        downloadPanel.add(labelStack,BorderLayout.CENTER);
        downloadPanel.add(数字,BorderLayout.LINE_START);
    }    @覆盖
    公共组件getListCellRendererComponent(
            JList的列表,
            对象的值,
            INT指数,
            布尔isSelected,
            布尔cellHasFocus){
        JLabel的L =(JLabel的)super.getListCellRendererComponent(
                列表值,索引,isSelected,cellHasFocus);
        downloadPanel.setBackground(l.getBackground());
        number.setText(+(索引+ 1));        返回downloadPanel;
    }
}

I have a a GUI looks as follow.

I want to dynamically add/remove a panel. I use ArrayList to keep trace of JPanel objects. And now I could add panel dynamically, but when I want to delete a panel, I could not get its attribute so that I can not remove it.

Here is my code:

public class Main implements ActionListener{
    private List <myPanel> mpList;
    private JPanel btnPanel;
    private JButton jbtAdd,jbtDelete;
    private JFrame jf;
    private JPanel jp;
    private JScrollPane js;
    private myPanel mp;
    private static int size=0;
    private int selectedId=-1;
    //private
    public Main(){
        mpList=new ArrayList<myPanel>();
        btnPanel=new JPanel();
        jbtAdd=new JButton("addJpanel");
        jbtDelete=new JButton("delJpanel");
        btnPanel.setLayout(new FlowLayout(FlowLayout.LEFT,1,1));
        btnPanel.add(jbtAdd);
        btnPanel.add(jbtDelete);
        jf=new JFrame("hello");
        jp=new JPanel();
        js=new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);   
        //jp.setLayout(new FlowLayout(FlowLayout.LEFT,1,1));
        jf.setLayout(new BorderLayout(10,10));
        jp.setLayout(new GridLayout(0,1,1,1));
        jp.setPreferredSize(new Dimension(500, 82*6));
        for(int i=0;i<6;i++){
            myPanel mp=new myPanel();
            //mp.setSize(400, 82);
            //mp.setBounds(0,82*i,480,82);
            mp.getFileTypeIconLabel().setText(String.valueOf(i));
            mp.setIndexId(size);
            size++;
            mpList.add(0,mp);
            mp.addMouseListener(new MouseListener(){
                @Override
                public void mouseClicked(MouseEvent e) {
                // TODO Auto-generated method stub
                    if(2==e.getClickCount()){
                        System.out.println("indexInd is"+mpList.get(0).getIndexId());
                        //System.out.println(index);
                        mpList.get(0).setBackground(Color.yellow);
                    }
                }

                @Override
                public void mouseEntered(MouseEvent e) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void mouseExited(MouseEvent e) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void mousePressed(MouseEvent e) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    // TODO Auto-generated method stub

                }});
            jp.add(mpList.get(0));
        }
        js.setViewportView(jp);
        jf.setSize(600, 500);
        jf.add(btnPanel,BorderLayout.NORTH);
        jf.add(js);
        jbtAdd.addActionListener(this);
        jbtDelete.addActionListener(this);
        jf.setVisible(true);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }
    public static void main(String args[]){
        new Main();
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        if(e.getSource()==jbtAdd){
            addMyPanel();
        }
        else if(e.getSource()==jbtDelete){
            delMyPanel();
        }
    }
    public void addMyPanel(){
        System.out.println("ok");
        mp=new myPanel();
        mp.getFileTypeIconLabel().setText(String.valueOf(mpList.size()));
        mp.setIndexId(size);
        System.out.println(size);
        size++;
        mpList.add(0, mp);
        mp.addMouseListener(new MouseListener(){
            @Override
            public void mouseClicked(MouseEvent e) {
            // TODO Auto-generated method stub
                if(2==e.getClickCount()){
                    System.out.println("indexInd is"+mpList.get(0).getIndexId());
                    //System.out.println(index);
                    mpList.get(0).setBackground(Color.yellow);
                }
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mouseExited(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mousePressed(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mouseReleased(MouseEvent e) {
                // TODO Auto-generated method stub

            }});
        jp.add(mpList.get(0));
        jp.setPreferredSize(new Dimension(500, 82*mpList.size()));
        //jp.validate();
        js.validate();
        //jp.repaint();
        js.repaint();
    }
    public void delMyPanel(){
        selectedId=getIndexOfMyPanelById();
        if(selectedId>=0){
            int indexId=getIndexOfMyPanelById();
            jp.remove(mpList.get(indexId));
            mpList.remove(indexId);
            jp.setPreferredSize(new Dimension(500,82*mpList.size()));
            jp.repaint();
        }
    }
    protected int getIndexOfMyPanelById(){
        Iterator<myPanel> it=mpList.iterator();
        for(int id=0;it.hasNext();id++){
            myPanel mp;
            mp=it.next();
            if(mp.isSelected()){
                return id;
            }
        }
        return -1;
    }
}

Here is code of myPanel

class myPanel extends JPanel{
    private static final long serialVersionUID = 1L;
    private JProgressBar downloadProgress;
    private JLabel fileTypeIconLabel,fileNameLabel,downloadInfoLabel,freeLabel;
    private int indexId;
    private boolean isSelected=false;
    protected myPanel(){
        setLayout(null);
        downloadProgress=new JProgressBar(0,100);
        fileTypeIconLabel=new JLabel("test");
        fileNameLabel=new JLabel("fileNameLabel");
        downloadInfoLabel=new JLabel("downloadInfoLabel");
        freeLabel=new JLabel("freeLabel");
        downloadProgress.setBounds(80, 44, 400, 18);
        downloadProgress.setStringPainted(true);
        //downloadProgress.setString("88%");
        fileTypeIconLabel.setBounds(0, 0, 80, 80);
        fileTypeIconLabel.setBackground(Color.cyan);
        fileTypeIconLabel.setOpaque(true);
        fileNameLabel.setBounds(80,0,400,22);
        fileNameLabel.setBackground(Color.black);
        fileNameLabel.setOpaque(true);
        downloadInfoLabel.setBounds(80, 22, 400, 22);
        downloadInfoLabel.setBackground(Color.red);
        downloadInfoLabel.setOpaque(true);
        //downloadProgress.setValue(50);
        freeLabel.setBounds(80, 62, 400, 18);
        freeLabel.setBackground(Color.lightGray);
        freeLabel.setOpaque(true);
        add(downloadProgress);
        add(fileTypeIconLabel);
        add(fileNameLabel);
        add(downloadInfoLabel);
        add(freeLabel); 

    }
    protected JLabel getFileTypeIconLabel() {
        return fileTypeIconLabel;
    }
    protected int getIndexId() {
        return indexId;
    }
    protected void setIndexId(int indexId) {
        this.indexId = indexId;
    }
    protected boolean isSelected() {
        return isSelected;
    }
    protected void setSelected(boolean isSelected) {
        this.isSelected = isSelected;
    }
}

解决方案

For many components in one space, use a CardLayout as seen in this short example.

Tips

jp.setPreferredSize(new Dimension(500, 82*6));

See Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? (Yes.)

downloadProgress.setBounds(80, 44, 400, 18);

Java GUIs might have to work on a number of platforms, on different screen resolutions & using different PLAFs. As such they are not conducive to exact placement of components. To organize the components for a robust GUI, instead use layout managers, or combinations of them1, along with layout padding & borders for white space2.

Edit 1

As an aside, the screen-shot screams JList with custom renderer to me. E.G.

import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class DymanicDownloadList {

    // the GUI as seen by the user (without frame)
    JPanel gui = new JPanel(new BorderLayout(2, 2));

    public void initGUI() {
        gui.setBorder(new EmptyBorder(2, 3, 2, 3));

        JToolBar tb = new JToolBar();
        gui.add(tb, BorderLayout.PAGE_START);

        final DefaultListModel<Download> listModel =
                new DefaultListModel<Download>();
        final JList<Download> list = new JList<Download>(listModel);
        list.setCellRenderer(new DownloadListCellRenderer());
        list.setVisibleRowCount(3);
        gui.add(new JScrollPane(list), BorderLayout.CENTER);

        Action add = new AbstractAction("Add Download") {

            @Override
            public void actionPerformed(ActionEvent e) {
                listModel.addElement(new Download());
            }
        };

        Action delete = new AbstractAction("Delete Download") {

            @Override
            public void actionPerformed(ActionEvent e) {
                int index = list.getSelectedIndex();
                if (index < 0) {
                    JOptionPane.showMessageDialog(
                            list,
                            "Select a download to delete!",
                            "Select Download",
                            JOptionPane.ERROR_MESSAGE);
                } else {
                    listModel.removeElementAt(index);
                }
            }
        };

        tb.add(add);
        tb.addSeparator();
        tb.add(delete);

        for (int ii = 0; ii < 2; ii++) {
            listModel.addElement(new Download());
        }
    }

    public JComponent getGUI() {
        return gui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                DymanicDownloadList ddl = new DymanicDownloadList();
                ddl.initGUI();

                JFrame f = new JFrame("Dynamic LIST");
                f.add(ddl.getGUI());
                // Ensures JVM closes after frame(s) closed and
                // all non-daemon threads are finished
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                // See http://stackoverflow.com/a/7143398/418556 for demo.
                f.setLocationByPlatform(true);

                // ensures the frame is the minimum size it needs to be
                // in order display the components within it
                f.pack();
                // should be done last, to avoid flickering, moving,
                // resizing artifacts.
                f.setVisible(true);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(r);
    }
}

class Download {

    Download() {
    }
}

class DownloadListCellRenderer extends DefaultListCellRenderer {

    JPanel downloadPanel = new JPanel(new BorderLayout(10, 10));
    JPanel labelStack = new JPanel(new GridLayout(0, 1, 2, 2));
    JLabel number = new JLabel("", SwingConstants.CENTER);
    JLabel source = new JLabel("File Name Label", SwingConstants.CENTER);
    JLabel info = new JLabel("Download Info Label", SwingConstants.CENTER);
    JLabel free = new JLabel("Free Label", SwingConstants.CENTER);
    JProgressBar progress = new JProgressBar() {
        @Override
        public Dimension getPreferredSize() {
            Dimension d = super.getPreferredSize();

            return new Dimension(400,d.height);
        }
    };

    DownloadListCellRenderer() {
        downloadPanel.add(labelStack, BorderLayout.CENTER);
        labelStack.setOpaque(false);
        number.setFont(number.getFont().deriveFont(40f));
        labelStack.add(source);
        labelStack.add(info);
        labelStack.add(progress);
        labelStack.add(free);
        downloadPanel.add(labelStack, BorderLayout.CENTER);
        downloadPanel.add(number, BorderLayout.LINE_START);
    }

    @Override
    public Component getListCellRendererComponent(
            JList list,
            Object value,
            int index,
            boolean isSelected,
            boolean cellHasFocus) {
        JLabel l = (JLabel) super.getListCellRendererComponent(
                list, value, index, isSelected, cellHasFocus);
        downloadPanel.setBackground(l.getBackground());
        number.setText("" + (index + 1));

        return downloadPanel;
    }
}

这篇关于如何动态删除一个JPanel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆