Java 如何动态生成多个JTextfield/JButton/。。。使用不同的id使用循环?
我现在正在做一个java项目,允许经理创建todo列表,让员工查看不同的todo、流程和修改,例如添加注释 员工界面应包括:Java 如何动态生成多个JTextfield/JButton/。。。使用不同的id使用循环?,java,swing,Java,Swing,我现在正在做一个java项目,允许经理创建todo列表,让员工查看不同的todo、流程和修改,例如添加注释 员工界面应包括: 根据数据库中的todo数量动态生成大量JTabbedPane 每个JtabbedPane必须包含todo的信息(标题、添加注释的JTextfield、标记todo为完成的JTextBox和保存更改的Jbutton) 我的问题是,当我在不同的JTabbedPane中生成我的JTextfield等时,它们都具有相同的id,因为我使用了一个while循环,如下所示: pr
- 根据数据库中的todo数量动态生成大量JTabbedPane
- 每个JtabbedPane必须包含todo的信息(标题、添加注释的JTextfield、标记todo为完成的JTextBox和保存更改的Jbutton)
private void init_employee() {
try {
/* create Frame */
setTitle("SUPTODO Employee");
setSize(800, 800);
/* New panel*/
JPanel topPanel = new JPanel();
topPanel.setLayout( new BorderLayout() );
getContentPane().add(topPanel);
tabbedPane = new JTabbedPane();
/* Select in my data base */
Statement stmt = (Statement) ConnectionManager.getConnection().createStatement();
String sql="SELECT id, title, contenu, comments FROM sup_todo WHERE done = 0";
ResultSet rset=(ResultSet) stmt.executeQuery(sql);
while(rset.next())
{
/* Get data */
ToDo todo = new ToDo();
todo.setId(rset.getLong(1));
todo.setTitle(rset.getString(2));
todo.setContenu(rset.getString(3));
todo.setComments(rset.getString(4));
/* Create the field */
panel = new JPanel();
panel.setLayout(null);
title = new JLabel(todo.getTitle());
title.setBounds( 200, 0, 100, 100 );
contenu = new JLabel(todo.getContenu());
contenu.setBounds(200, 50, 400, 200 );
employeeTextFieldToDo = new JTextField();
employeeTextFieldToDo.setBounds(200,300,400,200);
employeeCheckBoxToDo = new JCheckBox("Mark as done !");
employeeCheckBoxToDo.setBounds(200, 500, 200, 100);
employeeAddCommentToDo = new JButton("Save");
employeeAddCommentToDo.setBounds(350, 600, 100, 50);
//employeeAddCommentToDo.setBounds(x, y, width, height);
/* Action */
/* Save comments */
employeeAddCommentToDo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
/* PROBLEM HERE : Get the text of my last JTextField, not of the JTextField in his JTabbedPane */
String comment = employeeTextFieldToDo.getText();
JOptionPane.showConfirmDialog(SupTodoEmployeeFrame.this, "Votre commentaire est : " + comment, "comment message", JOptionPane.DEFAULT_OPTION);
}
});
/* Mark as done */
employeeCheckBoxToDo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
}
});
/* add to panel */
panel.add(title);
panel.add(contenu);
panel.add(employeeTextFieldToDo);
panel.add(employeeAddCommentToDo);
panel.add(employeeCheckBoxToDo);
panel.setVisible(true);
tabbedPane.addTab(todo.getTitle(), panel);
topPanel.add(tabbedPane, BorderLayout.CENTER);
}
} catch (SQLException e1) {
e1.printStackTrace();
}
}
如何生成具有唯一名称的JTexfield、JButton等,以便我在“保存”按钮和复选框上的操作涉及到正确的ToDo,执行SQL命令时使用右边的行,而不是使用此名称的最后一个字段。考虑创建在
while
方法作用域中是本地的UI变量。如果需要从匿名类中引用它们(例如ActionListener
实现),将它们标记为(确保删除其他变量声明)
final JTextField employeeTextFieldToDo = new JTextField();
final JButton employeeAddCommentToDo = new JButton("Save");
...
employeeAddCommentToDo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String comment = employeeTextFieldToDo.getText();
JOptionPane.showConfirmDialog(SupTodoEmployeeFrame.this, "Votre commentaire est : " + comment, "comment message", JOptionPane.DEFAULT_OPTION);
}
});
我会考虑使用JTraveStar,JButtons等的数组或数组,我自己已经用过了,这是一个软件项目,很舒服。
< p>为了解决你的问题,我建议下面的方法。创建一个类<代码> TodoPanel <代码>扩展<代码> jPuth<代码>。Constructor参数-示例实现使用您的组件和设置,但不“改进”某些方面:class ToDoPanel extends JPanel {
private JLabel title;
private JLabel contenu;
private JTextField employeeTextFieldToDo;
private JCheckBox employeeCheckBoxToDo;
private JButton employeeAddCommentToDo;
public ToDoPanel(ToDo todo) {
setLayout(null);
title = new JLabel(todo.getTitle());
title.setBounds(200, 0, 100, 100);
contenu = new JLabel(todo.getContenu());
contenu.setBounds(200, 50, 400, 200);
employeeTextFieldToDo = new JTextField();
employeeTextFieldToDo.setText(todo.getComments());
employeeTextFieldToDo.setBounds(200, 300, 400, 200);
employeeCheckBoxToDo = new JCheckBox("Mark as done !");
employeeCheckBoxToDo.setBounds(200, 500, 200, 100);
employeeAddCommentToDo = new JButton("Save");
employeeAddCommentToDo.setBounds(350, 600, 100, 50);
/* Action */
/* Save comments */
employeeAddCommentToDo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String comment = employeeTextFieldToDo.getText();
// JOptionPane.showConfirmDialog(, "Votre commentaire est : " + comment, "comment message", JOptionPane.DEFAULT_OPTION);
System.out.println("Hello " + comment);
}
});
/* Mark as done */
employeeCheckBoxToDo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// nothing
}
});
/* add to panel */
add(title);
add(contenu);
add(employeeTextFieldToDo);
add(employeeAddCommentToDo);
add(employeeCheckBoxToDo);
setVisible(true);
}
}
现在,包含JTabbedPane
的框架可以提供一种获取ToDo
项列表的方法(应该与此类分开,但为了保持其简短,它在内部)。循环浏览列表,并根据ToDo创建一个新的ToDoPanel
。然后将其作为选项卡添加到:
public class Main extends JFrame {
public static void main(String[] args) {
Main frame = new Main();
frame.setTitle("SUPTODO Employee");
frame.setSize(800, 800);
List<ToDo> todos = frame.getTodos();
JPanel topPanel = new JPanel();
topPanel.setLayout(new BorderLayout());
frame.getContentPane().add(topPanel);
JTabbedPane jTabbedPane = new JTabbedPane();
for (ToDo toDo : todos) {
ToDoPanel panel = new ToDoPanel(toDo);
jTabbedPane.addTab(toDo.getTitle(), panel);
}
topPanel.add(jTabbedPane, BorderLayout.CENTER);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
/**
* Get data from database as a list of ToDos
*
* @return
*/
private List<ToDo> getTodos() {
// example data - HERE goes your SQL query etc.
return Arrays.asList(new ToDo(1L, "Title", "Text", "Comments"), new ToDo(2L, "Title2", "Text2", "Comments2"));
}
}
public类主框架{
公共静态void main(字符串[]args){
主机架=新主机架();
框架。setTitle(“SUPTODO员工”);
框架设置尺寸(800800);
List todos=frame.gettoos();
JPanel-topPanel=新的JPanel();
setLayout(新的BorderLayout());
frame.getContentPane().add(topPanel);
JTabbedPane JTabbedPane=新JTabbedPane();
for(待办事项:待办事项){
ToDoPanel面板=新ToDoPanel(toDo);
jTabbedPane.addTab(toDo.getTitle(),panel);
}
添加(jTabbedPane,BorderLayout.CENTER);
frame.setVisible(true);
frame.addWindowListener(新的WindowAdapter(){
@凌驾
公共无效窗口关闭(WindowEvent e){
系统出口(0);
}
});
}
/**
*以TODO列表的形式从数据库获取数据
*
*@返回
*/
私有列表getTodos(){
//示例数据-下面是您的SQL查询等。
返回数组.asList(新ToDo(1L,“标题”、“文本”、“注释”)、新ToDo(2L,“标题2”、“文本2”、“注释2”);
}
}
现在,每个ToDo都由它自己的面板呈现,有不同的侦听器,并且可以被不同地管理。但是请考虑Andrew Thompson所写的评论。< /P>“如何使用一个循环来动态地生成具有不同ID的许多JTrtField/JButk/……”如果你的意思是“列表”,那么我会避开整个问题,保留一个
Vector
,并将其显示在JList
中。使用ListCellRenderer
确保每个任务
都按要求显示在列表中。或者,只需使用JTable
和任务的每个字段的列即可为了更快地获得更好的帮助,可以发布一个(最小完整的可验证示例)或(简短、自包含、正确的示例)。2) Java GUI必须在不同的操作系统、屏幕大小、屏幕分辨率等上工作,在不同的地区使用不同的PLAF。因此,它们不利于像素完美布局。而是使用布局管理器,或与布局填充和边框一起使用。