如何动态删除JPanel? [英] How to dynamically remove a JPanel?
问题描述
我有一个如下所示的 GUI.
我想动态添加/删除面板.我使用 ArrayList
来跟踪 JPanel
对象.现在我可以动态添加面板,但是当我想删除一个面板时,我无法获取它的属性,因此我无法删除它.
这是我的代码:
公共类 Main 实现 ActionListener{私人列表<myPanel>mpList;私人 JPanel btnPanel;私有 JButton jbtAdd,jbtDelete;私人 JFrame jf;私人JPanel jp;私有 JScrollPane js;私人 myPanel mp;私有静态整数大小=0;私有 int selectedId=-1;//私人的公共主(){mpList=new ArrayList();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("你好");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++){我的面板 mp=新的我的面板();//mp.setSize(400, 82);//mp.setBounds(0,82*i,480,82);mp.getFileTypeIconLabel().setText(String.valueOf(i));mp.setIndexId(大小);尺寸++;mpList.add(0,mp);mp.addMouseListener(新鼠标监听器(){@覆盖public void mouseClicked(MouseEvent e) {//TODO 自动生成的方法存根if(2==e.getClickCount()){System.out.println("indexInd 是"+mpList.get(0).getIndexId());//System.out.println(index);mpList.get(0).setBackground(Color.yellow);}}@覆盖public void mouseEntered(MouseEvent e) {//TODO 自动生成的方法存根}@覆盖public void mouseExited(MouseEvent e) {//TODO 自动生成的方法存根}@覆盖public void mousePressed(MouseEvent e) {//TODO 自动生成的方法存根}@覆盖public void 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(this);jbtDelete.addActionListener(this);jf.setVisible(真);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}公共静态无效主(字符串参数[]){新的主();}@覆盖public void actionPerformed(ActionEvent e) {//TODO 自动生成的方法存根if(e.getSource()==jbtAdd){添加我的面板();}否则 if(e.getSource()==jbtDelete){delMyPanel();}}公共无效 addMyPanel(){System.out.println("ok");mp=新的我的面板();mp.getFileTypeIconLabel().setText(String.valueOf(mpList.size()));mp.setIndexId(大小);System.out.println(大小);尺寸++;mpList.add(0, mp);mp.addMouseListener(新鼠标监听器(){@覆盖public void mouseClicked(MouseEvent e) {//TODO 自动生成的方法存根if(2==e.getClickCount()){System.out.println("indexInd 是"+mpList.get(0).getIndexId());//System.out.println(index);mpList.get(0).setBackground(Color.yellow);}}@覆盖public void mouseEntered(MouseEvent e) {//TODO 自动生成的方法存根}@覆盖public void mouseExited(MouseEvent e) {//TODO 自动生成的方法存根}@覆盖public void mousePressed(MouseEvent e) {//TODO 自动生成的方法存根}@覆盖public void mouseReleased(MouseEvent e) {//TODO 自动生成的方法存根}});jp.add(mpList.get(0));jp.setPreferredSize(new Dimension(500, 82*mpList.size()));//jp.validate();js.validate();//jp.repaint();js.repaint();}公共无效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(){迭代器it=mpList.iterator();for(int id=0;it.hasNext();id++){我的面板 mp;mp=it.next();如果(mp.isSelected()){返回标识;}}返回-1;}}
这是myPanel
class myPanel 扩展 JPanel{private static final long serialVersionUID = 1L;私人 JProgressBar 下载进度;私有 JLabel fileTypeIconLabel,fileNameLabel,downloadInfoLabel,freeLabel;私有 int indexId;私有布尔值 isSelected=false;受保护的 myPanel(){设置布局(空);下载进度=新 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);下载信息标签.setBounds(80, 22, 400, 22);下载InfoLabel.setBackground(Color.red);downloadInfoLabel.setOpaque(true);//downloadProgress.setValue(50);freeLabel.setBounds(80, 62, 400, 18);freeLabel.setBackground(Color.lightGray);freeLabel.setOpaque(true);添加(下载进度);添加(文件类型图标标签);添加(文件名标签);添加(下载信息标签);添加(自由标签);}受保护的 JLabel getFileTypeIconLabel() {返回文件类型图标标签;}受保护的 int getIndexId() {返回索引 ID;}protected void setIndexId(int indexId) {this.indexId = indexId;}受保护的布尔值 isSelected() {返回被选中;}protected void setSelected(boolean isSelected) {this.isSelected = isSelected;}}
对于一个空间中的多个组件,使用 (是的.)
downloadProgress.setBounds(80, 44, 400, 18);
Java GUI 可能必须在许多平台上工作,在不同的屏幕分辨率上使用不同的PLAF.因此,它们不利于元件的精确放置.要为强大的 GUI 组织组件,请改用布局管理器,或它们的组合1, 以及布局填充 &空白区域2的边框.
编辑 1
顺便说一句,屏幕截图对我来说JList
带有自定义渲染器.E.G.
import java.awt.*;导入 java.awt.event.ActionEvent;导入 javax.swing.*;导入 javax.swing.border.EmptyBorder;公共类动态下载列表 {//用户看到的 GUI(没有框架)JPanel gui = new JPanel(new BorderLayout(2, 2));公共无效initGUI(){gui.setBorder(new EmptyBorder(2, 3, 2, 3));JToolBar tb = new JToolBar();gui.add(tb, BorderLayout.PAGE_START);最终 DefaultListModel<下载>列表模型 =新的 DefaultListModel<下载>();最终 JList<下载>list = new JList<下载>(listModel);list.setCellRenderer(new DownloadListCellRenderer());list.setVisibleRowCount(3);gui.add(new JScrollPane(list), BorderLayout.CENTER);Action add = new AbstractAction(添加下载"){@覆盖public void actionPerformed(ActionEvent e) {listModel.addElement(new Download());}};Action delete = new AbstractAction(删除下载"){@覆盖public void actionPerformed(ActionEvent e) {int index = list.getSelectedIndex();如果(索引<0){JOptionPane.showMessageDialog(列表,选择要删除的下载!",选择下载",JOptionPane.ERROR_MESSAGE);} 别的 {listModel.removeElementAt(index);}}};tb.add(添加);tb.addSeparator();tb.add(删除);对于 (int ii = 0; ii <2; ii++) {listModel.addElement(new Download());}}公共 JComponent getGUI() {返回gui;}公共静态无效主(字符串 [] args){可运行 r = 新可运行(){@覆盖公共无效运行(){DymanicDownloadList ddl = new DymanicDownloadList();ddl.initGUI();JFrame f = new JFrame(动态列表");f.add(ddl.getGUI());//确保 JVM 在帧关闭后关闭,并且//所有非守护线程都完成了f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);//见 https://stackoverflow.com/a/7143398/418556 演示.f.setLocationByPlatform(true);//确保框架是它需要的最小尺寸//依次显示其中的组件f.pack();//应该最后完成,以避免闪烁,移动,//调整工件大小.f.setVisible(true);}};//应该在 EDT 上创建和更新 Swing GUI//http://docs.oracle.com/javase/tutorial/uiswing/concurrencySwingUtilities.invokeLater(r);}}类下载{下载() {}}类 DownloadListCellRenderer 扩展 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(文件名标签", SwingConstants.CENTER);JLabel info = new JLabel(下载信息标签", SwingConstants.CENTER);JLabel free = new JLabel("Free Label", SwingConstants.CENTER);JProgressBar 进度 = 新 JProgressBar() {@覆盖公共维度 getPreferredSize() {维度 d = super.getPreferredSize();返回新维度(400,d.height);}};下载ListCellRenderer() {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(免费);downloadPanel.add(labelStack, BorderLayout.CENTER);downloadPanel.add(number, BorderLayout.LINE_START);}@覆盖公共组件 getListCellRendererComponent(JList 列表,对象值,整数索引,布尔值被选中,布尔 cellHasFocus) {JLabel l = (JLabel) super.getListCellRendererComponent(列表、值、索引、isSelected、cellHasFocus);downloadPanel.setBackground(l.getBackground());number.setText("" + (index + 1));返回下载面板;}}
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 https://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屋!