gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:40:27 26 4
gpt4 key购买 nike

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

这是一个截图: theApp

示例代码如下:

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首先:谢谢。我注意到所提供的示例代码没有正确反射(reflect)我的代码,而且我在解释我的问题时失去了目标。我会保留上一个问题,因为它可能对其他人有用。让我们继续。

我需要替换某个面板,因此,我们之前对给定索引所做的操作应该以更动态的方式实现。我在我们的 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 而不是按钮。它的图标在鼠标进入/退出时发生变化,并在按下时添加一个确定的面板。对我来说这听起来更合适,顺便说一句,我们将不胜感激。

最佳答案

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

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

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 状态的索引位置在 try catch block 中。 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;
}

关于java - 如何将 JComponent 添加到 Box 的某个索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34352441/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com