[英]How to add a JComponent to a certain index of a Box
在我的软件中,我有一个ScrollPane,其视图有一个Box Layout并保存JPanels。 一个按钮允许将JPanel添加到该Box,我想找到一种方法将它放在一个特定的位置。
这是示例代码:
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.