基于 JList 值将 JButtons 动态添加到 JPanel
Adding JButtons Dynamically to JPanel based on JList values
我正在开发 Java Swing 应用程序。
我的要求:-
在我的 JFrame 中,我有一个 JList,其值为 "One"、"Two"、"Three" 等。当我 select 一个列表项时,我想显示 "n" 按钮,其中 "n" 是值 selected.
示例:- 如果我从列表中 select "Three",JFrame 中应该有 3 个按钮。
下面是我的代码:-
public class Details extends JFrame {
String[] navData = new String{"One","Two","Three","Four"};
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Details frame = new Details();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Details() {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Toolkit tk = Toolkit.getDefaultToolkit();
int xSize = ((int) tk.getScreenSize().getWidth());
int ySize = ((int) tk.getScreenSize().getHeight());
//frame.setSize(xSize,ySize);
setTitle("Test");
setBounds(0, 0, 776, 457);
setResizable(false);
//setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
final JList list = new JList(navData);
list.setBounds(0, 0, 140, ySize);
contentPane.add(list);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setFixedCellHeight(50);
list.setFixedCellWidth(70);
list.setBorder(new EmptyBorder(10,10, 10, 10));
list.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent arg0) {
int numButtons;
String selectedItem = navData[list.getSelectedIndex()];
switch (selectedItem) {
case "One":
addButtons(1);
break;
case "Two":
addButtons(2);
break;
case "Three":
addButtons(3);
break;
case "Four":
addButtons(4);
break;
default:
break;
}
}
});
list.setSelectedIndex(0);
}
public void addButtons(int n)
{
revalidate();
for(int i = 0; i<n;i++)
{
JButton button = new JButton(" "+navData[i]);
button.setBounds(200 + (i*50), 150, 50, 50);
contentPane.add(button);
}
}
}
- 问题:-
当我更改列表中的 selected 项时,JPanel 没有更新。换句话说,当我从列表中 select "Three" 时,我没有得到 3 个按钮。我只有 1 个默认创建的按钮 selection.
将 contentPane.setLayout(null);
替换为某种布局,例如 contentPane.setLayout(new GridBagLayout());
添加
contentPane.removeAll()
作为 addButtons()
.
中的第一行
您可以为按钮创建一个 "wrapper" 面板,即
...
private JPanel buttonsWrapper;
...
// in the constructor
buttonsWrapper = new JPanel();
buttonsWrapper.setLayout(null);
buttonsWrapper.setBounds(200, 150, 200, 50);
buttonsWrapper.add(wrapperPanel);
并向该面板添加按钮
public void addButtons(int n) {
buttonsWrapper.removeAll();
for(int i = 0; i < n; i++) {
JButton button = new JButton(" " + navData[i]);
button.setBounds((i*50), 0, 50, 50);
buttonsWrapper.add(button);
}
buttonsWrapper.revalidate();
buttonsWrapper.repaint();
}
我做了这些更改:
我将 JList 放在一个 JPanel 中,将 JButton 放在另一个 JPanel 中。
我为 JList JPanel 使用了 FlowLayout,为 JButtons JPanel 使用了 FlowLayout。如果您愿意,您可以随意更改这些 Swing 布局。
我将默认值更改为 4 个按钮,因此 JFrame 最多可以正确打包 4 个 JButton。
在尝试将 JButton 添加到 JPanel 之前,我添加了一种从 JPanel 中删除 JButton 的方法。
我重新验证并重新绘制了 JButton JPanel。
代码如下:
package com.ggl.testing;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListSelectionModel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class Details extends JFrame {
private static final long serialVersionUID = -555805219508469709L;
private String[] navData = { "One", "Two", "Three", "Four" };
private JPanel buttonPanel;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Details frame = new Details();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Details() {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setTitle("Test");
buttonPanel = new JPanel();
JPanel listPanel = new JPanel();
final JList<String> list = new JList<String>(navData);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setFixedCellHeight(50);
list.setFixedCellWidth(70);
list.setBorder(new EmptyBorder(10, 10, 10, 10));
list.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent event) {
String selectedItem = navData[list.getSelectedIndex()];
switch (selectedItem) {
case "One":
removeButtons(buttonPanel);
addButtons(buttonPanel, 1);
break;
case "Two":
removeButtons(buttonPanel);
addButtons(buttonPanel, 2);
break;
case "Three":
removeButtons(buttonPanel);
addButtons(buttonPanel, 3);
break;
case "Four":
removeButtons(buttonPanel);
addButtons(buttonPanel, 4);
break;
default:
break;
}
}
});
list.setSelectedIndex(3);
listPanel.add(list);
add(listPanel, BorderLayout.WEST);
add(buttonPanel, BorderLayout.CENTER);
pack();
}
public void removeButtons(JPanel panel) {
Component[] components = panel.getComponents();
for (int i = 0; i < components.length; i++) {
panel.remove(components[i]);
}
}
public void addButtons(JPanel panel, int n) {
for (int i = 0; i < n; i++) {
JButton button = new JButton(navData[i]);
panel.add(button);
}
panel.revalidate();
panel.repaint();
}
}
我正在开发 Java Swing 应用程序。 我的要求:-
在我的 JFrame 中,我有一个 JList,其值为 "One"、"Two"、"Three" 等。当我 select 一个列表项时,我想显示 "n" 按钮,其中 "n" 是值 selected.
示例:- 如果我从列表中 select "Three",JFrame 中应该有 3 个按钮。
下面是我的代码:-
public class Details extends JFrame {
String[] navData = new String{"One","Two","Three","Four"};
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Details frame = new Details();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Details() {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Toolkit tk = Toolkit.getDefaultToolkit();
int xSize = ((int) tk.getScreenSize().getWidth());
int ySize = ((int) tk.getScreenSize().getHeight());
//frame.setSize(xSize,ySize);
setTitle("Test");
setBounds(0, 0, 776, 457);
setResizable(false);
//setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
final JList list = new JList(navData);
list.setBounds(0, 0, 140, ySize);
contentPane.add(list);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setFixedCellHeight(50);
list.setFixedCellWidth(70);
list.setBorder(new EmptyBorder(10,10, 10, 10));
list.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent arg0) {
int numButtons;
String selectedItem = navData[list.getSelectedIndex()];
switch (selectedItem) {
case "One":
addButtons(1);
break;
case "Two":
addButtons(2);
break;
case "Three":
addButtons(3);
break;
case "Four":
addButtons(4);
break;
default:
break;
}
}
});
list.setSelectedIndex(0);
}
public void addButtons(int n)
{
revalidate();
for(int i = 0; i<n;i++)
{
JButton button = new JButton(" "+navData[i]);
button.setBounds(200 + (i*50), 150, 50, 50);
contentPane.add(button);
}
}
}
- 问题:-
当我更改列表中的 selected 项时,JPanel 没有更新。换句话说,当我从列表中 select "Three" 时,我没有得到 3 个按钮。我只有 1 个默认创建的按钮 selection.
将 contentPane.setLayout(null);
替换为某种布局,例如 contentPane.setLayout(new GridBagLayout());
添加
contentPane.removeAll()
作为 addButtons()
.
您可以为按钮创建一个 "wrapper" 面板,即
...
private JPanel buttonsWrapper;
...
// in the constructor
buttonsWrapper = new JPanel();
buttonsWrapper.setLayout(null);
buttonsWrapper.setBounds(200, 150, 200, 50);
buttonsWrapper.add(wrapperPanel);
并向该面板添加按钮
public void addButtons(int n) {
buttonsWrapper.removeAll();
for(int i = 0; i < n; i++) {
JButton button = new JButton(" " + navData[i]);
button.setBounds((i*50), 0, 50, 50);
buttonsWrapper.add(button);
}
buttonsWrapper.revalidate();
buttonsWrapper.repaint();
}
我做了这些更改:
我将 JList 放在一个 JPanel 中,将 JButton 放在另一个 JPanel 中。
我为 JList JPanel 使用了 FlowLayout,为 JButtons JPanel 使用了 FlowLayout。如果您愿意,您可以随意更改这些 Swing 布局。
我将默认值更改为 4 个按钮,因此 JFrame 最多可以正确打包 4 个 JButton。
在尝试将 JButton 添加到 JPanel 之前,我添加了一种从 JPanel 中删除 JButton 的方法。
我重新验证并重新绘制了 JButton JPanel。
代码如下:
package com.ggl.testing;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListSelectionModel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class Details extends JFrame {
private static final long serialVersionUID = -555805219508469709L;
private String[] navData = { "One", "Two", "Three", "Four" };
private JPanel buttonPanel;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Details frame = new Details();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Details() {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setTitle("Test");
buttonPanel = new JPanel();
JPanel listPanel = new JPanel();
final JList<String> list = new JList<String>(navData);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setFixedCellHeight(50);
list.setFixedCellWidth(70);
list.setBorder(new EmptyBorder(10, 10, 10, 10));
list.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent event) {
String selectedItem = navData[list.getSelectedIndex()];
switch (selectedItem) {
case "One":
removeButtons(buttonPanel);
addButtons(buttonPanel, 1);
break;
case "Two":
removeButtons(buttonPanel);
addButtons(buttonPanel, 2);
break;
case "Three":
removeButtons(buttonPanel);
addButtons(buttonPanel, 3);
break;
case "Four":
removeButtons(buttonPanel);
addButtons(buttonPanel, 4);
break;
default:
break;
}
}
});
list.setSelectedIndex(3);
listPanel.add(list);
add(listPanel, BorderLayout.WEST);
add(buttonPanel, BorderLayout.CENTER);
pack();
}
public void removeButtons(JPanel panel) {
Component[] components = panel.getComponents();
for (int i = 0; i < components.length; i++) {
panel.remove(components[i]);
}
}
public void addButtons(JPanel panel, int n) {
for (int i = 0; i < n; i++) {
JButton button = new JButton(navData[i]);
panel.add(button);
}
panel.revalidate();
panel.repaint();
}
}