繁体   English   中英

如何将JComponent添加到Box的某个索引

[英]How to add a JComponent to a certain index of a Box

在我的软件中,我有一个ScrollPane,其视图有一个Box Layout并保存JPanels。 一个按钮允许将JPanel添加到该Box,我想找到一种方法将它放在一个特定的位置。

这是一个screenShot: 该app

这是示例代码:

public class MyClass {

    //run a swing App
    public static void main(String[] args) throws IOException   {
        SwingUtilities.invokeLater(new ScrollPaneExample());        
    }
}


class ScrollPaneExample implements Runnable{

    private Box boxHolder;
    private JPanel scrollPaneContainer;

    //show a JFrame
    @Override
    public void run(){           
        JFrame mainFrame = initFrame();
        mainFrame.setPreferredSize(new Dimension(300, 200));
        mainFrame.setLocationRelativeTo(null);
        mainFrame.pack();
        mainFrame.setVisible(true);
    }

    //init JFrame and add to it a scrollpane and a button
    private JFrame initFrame() {
        JFrame mainFrame = new JFrame("MyFrame");
        mainFrame.setLayout(new BorderLayout());
        mainFrame.getContentPane().add(initScrollPane(),BorderLayout.CENTER);
        mainFrame.getContentPane().add(initButtonAdd(),BorderLayout.SOUTH);
        return mainFrame;
    }

    //init scrollpane which contains a boxholder for colored panels
    private Component initScrollPane() {
        scrollPaneContainer = new JPanel( new BorderLayout() );
        boxHolder = Box.createVerticalBox(); 
        scrollPaneContainer.add(boxHolder, BorderLayout.PAGE_START);
        return new JScrollPane(scrollPaneContainer);
    }

    //init a button which add a panel to the boxholder on pressed
    private Component initButtonAdd() {
        JButton button = new JButton("addPanel");
        button.setBackground(Color.green);
        button.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
               boxHolder.add(createPanel());
               scrollPaneContainer.revalidate();
           }
        });
        return button;
    }

    //create a panel setting its background to a random color
    private Component createPanel() {
        JPanel panel = new JPanel();
        panel.setBackground(randomColor());
        panel.setPreferredSize(new Dimension(100,50));
        panel.addMouseListener(new MouseListener() {
           public void mousePressed(MouseEvent e) {
                /** TODO code to replace the clicked panel with a new one*/     
           }
           @Override public void mouseClicked(MouseEvent e) {}
           @Override public void mouseReleased(MouseEvent e) {}
           @Override public void mouseEntered(MouseEvent e) {}
           @Override public void mouseExited(MouseEvent e) {}
        });
        panel.add(new JLabel("a colored Panel"));
        return panel;
    }

    //generate a randomColor
    private Color randomColor() {
        Random rand = new Random();
        float r = rand.nextFloat() / 2f ;
        float g = rand./***/nextFloat() / 2f;
        float b = rand.nextFloat() / 2f;
        Color randomColor = new Color(r, g, b);
        return randomColor;
    }


}

我想做点什么:

int indexPosition = 2;
boxHolder.add(createPanel(), indexPosition);

更新1-2首先:谢谢。 我注意到提供的示例代码没有正确反映我的代码,并且在解释我的问题时我已经失去了目标。 我将保留上一个问题,因为它对其他人有用。 让我们继续。

我需要替换某个面板,因此,我们之前使用给定索引所做的事情应该以更动态的方式实现。 我已经在我们的Jpanels中添加了一个mouseListener。 点击后,它们应该被新面板替换。 就像是:

    JPanel replacePanel = createPanel();
   // next istruction leads to a compilation error since Box do not has this method
    int indexOfClickedPanel= boxHolder.indexOf(this);
    boxHolder.add(replacePanel,indexOfClickedPanel); 

在我的代码中,我使用JLabel而不是按钮。 它的图标在mouseEntered / Exited上更改,并在onPressed上添加某个面板。 听起来对我来说更合适,任何建议都会受到赞赏。

在这个答案中,我将额外的代码添加到您的监听器,但如果您需要更改它,可以轻松更改。

如果您想在该位置添加另一个面板,您可以使用任何索引位置

public void mouseClicked(MouseEvent e) {
    boxHolder.add(createPanel());
    int indexPosition  = 2;
    try //Will only add here if you have a component in index position 1
    {
        boxHolder.add(createPanel(),indexPosition);
    }
    catch(Exception ex){}
    scrollPaneContainer.revalidate();
}

这将在索引位置2处添加面板,并将索引位置2中的当前面板移动到索引位置3。

如果您想要替换索引位置2中的当前面板,您可以使用

public void mouseClicked(MouseEvent e) {
    boxHolder.add(createPanel());
    int indexPosition  = 2;
    try //Will only remove it if there is already a panel or other component there
    {
        boxHolder.remove(indexPosition);
    }
    catch(Exception ex){}
    try //Will only add here if you have a component in index position 1
    {
        boxHolder.add(createPanel(),indexPosition);
    }
    catch(Exception ex){}
    scrollPaneContainer.revalidate();
}

这将删除当前位于索引位置2的面板,并在其位置添加另一个面板。

但是,如果您尝试将组件添加到索引位置2而索引位置0或1中没有任何组件,则会出现异常java.lang.IllegalArgumentException: illegal component position 因此,这就是为什么添加一个面板的代码,在该面板中,你的int变量, indexPosition ,states的索引位置在try catch块中。 这与remove方法的原因相同。

编辑

正如trashgod所说,如果你使用Action Listener会更好,所以在你的代码中它会是。

button.addActionListener(new ActionListener() 
{
    @Override
    public void actionPerformed(ActionEvent e)
    {
        //Rest of your code
    }
});

编辑2

如果您在单击JPanel时想要替换JPanel ,可以执行类似这样的操作。

private Component createPanel() {
    JPanel panel = new JPanel();
    panel.setBackground(randomColor());
    panel.setPreferredSize(new Dimension(100,50));
    panel.add(new JLabel("a colored Panel"));
    panel.addMouseListener(new MouseListener() {
        @Override 
        public void mouseClicked(MouseEvent e) {
            int indexPosition  = boxHolder.getComponentZOrder(panel);
            try
            {
                boxHolder.remove(indexPosition);
            }
            catch(Exception ex){}
            try //Will only add here if you have a component in index position 1
            {
                boxHolder.add(createPanel(),indexPosition);
            }
            catch(Exception ex){}
            scrollPaneContainer.revalidate();
        }
        @Override public void mousePressed(MouseEvent e) {}
        @Override public void mouseReleased(MouseEvent e) {}
        @Override public void mouseEntered(MouseEvent e) {}
        @Override public void mouseExited(MouseEvent e) {}
    });
    return panel;
}

至于改进的建议。 我建议将initScrollPane方法更改为以下代码,以便滚动是您可能更熟悉的速度。

private Component initScrollPane() {
    scrollPaneContainer = new JPanel( new BorderLayout() );
    boxHolder = Box.createVerticalBox(); 
    scrollPaneContainer.add(boxHolder, BorderLayout.PAGE_START);
    JScrollPane jSP = new JScrollPane(scrollPaneContainer);
    jSP.getVerticalScrollBar().setUnitIncrement(16);
    return jSP;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM