используйте cumcount()
, см. docs здесь
In [4]: df.groupby(['c1', 'c2']).cumcount()
Out[4]:
0 0
1 1
2 0
3 1
4 0
5 1
6 2
7 0
8 0
9 0
10 1
11 2
dtype: int64
Если вы хотите, чтобы порядок, начинающийся с 1
In [5]: df.groupby(['c1', 'c2']).cumcount()+1
Out[5]:
0 1
1 2
2 1
3 2
4 1
5 2
6 3
7 1
8 1
9 1
10 2
11 3
dtype: int64
Причина этого в том, что вы запускаете цикл for в потоке отправки событий (см. Событие Dispatch Thread ). Это поток, в котором происходят все взаимодействия с пользовательским интерфейсом.
Если вы выполняете длинную задачу, вы должны запустить ее в другом потоке, чтобы пользовательский интерфейс сохранял отзывчивость. Если вам нужно внести изменения в пользовательский интерфейс, например, изменить текст в вашей JTextPane и установить позицию каретки из другого потока, кроме потока отправки событий, вам нужно вызвать либо EventQueue.invokeLater()
, либо EventQueue.invokeAndWait()
(см. EventQueue ).
Я думаю, что инициируемые события от установки позиции каретки поставлены в очередь в вашем случае и могут обрабатываться только после завершения цикла (поскольку оба они обрабатываются в потоке отправки событий). Поэтому вы должны попробовать что-то вроде этого:
@Override
public void actionPerformed(ActionEvent e)
{
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < iter; i++)
{
final String display = String.format("%10d\n", i);
try {
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
append(display);
}
});
} catch (Exception e) {
e.printStackTrace();
}
} // end for i
}
}).start();
}
Может быть даже лучше, если вы вызываете EventQueue.invokeAndWait
только после x итераций и кешируете предыдущие результаты, которые необходимо отобразить.