Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何动态生成多个JTextfield/JButton/。。。使用不同的id使用循环?_Java_Swing - Fatal编程技术网

Java 如何动态生成多个JTextfield/JButton/。。。使用不同的id使用循环?

Java 如何动态生成多个JTextfield/JButton/。。。使用不同的id使用循环?,java,swing,Java,Swing,我现在正在做一个java项目,允许经理创建todo列表,让员工查看不同的todo、流程和修改,例如添加注释 员工界面应包括: 根据数据库中的todo数量动态生成大量JTabbedPane 每个JtabbedPane必须包含todo的信息(标题、添加注释的JTextfield、标记todo为完成的JTextBox和保存更改的Jbutton) 我的问题是,当我在不同的JTabbedPane中生成我的JTextfield等时,它们都具有相同的id,因为我使用了一个while循环,如下所示: pr

我现在正在做一个java项目,允许经理创建todo列表,让员工查看不同的todo、流程和修改,例如添加注释

员工界面应包括:

  • 根据数据库中的todo数量动态生成大量JTabbedPane
  • 每个JtabbedPane必须包含todo的信息(标题、添加注释的JTextfield、标记todo为完成的JTextBox和保存更改的Jbutton)

我的问题是,当我在不同的JTabbedPane中生成我的JTextfield等时,它们都具有相同的id,因为我使用了一个while循环,如下所示:

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。因此,它们不利于像素完美布局。而是使用布局管理器,或与布局填充和边框一起使用。